/* ==========================================================================
   Konvoy — thème
   Charte graphique du cahier des charges, § 8.
   Chargé après bootstrap.min.css : les redéfinitions de variables --bs-*
   l'emportent par l'ordre des feuilles, à spécificité égale.

   Sommaire
     1.  Polices
     2.  Palettes et jetons
     3.  Surcharges des variables Bootstrap
     4.  Base
     5.  Typographie
     6.  Boutons
     7.  Champs de formulaire
     8.  Cartes
     9.  Tableaux
     10. Pastilles de statut
     11. Alertes et notifications
     12. Coquille applicative : barre latérale, barre supérieure
     13. État vide et squelettes
     14. Utilitaires kv-
     15. Impression
   ========================================================================== */

/* ==========================================================================
   1. Polices — auto-hébergées, aucune dépendance à un réseau externe
   Graisses 400, 500 et 600 uniquement pour Inter (charte § 8.3).
   ========================================================================== */

@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/inter/Inter-Regular.woff2') format('woff2');
}

@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('../fonts/inter/Inter-Medium.woff2') format('woff2');
}

@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('../fonts/inter/Inter-SemiBold.woff2') format('woff2');
}

@font-face {
    font-family: 'JetBrains Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/jetbrains-mono/JetBrainsMono-Regular.woff2') format('woff2');
}

@font-face {
    font-family: 'JetBrains Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('../fonts/jetbrains-mono/JetBrainsMono-Medium.woff2') format('woff2');
}

/* ==========================================================================
   2. Palettes et jetons
   ========================================================================== */

:root {
    /* Bleu cargo — couleur de marque. Le 600 est structurant, non décoratif. */
    --kv-bleu-50: #EEF4FB;
    --kv-bleu-100: #D5E5F5;
    --kv-bleu-200: #A9C8E9;
    --kv-bleu-300: #75A5D8;
    --kv-bleu-400: #4682C4;
    --kv-bleu-500: #2A63A6;
    --kv-bleu-600: #1D4E89;
    --kv-bleu-700: #163C6B;
    --kv-bleu-800: #112C4F;
    --kv-bleu-900: #0B1D35;
    --kv-bleu-600-rgb: 29, 78, 137;

    /* Ardoise — neutres. */
    --kv-ardoise-25: #FAFAF9;
    --kv-ardoise-50: #F5F5F3;
    --kv-ardoise-100: #EBEBE8;
    --kv-ardoise-200: #DCDCD7;
    --kv-ardoise-300: #C2C2BB;
    --kv-ardoise-400: #97978F;
    --kv-ardoise-500: #71716A;
    --kv-ardoise-600: #545450;
    --kv-ardoise-700: #3E3E3A;
    --kv-ardoise-800: #292926;
    --kv-ardoise-900: #181816;

    /* Couleurs de sens. L'ambre est rare, réservé à ce qui exige une action. */
    --kv-signal: #DE8A14;
    --kv-signal-fond: #FBE3BC;
    --kv-signal-texte: #7A4708;

    --kv-succes: #157F5A;
    --kv-succes-fond: #DDF0E7;
    --kv-succes-texte: #0F5C42;

    --kv-alerte: #B26A05;
    --kv-alerte-fond: #FDF2DE;
    --kv-alerte-texte: #7A4708;

    --kv-danger: #C0362C;
    --kv-danger-fond: #FBDCD9;
    --kv-danger-texte: #8E2620;

    --kv-transit: #5B4AA8;
    --kv-transit-fond: #E4E0F4;
    --kv-transit-texte: #413577;

    /* Surfaces. Le fond de page est ardoise 50, les cartes sont blanches. */
    --kv-fond-page: var(--kv-ardoise-50);
    --kv-fond-carte: #FFFFFF;
    --kv-fond-enfonce: var(--kv-ardoise-100);
    --kv-bordure: var(--kv-ardoise-200);
    --kv-bordure-forte: var(--kv-ardoise-300);

    /* Texte. */
    --kv-texte: var(--kv-ardoise-800);
    --kv-texte-doux: var(--kv-ardoise-500);
    --kv-texte-inverse: #FFFFFF;

    /* Typographie. Échelle : 12, 13, 14, 16, 18, 20, 24. */
    --kv-police: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --kv-police-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    --kv-taille-12: 0.75rem;
    --kv-taille-13: 0.8125rem;
    --kv-taille-14: 0.875rem;
    --kv-taille-16: 1rem;
    --kv-taille-18: 1.125rem;
    --kv-taille-20: 1.25rem;
    --kv-taille-24: 1.5rem;

    /* Espacement — base 4 px. */
    --kv-espace-1: 0.25rem;
    --kv-espace-2: 0.5rem;
    --kv-espace-3: 0.75rem;
    --kv-espace-4: 1rem;
    --kv-espace-5: 1.25rem;
    --kv-espace-6: 1.5rem;
    --kv-espace-8: 2rem;
    --kv-espace-10: 2.5rem;

    /* Formes. */
    --kv-rayon-controle: 6px;
    --kv-rayon-carte: 10px;
    --kv-rayon-pastille: 999px;

    /* Dimensions des contrôles. */
    --kv-hauteur-controle: 40px;
    --kv-hauteur-ligne-tableau: 48px;
    --kv-largeur-laterale: 240px;
    --kv-largeur-laterale-reduite: 64px;
    --kv-hauteur-superieure: 56px;

    /* Ombres — jamais lourdes. */
    --kv-ombre-carte: 0 1px 2px rgba(24, 24, 22, 0.05);
    --kv-ombre-flottante: 0 4px 12px rgba(24, 24, 22, 0.10);

    /* Mouvement — 150 ms au survol, rien de plus. */
    --kv-transition: 150ms ease;
}

/* Hauteur des contrôles portée à 44 px sur mobile : cible tactile minimale. */
@media (max-width: 991.98px) {
    :root {
        --kv-hauteur-controle: 44px;
    }

    /* .btn-close (Bootstrap) reste visuellement petit — l'icône ne grossit
       pas — mais sa zone cliquable est portée à 44 px par du remplissage
       invisible, faute de quoi il est raté au pouce sur les toasts, modales
       et onglets fermables. */
    .btn-close {
        width: 44px;
        height: 44px;
        padding: 0;
        background-position: center;
    }
}

/* ==========================================================================
   3. Surcharges des variables Bootstrap
   ========================================================================== */

:root,
[data-bs-theme='light'] {
    --bs-body-font-family: var(--kv-police);
    --bs-font-monospace: var(--kv-police-mono);
    --bs-body-font-size: var(--kv-taille-14);
    --bs-body-font-weight: 400;
    --bs-body-line-height: 1.5;
    --bs-body-color: var(--kv-texte);
    --bs-body-color-rgb: 41, 41, 38;
    --bs-body-bg: var(--kv-fond-page);
    --bs-body-bg-rgb: 245, 245, 243;

    --bs-emphasis-color: var(--kv-ardoise-900);
    --bs-secondary-color: var(--kv-texte-doux);
    --bs-secondary-bg: var(--kv-ardoise-100);
    --bs-tertiary-color: var(--kv-ardoise-400);
    --bs-tertiary-bg: var(--kv-ardoise-50);

    --bs-border-color: var(--kv-bordure);
    --bs-border-color-translucent: var(--kv-bordure);
    --bs-border-radius: var(--kv-rayon-controle);
    --bs-border-radius-sm: 4px;
    --bs-border-radius-lg: var(--kv-rayon-carte);
    --bs-border-radius-xl: var(--kv-rayon-carte);
    --bs-border-radius-pill: var(--kv-rayon-pastille);

    --bs-primary: var(--kv-bleu-600);
    --bs-primary-rgb: 29, 78, 137;
    --bs-primary-text-emphasis: var(--kv-bleu-800);
    --bs-primary-bg-subtle: var(--kv-bleu-50);
    --bs-primary-border-subtle: var(--kv-bleu-200);

    --bs-secondary: var(--kv-ardoise-500);
    --bs-secondary-rgb: 113, 113, 106;

    --bs-success: var(--kv-succes);
    --bs-success-rgb: 21, 127, 90;
    --bs-success-text-emphasis: var(--kv-succes-texte);
    --bs-success-bg-subtle: var(--kv-succes-fond);
    --bs-success-border-subtle: #B9DFCF;

    --bs-warning: var(--kv-alerte);
    --bs-warning-rgb: 178, 106, 5;
    --bs-warning-text-emphasis: var(--kv-alerte-texte);
    --bs-warning-bg-subtle: var(--kv-alerte-fond);
    --bs-warning-border-subtle: var(--kv-signal-fond);

    --bs-danger: var(--kv-danger);
    --bs-danger-rgb: 192, 54, 44;
    --bs-danger-text-emphasis: var(--kv-danger-texte);
    --bs-danger-bg-subtle: var(--kv-danger-fond);
    --bs-danger-border-subtle: #F2BDB7;

    --bs-info: var(--kv-transit);
    --bs-info-rgb: 91, 74, 168;
    --bs-info-text-emphasis: var(--kv-transit-texte);
    --bs-info-bg-subtle: var(--kv-transit-fond);
    --bs-info-border-subtle: #CBC4EA;

    --bs-light: var(--kv-ardoise-50);
    --bs-light-rgb: 245, 245, 243;
    --bs-dark: var(--kv-ardoise-800);
    --bs-dark-rgb: 41, 41, 38;

    --bs-link-color: var(--kv-bleu-600);
    --bs-link-color-rgb: 29, 78, 137;
    --bs-link-hover-color: var(--kv-bleu-700);
    --bs-link-hover-color-rgb: 22, 60, 107;

    --bs-focus-ring-width: 3px;
    --bs-focus-ring-opacity: 0.25;
    --bs-focus-ring-color: rgba(var(--kv-bleu-600-rgb), 0.25);

    --bs-heading-color: var(--kv-ardoise-900);
}

/* ==========================================================================
   4. Base
   ========================================================================== */

html {
    /* Ancre l'échelle en pixels : 1rem = 16 px quelle que soit la page. */
    font-size: 16px;
}

body {
    background-color: var(--kv-fond-page);
    color: var(--kv-texte);
    font-family: var(--kv-police);
    font-size: var(--kv-taille-14);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    font-feature-settings: 'cv05' 1, 'cv08' 1;
}

::selection {
    background-color: var(--kv-bleu-100);
    color: var(--kv-bleu-900);
}

:focus-visible {
    outline: 2px solid var(--kv-bleu-400);
    outline-offset: 2px;
}

hr {
    border-color: var(--kv-bordure);
    opacity: 1;
}

/* Aucune animation élaborée : on respecte aussi la préférence système. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
    }
}

/* ==========================================================================
   5. Typographie
   ========================================================================== */

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
    font-weight: 600;
    color: var(--kv-ardoise-900);
    letter-spacing: -0.01em;
}

h1, .h1 { font-size: var(--kv-taille-24); }
h2, .h2 { font-size: var(--kv-taille-20); }
h3, .h3 { font-size: var(--kv-taille-18); }
h4, .h4 { font-size: var(--kv-taille-16); }
h5, .h5,
h6, .h6 { font-size: var(--kv-taille-14); }

/* Titre de page : 20 px, unique par écran. */
.kv-titre-page {
    font-size: var(--kv-taille-20);
    font-weight: 600;
    line-height: 1.3;
    margin: 0;
}

.kv-sous-titre {
    font-size: var(--kv-taille-13);
    color: var(--kv-texte-doux);
    margin: var(--kv-espace-1) 0 0;
}

/* Identifiants, numéros de suivi, codes-barres. Jamais du texte courant. */
.kv-mono,
code, kbd, samp, pre {
    font-family: var(--kv-police-mono);
    font-variant-ligatures: none;
}

.kv-suivi {
    font-family: var(--kv-police-mono);
    font-weight: 500;
    letter-spacing: 0.02em;
    white-space: nowrap;
}

/* Montants, poids et quantités : chiffres à chasse fixe pour aligner. */
.kv-nombre {
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum' 1;
    white-space: nowrap;
}

/* ==========================================================================
   6. Boutons — une seule action principale par écran
   ========================================================================== */

.btn {
    --bs-btn-padding-y: 0;
    --bs-btn-padding-x: var(--kv-espace-4);
    --bs-btn-font-size: var(--kv-taille-14);
    --bs-btn-font-weight: 500;
    --bs-btn-border-radius: var(--kv-rayon-controle);
    --bs-btn-line-height: 1.2;
    min-height: var(--kv-hauteur-controle);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--kv-espace-2);
    transition: background-color var(--kv-transition),
                border-color var(--kv-transition),
                color var(--kv-transition);
}

.btn:focus-visible {
    box-shadow: 0 0 0 3px rgba(var(--kv-bleu-600-rgb), 0.25);
}

.btn-sm {
    --bs-btn-padding-x: var(--kv-espace-3);
    --bs-btn-font-size: var(--kv-taille-13);
    min-height: 32px;
}

.btn-lg {
    --bs-btn-padding-x: var(--kv-espace-6);
    --bs-btn-font-size: var(--kv-taille-16);
    min-height: 48px;
}

.btn-primary {
    --bs-btn-bg: var(--kv-bleu-600);
    --bs-btn-border-color: var(--kv-bleu-600);
    --bs-btn-color: var(--kv-texte-inverse);
    --bs-btn-hover-bg: var(--kv-bleu-700);
    --bs-btn-hover-border-color: var(--kv-bleu-700);
    --bs-btn-hover-color: var(--kv-texte-inverse);
    --bs-btn-active-bg: var(--kv-bleu-800);
    --bs-btn-active-border-color: var(--kv-bleu-800);
    --bs-btn-active-color: var(--kv-texte-inverse);
    --bs-btn-disabled-bg: var(--kv-bleu-200);
    --bs-btn-disabled-border-color: var(--kv-bleu-200);
    --bs-btn-disabled-color: var(--kv-texte-inverse);
}

/* Action secondaire : contour ardoise, jamais un aplat coloré. */
.btn-secondary,
.btn-outline-secondary {
    --bs-btn-bg: #FFFFFF;
    --bs-btn-border-color: var(--kv-bordure-forte);
    --bs-btn-color: var(--kv-ardoise-700);
    --bs-btn-hover-bg: var(--kv-ardoise-50);
    --bs-btn-hover-border-color: var(--kv-ardoise-400);
    --bs-btn-hover-color: var(--kv-ardoise-900);
    --bs-btn-active-bg: var(--kv-ardoise-100);
    --bs-btn-active-border-color: var(--kv-ardoise-400);
    --bs-btn-active-color: var(--kv-ardoise-900);
    --bs-btn-disabled-bg: var(--kv-ardoise-50);
    --bs-btn-disabled-border-color: var(--kv-bordure);
    --bs-btn-disabled-color: var(--kv-ardoise-400);
}

.btn-outline-primary {
    --bs-btn-bg: transparent;
    --bs-btn-border-color: var(--kv-bleu-600);
    --bs-btn-color: var(--kv-bleu-600);
    --bs-btn-hover-bg: var(--kv-bleu-50);
    --bs-btn-hover-border-color: var(--kv-bleu-600);
    --bs-btn-hover-color: var(--kv-bleu-700);
    --bs-btn-active-bg: var(--kv-bleu-100);
    --bs-btn-active-border-color: var(--kv-bleu-700);
    --bs-btn-active-color: var(--kv-bleu-800);
}

.btn-danger {
    --bs-btn-bg: var(--kv-danger);
    --bs-btn-border-color: var(--kv-danger);
    --bs-btn-color: var(--kv-texte-inverse);
    --bs-btn-hover-bg: var(--kv-danger-texte);
    --bs-btn-hover-border-color: var(--kv-danger-texte);
    --bs-btn-hover-color: var(--kv-texte-inverse);
    --bs-btn-active-bg: var(--kv-danger-texte);
    --bs-btn-active-border-color: var(--kv-danger-texte);
    --bs-btn-active-color: var(--kv-texte-inverse);
}

.btn-outline-danger {
    --bs-btn-bg: transparent;
    --bs-btn-border-color: var(--kv-danger);
    --bs-btn-color: var(--kv-danger-texte);
    --bs-btn-hover-bg: var(--kv-danger-fond);
    --bs-btn-hover-border-color: var(--kv-danger);
    --bs-btn-hover-color: var(--kv-danger-texte);
}

.btn-success {
    --bs-btn-bg: var(--kv-succes);
    --bs-btn-border-color: var(--kv-succes);
    --bs-btn-color: var(--kv-texte-inverse);
    --bs-btn-hover-bg: var(--kv-succes-texte);
    --bs-btn-hover-border-color: var(--kv-succes-texte);
    --bs-btn-hover-color: var(--kv-texte-inverse);
}

.btn-link {
    --bs-btn-color: var(--kv-bleu-600);
    --bs-btn-hover-color: var(--kv-bleu-700);
    --bs-btn-font-weight: 500;
    text-decoration: none;
}

/* Bouton réduit à une icône : carré, à la hauteur des autres contrôles. */
.kv-btn-icone {
    width: var(--kv-hauteur-controle);
    min-width: var(--kv-hauteur-controle);
    padding-left: 0;
    padding-right: 0;
}

.btn .bi {
    font-size: var(--kv-taille-16);
    line-height: 1;
}

/* ==========================================================================
   7. Champs de formulaire
   Saisie à 16 px impérativement : en deçà, Safari iOS zoome au focus.
   ========================================================================== */

.form-label,
.col-form-label {
    font-size: var(--kv-taille-13);
    font-weight: 500;
    color: var(--kv-ardoise-700);
    margin-bottom: var(--kv-espace-1);
}

.form-control,
.form-select {
    font-size: var(--kv-taille-16);
    min-height: var(--kv-hauteur-controle);
    padding: var(--kv-espace-2) var(--kv-espace-3);
    color: var(--kv-texte);
    background-color: #FFFFFF;
    border: 1px solid var(--kv-bordure-forte);
    border-radius: var(--kv-rayon-controle);
    box-shadow: none;
    transition: border-color var(--kv-transition), box-shadow var(--kv-transition);
}

textarea.form-control {
    min-height: 88px;
    line-height: 1.5;
}

.form-control::placeholder {
    color: var(--kv-ardoise-400);
}

.form-control:hover:not(:disabled):not([readonly]),
.form-select:hover:not(:disabled) {
    border-color: var(--kv-ardoise-400);
}

.form-control:focus,
.form-select:focus {
    border-color: var(--kv-bleu-400);
    box-shadow: 0 0 0 3px rgba(var(--kv-bleu-600-rgb), 0.15);
    outline: none;
}

.form-control:disabled,
.form-control[readonly],
.form-select:disabled {
    background-color: var(--kv-ardoise-50);
    color: var(--kv-ardoise-500);
    border-color: var(--kv-bordure);
}

.form-control.is-invalid,
.form-select.is-invalid {
    border-color: var(--kv-danger);
    background-image: none;
    padding-right: var(--kv-espace-3);
}

.form-control.is-invalid:focus,
.form-select.is-invalid:focus {
    border-color: var(--kv-danger);
    box-shadow: 0 0 0 3px rgba(192, 54, 44, 0.15);
}

.invalid-feedback {
    font-size: var(--kv-taille-13);
    color: var(--kv-danger-texte);
    margin-top: var(--kv-espace-1);
}

.form-text {
    font-size: var(--kv-taille-13);
    color: var(--kv-texte-doux);
    margin-top: var(--kv-espace-1);
}

/* Champ de saisie d'un code-barres ou d'un numéro : chasse fixe. */
.form-control.kv-mono {
    letter-spacing: 0.03em;
}

.input-group-text {
    font-size: var(--kv-taille-14);
    color: var(--kv-texte-doux);
    background-color: var(--kv-ardoise-50);
    border-color: var(--kv-bordure-forte);
    border-radius: var(--kv-rayon-controle);
}

.form-check-input {
    width: 1.125rem;
    height: 1.125rem;
    margin-top: 0.1875rem;
    border-color: var(--kv-bordure-forte);
}

.form-check-input:checked {
    background-color: var(--kv-bleu-600);
    border-color: var(--kv-bleu-600);
}

.form-check-input:focus {
    border-color: var(--kv-bleu-400);
    box-shadow: 0 0 0 3px rgba(var(--kv-bleu-600-rgb), 0.15);
}

.form-check-label {
    font-size: var(--kv-taille-14);
}

.form-switch .form-check-input:checked {
    background-color: var(--kv-bleu-600);
}

/* Champ obligatoire : l'astérisque est un repère, pas une décoration. */
.kv-obligatoire::after {
    content: ' *';
    color: var(--kv-danger);
    font-weight: 500;
}

/* Champ de recherche rapide : grande taille, chasse fixe, focus permanent. */
.kv-champ-scan {
    font-family: var(--kv-police-mono);
    font-size: var(--kv-taille-24);
    min-height: 64px;
    text-align: center;
    letter-spacing: 0.06em;
}

/* ==========================================================================
   8. Cartes — blanches sur fond ardoise, jamais l'inverse
   ========================================================================== */

.card,
.kv-carte {
    --bs-card-bg: var(--kv-fond-carte);
    --bs-card-border-color: var(--kv-bordure);
    --bs-card-border-radius: var(--kv-rayon-carte);
    --bs-card-inner-border-radius: calc(var(--kv-rayon-carte) - 1px);
    --bs-card-spacer-x: var(--kv-espace-5);
    --bs-card-spacer-y: var(--kv-espace-4);
    --bs-card-cap-bg: var(--kv-fond-carte);
    --bs-card-cap-padding-x: var(--kv-espace-5);
    --bs-card-cap-padding-y: var(--kv-espace-4);
    background-color: var(--kv-fond-carte);
    border: 1px solid var(--kv-bordure);
    border-radius: var(--kv-rayon-carte);
    box-shadow: var(--kv-ombre-carte);
}

.kv-carte__entete {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--kv-espace-4);
    padding: var(--kv-espace-4) var(--kv-espace-5);
    border-bottom: 1px solid var(--kv-bordure);
}

.kv-carte__titre {
    font-size: var(--kv-taille-14);
    font-weight: 600;
    color: var(--kv-ardoise-900);
    margin: 0;
}

.kv-carte__legende {
    font-size: var(--kv-taille-13);
    color: var(--kv-texte-doux);
    margin: var(--kv-espace-1) 0 0;
}

.kv-carte__corps {
    padding: var(--kv-espace-5);
}

.kv-carte__corps--serre {
    padding: 0;
}

.kv-carte__pied {
    padding: var(--kv-espace-4) var(--kv-espace-5);
    border-top: 1px solid var(--kv-bordure);
    background-color: var(--kv-ardoise-25);
    border-radius: 0 0 calc(var(--kv-rayon-carte) - 1px) calc(var(--kv-rayon-carte) - 1px);
}

/* Carte cliquable — bascule des listes sous 768 px. */
.kv-carte--cliquable {
    transition: border-color var(--kv-transition), box-shadow var(--kv-transition);
}

.kv-carte--cliquable:hover {
    border-color: var(--kv-bleu-300);
    box-shadow: var(--kv-ombre-flottante);
}

/* ==========================================================================
   9. Tableaux — lignes de 48 px
   ========================================================================== */

.table {
    --bs-table-bg: var(--kv-fond-carte);
    --bs-table-color: var(--kv-texte);
    --bs-table-border-color: var(--kv-bordure);
    --bs-table-hover-bg: var(--kv-ardoise-25);
    --bs-table-hover-color: var(--kv-texte);
    --bs-table-striped-bg: var(--kv-ardoise-25);
    --bs-table-active-bg: var(--kv-bleu-50);
    margin-bottom: 0;
    font-size: var(--kv-taille-14);
}

.table > thead {
    border-bottom: 1px solid var(--kv-bordure);
}

.table > thead th {
    font-size: var(--kv-taille-12);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--kv-texte-doux);
    background-color: var(--kv-ardoise-25);
    padding: var(--kv-espace-3) var(--kv-espace-4);
    white-space: nowrap;
    vertical-align: middle;
}

.table > tbody > tr {
    height: var(--kv-hauteur-ligne-tableau);
}

.table > tbody > tr > td {
    padding: var(--kv-espace-3) var(--kv-espace-4);
    vertical-align: middle;
    border-bottom-color: var(--kv-bordure);
}

.table > tbody > tr:last-child > td {
    border-bottom-width: 0;
}

.table-hover > tbody > tr:hover {
    cursor: pointer;
}

/* En-tête figé pour les longues listes de colis. */
.kv-tableau-fige thead th {
    position: sticky;
    top: 0;
    z-index: 2;
}

.kv-tableau-enveloppe {
    overflow-x: auto;
    border-radius: var(--kv-rayon-carte);
}

/* Colonnes de chiffres : alignées à droite, chasse fixe. */
.kv-colonne-nombre {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* ==========================================================================
   10. Pastilles de statut
   Une pastille porte toujours son libellé écrit : la couleur seule ne
   véhicule jamais l'information (charte § 8.2).
   ========================================================================== */

.kv-pastille {
    display: inline-flex;
    align-items: center;
    gap: var(--kv-espace-1);
    padding: 0.125rem var(--kv-espace-3);
    min-height: 24px;
    border: 1px solid transparent;
    border-radius: var(--kv-rayon-pastille);
    font-size: var(--kv-taille-12);
    font-weight: 500;
    line-height: 1.4;
    white-space: nowrap;
}

.kv-pastille--enregistre {
    background-color: var(--kv-ardoise-100);
    color: var(--kv-ardoise-700);
}

.kv-pastille--expedie {
    background-color: var(--kv-signal-fond);
    color: var(--kv-signal-texte);
}

.kv-pastille--arrive {
    background-color: var(--kv-transit-fond);
    color: var(--kv-transit-texte);
}

.kv-pastille--livre {
    background-color: var(--kv-succes-fond);
    color: var(--kv-succes-texte);
}

.kv-pastille--retenu {
    background-color: var(--kv-danger-fond);
    color: var(--kv-danger-texte);
}

.kv-pastille--annule {
    background-color: transparent;
    border-color: var(--kv-ardoise-300);
    color: var(--kv-ardoise-500);
}

/* Le pays porté par deux statuts seulement — origine pour « Enregistré »,
   destination pour « Arrivé ». Code ISO à deux lettres : le nom complet ferait
   déborder la pastille dans un tableau dense. Second plan, parce que le statut
   reste ce qui se lit d'abord. */
.kv-pastille__pays {
    color: inherit;
    opacity: 0.7;
}

/* Pastilles hors statut de colis : obsolescence d'un document, rôle, etc. */
.kv-pastille--neutre {
    background-color: var(--kv-ardoise-100);
    color: var(--kv-ardoise-700);
}

.kv-pastille--signal {
    background-color: var(--kv-signal-fond);
    color: var(--kv-signal-texte);
}

.kv-pastille--info {
    background-color: var(--kv-bleu-50);
    color: var(--kv-bleu-800);
}

.kv-pastille--contour {
    background-color: transparent;
    border-color: var(--kv-ardoise-300);
    color: var(--kv-ardoise-500);
}

/* ==========================================================================
   11. Alertes et notifications
   ========================================================================== */

/* Toasts empilés en haut à droite, 16 px du bord (maquette « États
   transverses »). Position fixe : les notifications flash ne doivent pas
   pousser le contenu de la page, et doivent rester visibles au défilement. */
.kv-notifications {
    position: fixed;
    top: var(--kv-espace-4);
    right: var(--kv-espace-4);
    z-index: 1090;
    display: flex;
    flex-direction: column;
    gap: var(--kv-espace-2);
    width: 100%;
    max-width: 400px;
}

@media (max-width: 575.98px) {
    .kv-notifications {
        left: var(--kv-espace-4);
        right: var(--kv-espace-4);
        max-width: none;
    }
}

.alert {
    --bs-alert-border-radius: var(--kv-rayon-controle);
    --bs-alert-padding-x: var(--kv-espace-4);
    --bs-alert-padding-y: var(--kv-espace-3);
    display: flex;
    align-items: flex-start;
    gap: var(--kv-espace-3);
    font-size: var(--kv-taille-14);
    border-width: 1px;
    margin-bottom: 0;
    box-shadow: 0 4px 12px rgba(24, 24, 22, .1);
}

.alert .bi {
    font-size: var(--kv-taille-16);
    line-height: 1.4;
    flex-shrink: 0;
}

.alert-success {
    --bs-alert-bg: var(--kv-succes-fond);
    --bs-alert-color: var(--kv-succes-texte);
    --bs-alert-border-color: #B9DFCF;
}

.alert-danger {
    --bs-alert-bg: var(--kv-danger-fond);
    --bs-alert-color: var(--kv-danger-texte);
    --bs-alert-border-color: #F2BDB7;
}

.alert-warning {
    --bs-alert-bg: var(--kv-alerte-fond);
    --bs-alert-color: var(--kv-alerte-texte);
    --bs-alert-border-color: var(--kv-signal-fond);
}

.alert-info {
    --bs-alert-bg: var(--kv-bleu-50);
    --bs-alert-color: var(--kv-bleu-800);
    --bs-alert-border-color: var(--kv-bleu-200);
}

/* ==========================================================================
   12. Coquille applicative
   Barre latérale de 240 px repliable à 64 px au-delà de 992 px,
   offcanvas Bootstrap en deçà.
   ========================================================================== */

.kv-appli {
    min-height: 100vh;
}

/* --- Barre latérale ------------------------------------------------------ */

.kv-laterale {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    z-index: 1030;
    width: var(--kv-largeur-laterale);
    display: flex;
    flex-direction: column;
    background-color: var(--kv-bleu-900);
    color: var(--kv-bleu-100);
    transition: width var(--kv-transition);
}

.kv-laterale__marque {
    display: flex;
    align-items: center;
    gap: var(--kv-espace-3);
    height: var(--kv-hauteur-superieure);
    padding: 0 var(--kv-espace-4);
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
    color: #FFFFFF;
    text-decoration: none;
    flex-shrink: 0;
}

.kv-laterale__logo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    flex-shrink: 0;
    border-radius: var(--kv-rayon-controle);
    background-color: var(--kv-bleu-600);
    color: #FFFFFF;
    font-size: var(--kv-taille-16);
}

.kv-laterale__nom {
    font-size: var(--kv-taille-16);
    font-weight: 600;
    letter-spacing: 0.02em;
    white-space: nowrap;
}

.kv-laterale__nav {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: var(--kv-espace-3) var(--kv-espace-2);
}

.kv-laterale__groupe {
    padding: var(--kv-espace-4) var(--kv-espace-3) var(--kv-espace-2);
    font-size: var(--kv-taille-12);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: rgba(255, 255, 255, 0.45);
    white-space: nowrap;
}

.kv-lien {
    display: flex;
    align-items: center;
    gap: var(--kv-espace-3);
    min-height: 40px;
    padding: 0 var(--kv-espace-3);
    margin-bottom: 2px;
    border-radius: var(--kv-rayon-controle);
    color: var(--kv-bleu-100);
    font-size: var(--kv-taille-14);
    font-weight: 400;
    text-decoration: none;
    white-space: nowrap;
    transition: background-color var(--kv-transition), color var(--kv-transition);
}

.kv-lien .bi {
    font-size: var(--kv-taille-18);
    flex-shrink: 0;
    line-height: 1;
}

.kv-lien:hover,
.kv-lien:focus-visible {
    background-color: rgba(255, 255, 255, 0.08);
    color: #FFFFFF;
}

.kv-lien--actif {
    background-color: var(--kv-bleu-600);
    color: #FFFFFF;
    font-weight: 500;
}

.kv-lien--actif:hover {
    background-color: var(--kv-bleu-500);
}

.kv-laterale__pied {
    flex-shrink: 0;
    padding: var(--kv-espace-2);
    border-top: 1px solid rgba(255, 255, 255, 0.08);
}

/* Bouton de repli, visible au-delà de 992 px seulement. */
.kv-laterale__repli {
    display: none;
}

/* --- Contenu ------------------------------------------------------------- */

.kv-contenu {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-width: 0;
    transition: margin-left var(--kv-transition);
}

.kv-page {
    flex: 1 1 auto;
    padding: var(--kv-espace-6);
}

.kv-page__entete {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--kv-espace-4);
    flex-wrap: wrap;
    margin-bottom: var(--kv-espace-5);
}

.kv-page__actions {
    display: flex;
    align-items: center;
    gap: var(--kv-espace-2);
    flex-wrap: wrap;
}

/* --- Barre supérieure ---------------------------------------------------- */

.kv-superieure {
    position: sticky;
    top: 0;
    z-index: 1020;
    display: flex;
    align-items: center;
    gap: var(--kv-espace-3);
    height: var(--kv-hauteur-superieure);
    flex-shrink: 0;
    padding: 0 var(--kv-espace-6);
    background-color: #FFFFFF;
    border-bottom: 1px solid var(--kv-bordure);
}

.kv-superieure__recherche {
    flex: 1 1 auto;
    max-width: 420px;
}

.kv-superieure__recherche .form-control {
    min-height: 36px;
    font-size: var(--kv-taille-14);
    background-color: var(--kv-ardoise-50);
    border-color: var(--kv-bordure);
}

.kv-superieure__actions {
    display: flex;
    align-items: center;
    gap: var(--kv-espace-2);
    margin-left: auto;
}

.kv-superieure__bascule {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border: 0;
    border-radius: var(--kv-rayon-controle);
    background-color: transparent;
    color: var(--kv-ardoise-600);
    font-size: var(--kv-taille-20);
    transition: background-color var(--kv-transition);
}

.kv-superieure__bascule:hover {
    background-color: var(--kv-ardoise-100);
    color: var(--kv-ardoise-900);
}

/* Pastille d'identité dans la barre supérieure. */
.kv-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: var(--kv-rayon-pastille);
    background-color: var(--kv-bleu-50);
    color: var(--kv-bleu-700);
    font-size: var(--kv-taille-13);
    font-weight: 600;
    flex-shrink: 0;
}

.dropdown-menu {
    --bs-dropdown-border-color: var(--kv-bordure);
    --bs-dropdown-border-radius: var(--kv-rayon-carte);
    --bs-dropdown-font-size: var(--kv-taille-14);
    --bs-dropdown-link-hover-bg: var(--kv-ardoise-50);
    --bs-dropdown-link-active-bg: var(--kv-bleu-50);
    --bs-dropdown-link-active-color: var(--kv-bleu-800);
    --bs-dropdown-padding-y: var(--kv-espace-1);
    box-shadow: var(--kv-ombre-flottante);
}

.dropdown-item {
    display: flex;
    align-items: center;
    gap: var(--kv-espace-2);
    min-height: 36px;
}

/* --- Comportement responsive -------------------------------------------- */

/* Bureau : la latérale est fixe, le contenu se décale. */
@media (min-width: 992px) {
    .kv-contenu {
        margin-left: var(--kv-largeur-laterale);
    }

    .kv-laterale__repli {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 100%;
        min-height: 36px;
        border: 0;
        border-radius: var(--kv-rayon-controle);
        background-color: transparent;
        color: rgba(255, 255, 255, 0.6);
        font-size: var(--kv-taille-18);
        transition: background-color var(--kv-transition), color var(--kv-transition);
    }

    .kv-laterale__repli:hover {
        background-color: rgba(255, 255, 255, 0.08);
        color: #FFFFFF;
    }

    /* État replié : rail de 64 px, libellés masqués, icônes centrées. */
    .kv-laterale-reduite .kv-laterale {
        width: var(--kv-largeur-laterale-reduite);
    }

    .kv-laterale-reduite .kv-contenu {
        margin-left: var(--kv-largeur-laterale-reduite);
    }

    .kv-laterale-reduite .kv-laterale__nom,
    .kv-laterale-reduite .kv-laterale__groupe,
    .kv-laterale-reduite .kv-lien__libelle {
        display: none;
    }

    .kv-laterale-reduite .kv-laterale__marque,
    .kv-laterale-reduite .kv-lien {
        justify-content: center;
        padding-left: 0;
        padding-right: 0;
    }

    .kv-laterale-reduite .kv-lien {
        gap: 0;
    }
}

/* Mobile : la latérale disparaît, la navigation passe en offcanvas. */
@media (max-width: 991.98px) {
    .kv-laterale {
        display: none;
    }

    .kv-contenu {
        margin-left: 0;
    }

    .kv-superieure,
    .kv-page {
        padding-left: var(--kv-espace-4);
        padding-right: var(--kv-espace-4);
    }

    .kv-page {
        padding-top: var(--kv-espace-4);
        padding-bottom: var(--kv-espace-4);
    }
}

/* Le hamburger n'existe qu'en dessous de 992 px. */
.kv-superieure__hamburger {
    display: inline-flex;
}

@media (min-width: 992px) {
    .kv-superieure__hamburger {
        display: none;
    }
}

/* Offcanvas de navigation : même habillage que la latérale. */
.kv-offcanvas {
    width: var(--kv-largeur-laterale) !important;
    background-color: var(--kv-bleu-900);
    color: var(--kv-bleu-100);
}

.kv-offcanvas .kv-laterale__nav {
    padding: var(--kv-espace-3) var(--kv-espace-2);
}

/* --- Écrans sans session -------------------------------------------------
   Conforme à docs/maquettes/Connexion.dc.html, qui fait foi pour la mise en
   page. Deux points s'en écartent volontairement, et les deux sont motivés
   dans resources/views/auth/connexion.blade.php : le sous-titre ne nomme pas
   l'agence, inconnue avant authentification, et le sélecteur de langue est
   présent alors que la maquette l'omet — le cahier des charges l'exige (E1,
   RG-62).

   Le fond est blanc, pas ardoise : c'est le seul écran du produit où le
   contenu ne vit pas dans une carte. Le contraste vient du panneau de marque.
   ------------------------------------------------------------------------- */

.kv-invite {
    display: flex;
    min-height: 100vh;
    background-color: var(--kv-fond-carte);
}

.kv-invite__panneau {
    display: none;
}

.kv-invite__zone {
    position: relative;
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    /* Le rembourrage haut laisse la place aux réglages, positionnés dans le
       coin : sans lui, ils chevaucheraient le formulaire sur un écran court. */
    padding: var(--kv-espace-10) var(--kv-espace-6) var(--kv-espace-8);
    background-color: var(--kv-fond-carte);
}

.kv-invite__boite {
    width: 100%;
    max-width: 400px;
}

/* 14 px et non 13 : sur cet écran le sous-titre est une phrase d'accueil, pas
   un libellé de champ. La maquette le fixe ainsi. */
.kv-invite .kv-sous-titre {
    font-size: var(--kv-taille-14);
}

.kv-invite__marque {
    display: flex;
    align-items: center;
    gap: var(--kv-espace-3);
    color: #FFFFFF;
}

/* Losange : un carré tourné, jamais une icône de la fonte. La marque doit
   rester identique là où Bootstrap Icons n'est pas chargé — un PDF, un
   courriel, un écran dont la fonte n'a pas fini de se télécharger. */
.kv-invite__losange {
    width: 28px;
    height: 28px;
    flex: 0 0 28px;
    border: 2px solid currentColor;
    border-radius: var(--kv-rayon-controle);
    transform: rotate(45deg);
}

.kv-invite__nom {
    font-size: var(--kv-taille-20);
    font-weight: 600;
    letter-spacing: 0.02em;
}

.kv-invite__marque--compacte {
    margin-bottom: var(--kv-espace-8);
    color: var(--kv-bleu-600);
}

.kv-invite__marque--compacte .kv-invite__losange {
    width: 26px;
    height: 26px;
    flex-basis: 26px;
}

.kv-invite__pied {
    font-size: var(--kv-taille-12);
    color: var(--kv-ardoise-400);
    text-align: center;
    text-wrap: pretty;
    margin: var(--kv-espace-6) 0 0;
}

/* Réglages de l'écran, en haut à droite : c'est la convention, et c'est vu
   avant de commencer à saisir. Le sélecteur de langue y vit — la personne qui
   en a besoin est justement celle qui ne lit pas la langue affichée, et un
   réglage placé en pied serait la dernière chose qu'elle trouverait.

   Il est aussi premier dans l'ordre du document, pour que le clavier et les
   lecteurs d'écran le rencontrent avant le formulaire. */
.kv-invite__reglages {
    position: absolute;
    top: var(--kv-espace-4);
    right: var(--kv-espace-4);
    z-index: 1;
}

@media (min-width: 992px) {
    .kv-invite__reglages {
        top: var(--kv-espace-6);
        right: var(--kv-espace-6);
    }
}

/* --- Sélecteur de langue ------------------------------------------------- */

.kv-langues__groupe {
    display: inline-flex;
    align-items: center;
}

.kv-langues__choix {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    /* 40 px de haut, 44 sur mobile : c'est un contrôle, il se touche du doigt.
       La discrétion vient de la couleur, pas d'une cible trop petite. */
    min-height: var(--kv-hauteur-controle);
    padding: 0 var(--kv-espace-2);
    border: 0;
    background: none;
    font-family: var(--kv-police-mono);
    font-size: var(--kv-taille-12);
    color: var(--kv-ardoise-400);
    border-radius: var(--kv-rayon-controle);
    transition: color var(--kv-transition), background-color var(--kv-transition);
}

.kv-langues__choix:hover {
    color: var(--kv-bleu-600);
    background-color: var(--kv-ardoise-50);
}

.kv-langues__choix--actif {
    color: var(--kv-bleu-600);
    font-weight: 500;
}

/* Séparateur : un filet entre les choix, pour qu'ils se lisent comme une
   alternative et non comme deux boutons sans rapport. */
.kv-langues__choix + .kv-langues__choix {
    border-left: 1px solid var(--kv-bordure);
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}

/* Lien secondaire : présent sans réclamer l'attention, souligné au survol
   seulement. Le bleu 600 est structurant, pas décoratif (charte § 8.4). */
.kv-lien-discret {
    color: var(--kv-ardoise-600);
    text-decoration: none;
}

.kv-lien-discret:hover,
.kv-lien-discret:focus-visible {
    color: var(--kv-bleu-600);
    text-decoration: underline;
}

/* Panneau de marque à gauche au-delà de 992 px (écran E1). */
@media (min-width: 992px) {
    .kv-invite__panneau {
        position: relative;
        overflow: hidden;
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        width: 45%;
        flex: 0 0 45%;
        padding: var(--kv-espace-10) var(--kv-espace-8);
        background-color: var(--kv-bleu-800);
        color: var(--kv-bleu-200);
    }

    .kv-invite__panneau > * {
        position: relative;
    }

    /* Motif de fond : des filets et deux cercles, tracés en CSS pour ne pas
       encombrer le gabarit de div décoratives. Le dégradé ne dégrade rien —
       il sert à répéter une ligne de 1 px, pas à faire varier une couleur.
       La charte interdit les dégradés décoratifs, pas cet usage. */
    .kv-invite__motif {
        position: absolute;
        inset: 0;
        pointer-events: none;
        background-image: repeating-linear-gradient(
            114deg,
            rgba(255, 255, 255, 0.09) 0 1px,
            transparent 1px 132px
        );
    }

    .kv-invite__motif::before,
    .kv-invite__motif::after {
        content: '';
        position: absolute;
        border: 1px solid rgba(255, 255, 255, 0.08);
        border-radius: var(--kv-rayon-pastille);
    }

    .kv-invite__motif::before {
        right: -120px;
        bottom: -120px;
        width: 360px;
        height: 360px;
    }

    .kv-invite__motif::after {
        right: -60px;
        bottom: -60px;
        width: 240px;
        height: 240px;
        border-color: rgba(255, 255, 255, 0.06);
    }

    .kv-invite__discours {
        max-width: 420px;
    }

    .kv-invite__accroche {
        font-size: var(--kv-taille-24);
        font-weight: 500;
        line-height: 1.4;
        color: #FFFFFF;
        text-wrap: pretty;
        margin: 0 0 var(--kv-espace-4);
    }

    .kv-invite__mention {
        font-size: var(--kv-taille-14);
        line-height: 1.6;
        color: var(--kv-bleu-200);
        text-wrap: pretty;
        margin: 0;
    }

    /* Rappel de périmètre en pied de panneau : le client final n'a pas de
       compte, et une personne arrivée là par erreur doit le comprendre. */
    .kv-invite__reserve {
        display: flex;
        align-items: center;
        gap: var(--kv-espace-2);
        font-size: var(--kv-taille-12);
        color: var(--kv-bleu-300);
    }
}

/* Bouton d'affichage du mot de passe, accolé au champ. Sa hauteur suit celle
   du champ, qui passe à 44 px sous 992 px — la cible tactile minimale. */
.kv-invite__oeil {
    border: 1px solid var(--kv-bordure);
    border-left: 0;
    border-radius: 0 var(--kv-rayon-controle) var(--kv-rayon-controle) 0;
    background-color: var(--kv-fond-carte);
    color: var(--kv-ardoise-600);
    width: 48px;
    min-height: var(--kv-hauteur-controle);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color var(--kv-transition), color var(--kv-transition);
}

.kv-invite__oeil:hover {
    background-color: var(--kv-ardoise-50);
    color: var(--kv-bleu-600);
}

/* ==========================================================================
   13. État vide et squelettes de chargement
   Un écran vide est une invitation à agir, pas un constat de vide.
   ========================================================================== */

.kv-etat-vide {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--kv-espace-3);
    padding: var(--kv-espace-10) var(--kv-espace-6);
    text-align: center;
}

.kv-etat-vide__icone {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: var(--kv-rayon-pastille);
    background-color: var(--kv-ardoise-100);
    color: var(--kv-ardoise-500);
    font-size: var(--kv-taille-24);
}

.kv-etat-vide__titre {
    font-size: var(--kv-taille-16);
    font-weight: 600;
    color: var(--kv-ardoise-900);
    margin: 0;
}

.kv-etat-vide__texte {
    font-size: var(--kv-taille-14);
    color: var(--kv-texte-doux);
    max-width: 42ch;
    margin: 0;
}

.kv-squelette {
    display: block;
    height: 1em;
    border-radius: var(--kv-rayon-controle);
    background-color: var(--kv-ardoise-100);
    animation: kv-pulsation 1.4s ease-in-out infinite;
}

@keyframes kv-pulsation {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

/* ==========================================================================
   14. Utilitaires kv-
   Créés seulement là où Bootstrap n'a pas d'équivalent.
   ========================================================================== */

.kv-t-12 { font-size: var(--kv-taille-12); }
.kv-t-13 { font-size: var(--kv-taille-13); }
.kv-t-14 { font-size: var(--kv-taille-14); }
.kv-t-16 { font-size: var(--kv-taille-16); }
.kv-t-18 { font-size: var(--kv-taille-18); }
.kv-t-20 { font-size: var(--kv-taille-20); }
.kv-t-24 { font-size: var(--kv-taille-24); }

.kv-g-400 { font-weight: 400; }
.kv-g-500 { font-weight: 500; }
.kv-g-600 { font-weight: 600; }

.kv-doux { color: var(--kv-texte-doux); }
.kv-fort { color: var(--kv-ardoise-900); }
.kv-marque { color: var(--kv-bleu-600); }

.kv-fond-page { background-color: var(--kv-fond-page); }
.kv-fond-carte { background-color: var(--kv-fond-carte); }
.kv-fond-enfonce { background-color: var(--kv-fond-enfonce); }

.kv-bordure { border: 1px solid var(--kv-bordure); }
.kv-bordure-haut { border-top: 1px solid var(--kv-bordure); }
.kv-bordure-bas { border-bottom: 1px solid var(--kv-bordure); }

.kv-rayon-controle { border-radius: var(--kv-rayon-controle); }
.kv-rayon-carte { border-radius: var(--kv-rayon-carte); }

/* Coupe un texte long sur une ligne sans casser la grille. */
.kv-tronque {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

/* ------------------------------------------------------------------------
   Fil des étapes de l'assistant d'envoi (E3)
   ------------------------------------------------------------------------ */

.kv-etapes {
    display: grid;

    /* minmax(0, 1fr) et NON 1fr : « 1fr » vaut « minmax(auto, 1fr) », dont la
       taille minimale est celle du contenu. Les pistes refusaient donc de
       rétrécir, la grille débordait de sa carte, et la troisième étape sortait
       de l'écran au lieu de laisser son libellé se tronquer. */
    grid-template-columns: repeat(3, minmax(0, 1fr));

    gap: 8px;
    margin: 0;
    padding: 12px;
    list-style: none;
}

/* Même raison : sans min-width, l'élément de grille impose sa taille de
   contenu à la piste, et minmax(0, 1fr) ne sert plus à rien. */
.kv-etapes > li { min-width: 0; }

.kv-etape {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 8px;
    text-align: left;
    background: none;
    border: 1px solid var(--kv-bordure);
    border-radius: var(--kv-rayon-controle);
}

.kv-etape--active {
    border-color: var(--kv-bleu-600);
    background: var(--kv-bleu-50);
}

.kv-etape__puce {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 28px;
    width: 28px;
    height: 28px;
    border-radius: 999px;
    font-size: 13px;
    font-weight: 600;
    background: var(--kv-ardoise-100);
    color: var(--kv-texte-doux);
}

.kv-etape__puce--atteinte {
    background: var(--kv-bleu-600);
    color: #fff;
}

.kv-etape__texte {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.kv-etape__rang {
    font-size: 12px;
    color: var(--kv-texte-doux);
    text-transform: uppercase;
}

.kv-etape__titre {
    font-size: 14px;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Sous 576 px, trois libellés côte à côte ne tiennent pas : « Expéditeur et
   destinataire » dans une centaine de pixels ne se lit pas, et tronqué il ne
   dit rien — « Exp… ». On garde les trois pastilles, pour que le parcours reste
   visible, et l'on n'affiche le libellé que de l'étape en cours : c'est la
   seule dont on ait besoin de lire le nom.

   La grille cède la place à une boîte flexible : les étapes non courantes se
   réduisent à leur pastille, l'étape courante prend TOUT le reste. En trois
   colonnes égales, elle n'aurait eu qu'un tiers de la largeur pour un libellé
   qui a besoin de tout. */
@media (max-width: 575.98px) {
    .kv-etapes {
        display: flex;
        gap: 6px;
        padding: 10px;
    }

    .kv-etapes > li { flex: 0 0 auto; }
    .kv-etapes > li.kv-etapes__actif { flex: 1 1 auto; min-width: 0; }

    .kv-etape { gap: 8px; }

    /* Le rang disparaît : la pastille porte déjà le numéro. */
    .kv-etape__rang { display: none; }

    .kv-etape:not(.kv-etape--active) { justify-content: center; }
    .kv-etape:not(.kv-etape--active) .kv-etape__texte { display: none; }
}

/* Réservé aux lecteurs d'écran et au saut de navigation. */
.kv-saut-nav {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 1080;
}

.kv-saut-nav:focus {
    left: var(--kv-espace-4);
    top: var(--kv-espace-2);
    padding: var(--kv-espace-2) var(--kv-espace-4);
    background-color: #FFFFFF;
    border-radius: var(--kv-rayon-controle);
    box-shadow: var(--kv-ombre-flottante);
}

/* Paire libellé / valeur des fiches. */
.kv-definition {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--kv-espace-1);
    margin-bottom: var(--kv-espace-4);
}

.kv-definition__libelle {
    font-size: var(--kv-taille-12);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--kv-texte-doux);
}

.kv-definition__valeur {
    font-size: var(--kv-taille-14);
    color: var(--kv-texte);
}

/* Indicateur du tableau de bord. */
.kv-indicateur__valeur {
    font-size: var(--kv-taille-24);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--kv-ardoise-900);
    line-height: 1.2;
}

.kv-indicateur__libelle {
    font-size: var(--kv-taille-13);
    color: var(--kv-texte-doux);
}

/* Journal d'activité : filet vertical reliant les événements. */
.kv-journal {
    list-style: none;
    padding: 0;
    margin: 0;
}

.kv-journal__ligne {
    position: relative;
    padding: 0 0 var(--kv-espace-4) var(--kv-espace-6);
    border-left: 1px solid var(--kv-bordure);
}

.kv-journal__ligne:last-child {
    border-left-color: transparent;
    padding-bottom: 0;
}

.kv-journal__ligne::before {
    content: '';
    position: absolute;
    left: -4.5px;
    top: 5px;
    width: 8px;
    height: 8px;
    border-radius: var(--kv-rayon-pastille);
    background-color: var(--kv-ardoise-300);
}

.kv-journal__date {
    font-size: var(--kv-taille-12);
    color: var(--kv-texte-doux);
    font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   14 bis. Écrans E8 et E9 — utilisateurs, paramètres, menu du compte
   Conforme à docs/maquettes/Utilisateurs.dc.html et Paramètres.dc.html.
   ========================================================================== */

/* --- Menu du compte, en pied de barre latérale ---------------------------

   La maquette le place là, et le cahier des charges le confirme (§ 6) : le
   menu utilisateur vit en bas de la barre latérale de tous les écrans
   authentifiés. Il vit donc sur le bleu 900, d'où les couleurs claires
   ci-dessous — la pastille d'identité, elle, garde son fond bleu 50, qui
   ressort sur ce fond sombre sans qu'il faille une seconde variante.
   ------------------------------------------------------------------------- */

.kv-compte {
    display: flex;
    align-items: center;
    gap: var(--kv-espace-3);
    width: 100%;
    min-height: 48px;
    padding: var(--kv-espace-2);
    border: 0;
    border-radius: var(--kv-rayon-controle);
    background-color: transparent;
    color: var(--kv-bleu-100);
    text-align: left;
    transition: background-color var(--kv-transition);
}

.kv-compte:hover,
.kv-compte[aria-expanded='true'] {
    background-color: rgba(255, 255, 255, 0.08);
}

.kv-compte__identite {
    min-width: 0;
    flex: 1 1 auto;
}

.kv-compte__nom {
    display: block;
    font-size: var(--kv-taille-13);
    font-weight: 500;
    color: #FFFFFF;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kv-compte__role {
    display: block;
    font-size: var(--kv-taille-12);
    color: rgba(255, 255, 255, 0.6);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.kv-compte__chevron {
    flex-shrink: 0;
    font-size: var(--kv-taille-12);
    color: rgba(255, 255, 255, 0.5);
}

/* Replié : ne reste que la pastille, centrée sur le rail de 64 px. */
@media (min-width: 992px) {
    .kv-laterale-reduite .kv-compte__identite,
    .kv-laterale-reduite .kv-compte__chevron {
        display: none;
    }

    .kv-laterale-reduite .kv-compte {
        justify-content: center;
    }
}

/* Le sélecteur de langue posé dans le menu déroulant, sur fond blanc : il
   retrouve les couleurs de l'écran de connexion sans variante sombre. */
.kv-menu-langue {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--kv-espace-3);
    padding: var(--kv-espace-1) var(--kv-espace-3);
}

/* --- Actions d'une ligne de tableau -------------------------------------- */

.kv-acte {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--kv-hauteur-controle);
    height: var(--kv-hauteur-controle);
    border: 1px solid transparent;
    border-radius: var(--kv-rayon-controle);
    background-color: transparent;
    color: var(--kv-ardoise-600);
    font-size: var(--kv-taille-16);
    transition: background-color var(--kv-transition), border-color var(--kv-transition), color var(--kv-transition);
}

.kv-acte:hover {
    background-color: var(--kv-ardoise-50);
    border-color: var(--kv-bordure);
    color: var(--kv-bleu-600);
}

.kv-acte:disabled {
    color: var(--kv-ardoise-300);
    background-color: transparent;
    border-color: transparent;
}

.kv-acte--danger:hover {
    background-color: var(--kv-danger-fond);
    border-color: var(--kv-danger-fond);
    color: var(--kv-danger-texte);
}

/* Ligne d'un compte désactivé : la couleur seule ne dit rien, la pastille
   « Désactivé » porte l'information. L'atténuation n'est qu'un renfort. */
.kv-ligne--eteinte .kv-avatar {
    background-color: var(--kv-ardoise-100);
    color: var(--kv-ardoise-400);
}

.kv-ligne--eteinte .kv-cellule-nom,
.kv-ligne--eteinte .kv-cellule-email {
    color: var(--kv-texte-doux);
}

/* --- Choix d'un rôle, en cartes cliquables ------------------------------- */

.kv-choix {
    display: flex;
    align-items: flex-start;
    gap: var(--kv-espace-3);
    padding: var(--kv-espace-3);
    border: 1px solid var(--kv-bordure);
    border-radius: var(--kv-rayon-controle);
    background-color: var(--kv-fond-carte);
    cursor: pointer;
    transition: background-color var(--kv-transition), border-color var(--kv-transition);
}

.kv-choix:hover {
    background-color: var(--kv-ardoise-25);
}

.kv-choix:has(input:checked) {
    border-color: var(--kv-bleu-600);
    background-color: var(--kv-bleu-50);
}

/* Repli pour les navigateurs sans :has() — la bordure de focus reste, et
   c'est le bouton radio lui-même qui dit ce qui est coché. */
.kv-choix:focus-within {
    border-color: var(--kv-bleu-300);
}

.kv-choix input {
    margin: 2px 0 0;
    flex: 0 0 auto;
    min-height: 0;
}

.kv-choix__titre {
    display: block;
    font-size: var(--kv-taille-14);
    font-weight: 500;
    color: var(--kv-ardoise-900);
}

.kv-choix__texte {
    display: block;
    font-size: var(--kv-taille-13);
    color: var(--kv-ardoise-600);
    margin-top: 2px;
}

/* --- Onglets verticaux des paramètres ------------------------------------ */

.kv-onglets {
    display: flex;
    flex-direction: column;
    padding: var(--kv-espace-2) 0;
}

.kv-onglet {
    display: flex;
    align-items: flex-start;
    gap: var(--kv-espace-3);
    width: 100%;
    min-height: 44px;
    padding: var(--kv-espace-3);
    border: 0;
    border-left: 2px solid transparent;
    background-color: transparent;
    color: var(--kv-ardoise-700);
    text-align: left;
    text-decoration: none;
    transition: background-color var(--kv-transition), color var(--kv-transition), border-color var(--kv-transition);
}

.kv-onglet:hover {
    background-color: var(--kv-ardoise-25);
    color: var(--kv-bleu-600);
}

.kv-onglet--actif {
    background-color: var(--kv-bleu-50);
    border-left-color: var(--kv-bleu-600);
    color: var(--kv-bleu-600);
}

.kv-onglet__titre {
    display: block;
    font-size: var(--kv-taille-14);
    font-weight: 500;
}

.kv-onglet__resume {
    display: block;
    font-size: var(--kv-taille-12);
    color: var(--kv-texte-doux);
    margin-top: 2px;
}

/* --- Dépôt du logo ------------------------------------------------------- */

.kv-depot {
    display: flex;
    align-items: center;
    gap: var(--kv-espace-4);
    padding: var(--kv-espace-4);
    border: 1px dashed var(--kv-bordure-forte);
    border-radius: var(--kv-rayon-carte);
    background-color: var(--kv-ardoise-25);
    transition: border-color var(--kv-transition), background-color var(--kv-transition);
}

.kv-depot:hover,
.kv-depot:focus-within {
    border-color: var(--kv-bleu-300);
    background-color: var(--kv-bleu-50);
}

.kv-depot__vignette {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 72px;
    height: 72px;
    flex: 0 0 72px;
    overflow: hidden;
    border: 1px solid var(--kv-bordure);
    border-radius: var(--kv-rayon-controle);
    background-color: var(--kv-fond-carte);
    color: var(--kv-ardoise-400);
}

.kv-depot__vignette img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/* --- Aperçu de l'en-tête de document ------------------------------------- */

.kv-apercu {
    padding: var(--kv-espace-5);
    background-color: var(--kv-fond-page);
    border-radius: 0 0 var(--kv-rayon-carte) var(--kv-rayon-carte);
}

.kv-apercu__feuille {
    padding: var(--kv-espace-5);
    background-color: #FFFFFF;
    border: 1px solid var(--kv-bordure);
    border-radius: var(--kv-rayon-controle);
    box-shadow: var(--kv-ombre-carte);
}

.kv-apercu__entete {
    display: flex;
    align-items: flex-start;
    gap: var(--kv-espace-4);
    padding-bottom: var(--kv-espace-4);
    border-bottom: 2px solid var(--kv-bleu-600);
}

.kv-apercu__logo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    flex: 0 0 56px;
    overflow: hidden;
    border: 1px solid var(--kv-bordure);
    border-radius: 4px;
    color: var(--kv-ardoise-400);
}

.kv-apercu__logo img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.kv-apercu__agence {
    font-size: var(--kv-taille-16);
    font-weight: 600;
    color: var(--kv-ardoise-900);
}

.kv-apercu__ligne {
    font-size: var(--kv-taille-12);
    color: var(--kv-ardoise-600);
    margin-top: var(--kv-espace-1);
    white-space: pre-line;
}

.kv-apercu__document {
    font-size: var(--kv-taille-13);
    font-weight: 600;
    color: var(--kv-bleu-700);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* Traits de remplissage : l'aperçu montre une mise en page, pas un contenu. */
.kv-apercu__trait {
    height: 8px;
    border-radius: 2px;
    background-color: var(--kv-ardoise-100);
    margin-top: var(--kv-espace-2);
}

.kv-apercu__pied {
    display: flex;
    justify-content: space-between;
    gap: var(--kv-espace-3);
    margin-top: var(--kv-espace-4);
    padding-top: var(--kv-espace-3);
    border-top: 1px solid var(--kv-bordure);
    font-size: var(--kv-taille-12);
    color: var(--kv-texte-doux);
}

/* --- Modales -------------------------------------------------------------

   Ouvertes par Alpine et non par le JavaScript de Bootstrap : l'état vit déjà
   côté Alpine — quelle modale, sur quelle ligne —, et deux mécanismes qui
   ouvrent la même fenêtre finissent par se contredire au premier refus de
   validation, quand il faut la rouvrir depuis le serveur.
   ------------------------------------------------------------------------- */

.modal-content {
    border: 1px solid var(--kv-bordure);
    border-radius: var(--kv-rayon-carte);
    box-shadow: var(--kv-ombre-flottante);
}

.modal-header,
.modal-footer {
    border-color: var(--kv-ardoise-100);
    padding: var(--kv-espace-4) var(--kv-espace-5);
}

.modal-footer {
    gap: var(--kv-espace-3);
}

.modal-body {
    padding: var(--kv-espace-5);
}

/* Suggestions de motif — des raccourcis de saisie, pas des cases à cocher :
   elles remplissent le champ, qui reste modifiable. Rien n'est prérempli, un
   motif prérempli se validant sans être lu. */

.kv-suggestions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--kv-espace-2);
    margin-bottom: var(--kv-espace-2);
}

.kv-suggestion {
    height: 28px;
    padding: 0 var(--kv-espace-3);
    border: 1px solid var(--kv-bordure);
    border-radius: var(--kv-rayon-pastille);
    background-color: transparent;
    font-size: var(--kv-taille-13);
    color: var(--kv-ardoise-700);
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.kv-suggestion:hover {
    border-color: var(--kv-bleu-300);
    background-color: var(--kv-bleu-50);
    color: var(--kv-bleu-700);
}

.kv-suggestion--retenue {
    border-color: var(--kv-bleu-300);
    background-color: var(--kv-bleu-50);
    color: var(--kv-bleu-700);
    font-weight: 500;
}

/* Alpine n'est chargé qu'en fin de document : sans cette règle, tout ce qui
   est piloté par lui s'afficherait le temps d'un battement de cil. */
[x-cloak] {
    display: none !important;
}

/* --- Panneau latéral ------------------------------------------------------

   Fiche d'édition ouverte depuis une liste (écran E7, puis la fiche envoi).
   Repose sur l'offcanvas de Bootstrap pour la position et la transition, mais
   pilotée par Alpine : la classe « show » suffit à l'afficher, sans le
   JavaScript de Bootstrap.
   ------------------------------------------------------------------------- */

.kv-panneau {
    width: 100%;
    max-width: 480px;
    display: flex;
    flex-direction: column;
    background-color: var(--kv-fond-carte);
    border-left: 1px solid var(--kv-bordure);
}

.kv-panneau__entete {
    flex: 0 0 auto;
    display: flex;
    align-items: flex-start;
    gap: var(--kv-espace-3);
    padding: var(--kv-espace-4) var(--kv-espace-5);
    border-bottom: 1px solid var(--kv-ardoise-100);
}

/* Le corps est la seule zone qui défile : l'en-tête garde le nom sous les yeux
   et le pied garde le bouton d'enregistrement atteignable, quelle que soit la
   longueur du formulaire. */
.kv-panneau__corps {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

.kv-panneau__section {
    padding: var(--kv-espace-4) var(--kv-espace-5);
    border-bottom: 1px solid var(--kv-ardoise-100);
}

.kv-panneau__section:last-child {
    border-bottom: 0;
}

.kv-panneau__pied {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: var(--kv-espace-3);
    flex-wrap: wrap;
    padding: var(--kv-espace-4) var(--kv-espace-5);
    border-top: 1px solid var(--kv-ardoise-100);
    background-color: var(--kv-fond-carte);
}

.kv-section-titre {
    margin: 0 0 var(--kv-espace-3);
    font-size: var(--kv-taille-13);
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--kv-texte-doux);
}

.kv-avatar--grand {
    width: 40px;
    height: 40px;
    flex: 0 0 40px;
    font-size: var(--kv-taille-14);
}

/* --- Ligne de tableau ouvrable -------------------------------------------

   La ligne entière s'ouvre à la souris. Le bouton de la dernière colonne
   reste le chemin du clavier : une ligne de tableau n'est ni focalisable ni
   annonçable comme cliquable.
   ------------------------------------------------------------------------- */

.kv-ligne-ouvrable {
    cursor: pointer;
}

.kv-ligne-ouvrable:hover {
    background-color: var(--kv-ardoise-25);
}

.kv-ligne--retenue,
.kv-ligne--retenue:hover {
    background-color: var(--kv-bleu-50);
}

/* --- Encadré d'explication ----------------------------------------------- */

.kv-note {
    display: flex;
    align-items: flex-start;
    gap: var(--kv-espace-2);
    padding: var(--kv-espace-3);
    border-radius: var(--kv-rayon-controle);
    background-color: var(--kv-ardoise-50);
    font-size: var(--kv-taille-13);
    color: var(--kv-ardoise-600);
}

.kv-note .bi {
    flex-shrink: 0;
    margin-top: 2px;
    color: var(--kv-ardoise-400);
}

/* ==========================================================================
   15. Impression
   Les documents PDF ont leurs propres gabarits ; ceci concerne l'impression
   d'un écran depuis le navigateur.
   ========================================================================== */

@media print {
    .kv-laterale,
    .kv-superieure,
    .kv-page__actions,
    .kv-notifications,
    .offcanvas {
        display: none !important;
    }

    .kv-contenu {
        margin-left: 0;
    }

    .card,
    .kv-carte {
        border-color: var(--kv-ardoise-300);
        box-shadow: none;
        break-inside: avoid;
    }

    body {
        background-color: #FFFFFF;
    }
}
