/*
 * Thème RH — surcouche du design system Bootstrap 5.3.
 * Chargé après bootstrap.min.css (voir assets/app.js) : les surcharges gagnent.
 * Source des tokens : https://designsystem.topcrono.com/
 */

:root {
   /* --- Design tokens clinique / soins --- */
   --tc-red: #0E7A8A;
   --tc-red-hover: #0B6673;
   --tc-red-active: #094F5E;
   --tc-red-subtle: #EAF8FA;
   --tc-red-border: #C9E7EC;
   --tc-red-soft: rgba(14, 122, 138, .13);
   --tc-red-light: #48A7B3;

   /* --- Jetons de contraste -------------------------------------------------
      Ces quatre jetons ne portent PAS une couleur de la charte, mais la couleur
      de TEXTE qui reste lisible par-dessus. Ils sont calculés à partir de la
      charte de l'entreprise (voir App\Service\Branding\BrandPalette) et
      surchargés par le bloc de thème de base.html.twig. Les valeurs ci-dessous
      sont celles du design system : elles s'appliquent si ce bloc venait à
      manquer.

      --tc-on-primary : encre posée sur la couleur de marque (boutons, badges).
                        Sur une charte jaune, du blanc donnerait un contraste de
                        1,4 — le texte disparaîtrait.
      --tc-on-sidebar : encre posée sur la barre latérale. Toujours blanche en
                        pratique, mais calculée pour suivre si les bornes de la
                        barre latérale venaient à bouger.
      --tc-accent-ink : la couleur de marque employée comme couleur de TEXTE.
                        Une charte claire y est assombrie juste assez pour
                        rester lisible — et l'encre s'éclaircit la nuit, puisque
                        ce jeton suit le thème.
      --tc-accent-on-light : la même, mais GARANTIE sur une surface claire quel
                        que soit le thème. Sert au petit nombre d'endroits dont
                        le fond reste blanc de jour comme de nuit — la pastille
                        du logo, par exemple. Sans elle, ces endroits prenaient
                        l'encre claire du mode sombre et le texte disparaissait
                        sur leur propre fond.
   ------------------------------------------------------------------------- */
   --tc-on-primary: #FFFFFF;
   --tc-on-sidebar: #FFFFFF;
   --tc-accent-ink: #0E7A8A;
   --tc-accent-on-light: #0E7A8A;

    /* Statuts (design system EasyCH) — fond / bordure / texte */
    --tc-amber-bg: #FEF3E2;
    --tc-amber-border: #F5E3BC;
    --tc-amber-ink: #B9770E;
    --tc-green-bg: #E7F5EC;
    --tc-green-border: #CDE9D5;
    --tc-green-ink: #1E7E34;
    --tc-info-bg: #E7F0FE;
    --tc-info-border: #C7DBFB;
    --tc-info-ink: #0B5ED7;
    /* Danger — famille SÉMANTIQUE, et c'est tout l'intérêt : elle ne suit PAS
       la charte de l'entreprise. « Rouge = danger » est une convention
       d'interface, pas une identité de marque.

       Sans elle, le code détournait les jetons de marque pour dire le danger
       (`--tc-red` sur `.tone-danger`, `.app-menu__item--danger`,
       `.clegal-note--danger`…). Tant que la charte était cramoisie cela passait
       inaperçu ; avec une charte jaune ou verte, un message d'erreur prend la
       couleur de la marque — au mieux il cesse d'alerter, au pire il disparaît
       sur son propre fond. */
    --tc-danger-bg: #FDECEA;
    --tc-danger-border: #F1C0BC;
    --tc-danger-ink: #C0392B;

   --tc-sidebar: #123C4A;
   --tc-sidebar-border: #1C5364;
   --tc-sidebar-hover: #184D5D;
   --tc-sidebar-muted: #D8EEF1;
   --tc-sidebar-section: #9CCBD1;
   --tc-sidebar-faint: #7B898E;

   --tc-ink: #16323C;
   --tc-ink-2: #355A66;
   --tc-ink-3: #5C7C85;
   --tc-ink-4: #90A8AF;
   --tc-border: #D7E6EA;
   --tc-bg: #F3F9F8;
    --tc-surface: #FFFFFF;
   --tc-surface-soft: #F7FBFC;
   --tc-surface-alt: #EDF7F9;

   --bs-body-bg: #F3F9F8;
   --bs-body-color: #16323C;
    --bs-card-bg: #FFFFFF;
   --bs-card-color: #16323C;
   --bs-secondary-color: #5C7C85;
   --bs-tertiary-color: #355A66;

    /* Présence (calendrier des six derniers mois) — trois lectures, trois
       teintes : journée travaillée, journée écourtée, journée non travaillée.
       La quatrième est la journée où personne n'était attendu. */
    --tc-attendance-present: #28A745;
    --tc-attendance-partial: #8FD3A8;
    --tc-attendance-absent: #EBEDF0;
    --tc-attendance-off: #F6F7F8;

    --tc-font-mono: 'JetBrains Mono', ui-monospace, monospace;

    /* --- Surcharge des variables Bootstrap --- */
   --bs-primary: #0E7A8A;
   --bs-primary-rgb: 14, 122, 138;
   --bs-body-bg: #F3F9F8;
   --bs-body-color: #16323C;
    --bs-body-font-family: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
   --bs-link-color: #0E7A8A;
   --bs-link-color-rgb: 14, 122, 138;
   --bs-link-hover-color: #0B6673;
   --bs-link-hover-color-rgb: 11, 102, 115;
   --bs-border-color: #D7E6EA;
    --bs-border-radius: .5rem;
    --bs-border-radius-lg: .75rem;
}

[data-bs-theme="dark"] {
   --tc-red-subtle: #123B49;
   --tc-red-border: #28596A;
   --tc-red-soft: rgba(72, 167, 179, .22);
   --tc-red-light: #8BC7D1;

    --tc-amber-bg: #3b2a12;
    --tc-amber-border: #664b1d;
    --tc-amber-ink: #f5c76a;
    --tc-green-bg: #122b1d;
    --tc-green-border: #235139;
    --tc-green-ink: #7fe2a7;
    --tc-info-bg: #16243c;
    --tc-info-border: #294a7a;
    --tc-info-ink: #6EA8FE;
    --tc-danger-bg: #3B1A1E;
    --tc-danger-border: #6B2B33;
    --tc-danger-ink: #F7A7B7;

   --tc-sidebar: #0E2E38;
   --tc-sidebar-border: #1B4855;
   --tc-sidebar-hover: #153D49;
   --tc-sidebar-muted: #D4EEF3;
   --tc-sidebar-section: #96C5CD;
   --tc-sidebar-faint: #7B898E;

   --tc-ink: #effafc;
   --tc-ink-2: #dfeff2;
   --tc-ink-3: #bfd7dd;
   --tc-ink-4: #9ab5be;
   --tc-border: #234B57;
   --tc-bg: #0C1F28;
    --tc-surface: #171e28;
    --tc-surface-soft: #1d2630;
    --tc-surface-alt: #101923;

    --bs-body-bg: #0d141a;
    --bs-body-color: #edf2f7;
    --bs-card-bg: #171e28;
    --bs-card-color: #edf2f7;
    --bs-secondary-color: #b8c3cf;
    --bs-tertiary-color: #dfe8f3;
    --bs-border-color: #2a3038;
}

body {
    background: var(--tc-bg);
    color: var(--tc-ink);
}

[data-bs-theme="dark"] .btn-tc-outline,
[data-bs-theme="dark"] .btn-tc-outline-danger,
[data-bs-theme="dark"] .quick-modal .modal-content,
[data-bs-theme="dark"] .card,
[data-bs-theme="dark"] .ccard,
[data-bs-theme="dark"] .kpi-card,
[data-bs-theme="dark"] .export-card,
[data-bs-theme="dark"] .app-topbar,
[data-bs-theme="dark"] .app-userchip,
[data-bs-theme="dark"] .app-menu,
[data-bs-theme="dark"] .app-menu__head,
[data-bs-theme="dark"] .app-subheader,
[data-bs-theme="dark"] .period-seg button,
[data-bs-theme="dark"] .date-filter,
[data-bs-theme="dark"] .date-filter input[type="date"],
[data-bs-theme="dark"] .ekpi,
[data-bs-theme="dark"] .ecard,
[data-bs-theme="dark"] .etally,
[data-bs-theme="dark"] .prof-accordion,
[data-bs-theme="dark"] .app-search,
[data-bs-theme="dark"] .quick-modal .form-control,
[data-bs-theme="dark"] .quick-modal .form-select,
[data-bs-theme="dark"] .ccard .form-control,
[data-bs-theme="dark"] .ccard .form-select,
[data-bs-theme="dark"] .app-menu__item,
[data-bs-theme="dark"] .app-space__icon,
[data-bs-theme="dark"] .prof-row__icon,
[data-bs-theme="dark"] .prof-value-box,
[data-bs-theme="dark"] .tc-input,
[data-bs-theme="dark"] .trigger-btn,
[data-bs-theme="dark"] .with-surface {
    background: var(--tc-surface);
    color: var(--tc-ink);
    border-color: var(--tc-border);
}

/* Accent : la marque employée comme couleur de TEXTE, par opposition aux fonds
   (`--tc-red`). --tc-accent-ink est la marque assombrie juste assez pour rester
   lisible sur une surface claire, et l'équivalent clair en thème sombre — la
   variante sombre n'a donc plus à être écrite, le jeton se redéfinit seul. */
.tc-accent { color: var(--tc-accent-ink); }
.tc-accent-bg { background: var(--tc-red); }
[data-bs-theme="dark"] .tc-accent-bg { background: var(--tc-red-light); }
[data-bs-theme="dark"] .tone-danger { color: var(--tc-danger-ink); }

[data-bs-theme="dark"] .app-menu__sep,
[data-bs-theme="dark"] .app-menu__head,
[data-bs-theme="dark"] .app-subheader,
[data-bs-theme="dark"] .app-topbar,
[data-bs-theme="dark"] .app-search,
[data-bs-theme="dark"] .date-filter,
[data-bs-theme="dark"] .date-filter input[type="date"],
[data-bs-theme="dark"] .app-userchip,
[data-bs-theme="dark"] .app-menu,
[data-bs-theme="dark"] .ccard,
[data-bs-theme="dark"] .card,
[data-bs-theme="dark"] .ekpi,
[data-bs-theme="dark"] .ecard,
[data-bs-theme="dark"] .etally,
[data-bs-theme="dark"] .prof-accordion {
    border-color: var(--tc-border);
}

[data-bs-theme="dark"] .app-menu__item:hover,
[data-bs-theme="dark"] .app-iconbtn:hover,
[data-bs-theme="dark"] .app-userchip:hover,
[data-bs-theme="dark"] .page-tab:hover,
[data-bs-theme="dark"] .period-seg button:hover,
[data-bs-theme="dark"] .btn-tc-outline:hover,
[data-bs-theme="dark"] .btn-tc-outline-danger:hover {
    background: var(--tc-surface-soft);
}

[data-bs-theme="dark"] .app-menu__item--danger:hover {
    background: var(--tc-danger-bg);
}

[data-bs-theme="dark"] .app-search input,
[data-bs-theme="dark"] .date-filter input[type="date"],
[data-bs-theme="dark"] .quick-modal .form-control,
[data-bs-theme="dark"] .quick-modal .form-select,
[data-bs-theme="dark"] .ccard .form-control,
[data-bs-theme="dark"] .ccard .form-select,
[data-bs-theme="dark"] .tc-input {
    background: var(--tc-surface-soft);
    color: var(--tc-ink);
}

[data-bs-theme="dark"] .app-search input::placeholder,
[data-bs-theme="dark"] .quick-modal .form-control::placeholder,
[data-bs-theme="dark"] .date-filter input[type="date"]::-webkit-calendar-picker-indicator {
    color: var(--tc-ink-3);
}

[data-bs-theme="dark"] .btn-tc-outline {
    background: var(--tc-surface);
    color: var(--tc-ink-2);
}

[data-bs-theme="dark"] .btn-tc-outline-danger {
    background: var(--tc-surface);
    color: var(--tc-danger-ink);
}

/* Le survol de la variante « rejet doux » garde sa teinte rouge en mode sombre :
   le sélecteur groupé ci-dessus lui donnait une surface neutre, et le bouton
   perdait son sens (« ceci va me faire perdre des données ») la moitié du
   temps. */
[data-bs-theme="dark"] .btn-tc-outline-danger:hover {
    background: var(--tc-danger-bg);
}

/* ── Espace employé : onglets de fiche, profil, évaluations ────────────────
   Compléments du mode sombre pour les classes partagées restées en clair.
   On surcharge uniquement en sombre : le rendu clair ne change pas.
   Le teal --tc-red reste la couleur des FONDS (bouton + texte blanc) ; pour le
   TEXTE accentué on passe à --tc-red-light, seul lisible sur fond sombre. */
[data-bs-theme="dark"] .tc-subtab.is-active {
    background: var(--tc-red-subtle);
    color: var(--tc-red-light);
    border-bottom-color: var(--tc-red-light);
}

[data-bs-theme="dark"] .prof-badge,
[data-bs-theme="dark"] .prof-row__icon--accent {
    background: var(--tc-red-subtle);
    color: var(--tc-red-light);
}

[data-bs-theme="dark"] .prof-avatar__dot { border-color: var(--tc-surface); }
[data-bs-theme="dark"] .prof-row { border-bottom-color: var(--tc-border); }
[data-bs-theme="dark"] .prof-chip { background: var(--tc-surface-soft); }
[data-bs-theme="dark"] .prof-accordion__body { border-top-color: var(--tc-border); }
[data-bs-theme="dark"] .prof-flag { background: var(--tc-surface-soft); color: var(--tc-ink-4); }
[data-bs-theme="dark"] .prof-chmod__octal { color: var(--tc-red-light); }
[data-bs-theme="dark"] .prof-btn-soft { background: var(--tc-red-subtle); color: var(--tc-red-light); }
[data-bs-theme="dark"] .prof-btn-soft:hover { background: var(--tc-red-soft); color: var(--tc-red-light); }
[data-bs-theme="dark"] .prof-btn-block:hover { background: var(--tc-red-hover); }
[data-bs-theme="dark"] .prof-missing { background: var(--tc-surface-soft); border-color: var(--tc-border); }
[data-bs-theme="dark"] .prof-missing__required { color: var(--tc-red-light); }
[data-bs-theme="dark"] .tc-input:disabled { background-color: var(--tc-surface); }

[data-bs-theme="dark"] .ekpi--done { background: var(--tc-green-bg); color: var(--tc-green-ink); }
[data-bs-theme="dark"] .ekpi--running { background: #241f3a; color: #b9a6f2; }
[data-bs-theme="dark"] .ekpi--waiting { background: var(--tc-amber-bg); color: var(--tc-amber-ink); }

[data-bs-theme="dark"] .ecard__head,
[data-bs-theme="dark"] .ecard__foot { border-color: var(--tc-border); }

/* .escore__gap n'a plus de variante sombre : les familles sémantiques se
   redéfinissent elles-mêmes dans le thème sombre, la surcharge faisait doublon. */
[data-bs-theme="dark"] .ecamp__progress span { background: var(--tc-red-light); }
[data-bs-theme="dark"] .elevel:has(input:checked) { border-color: var(--tc-red-light); }

[data-bs-theme="dark"] .ecard__alert,
[data-bs-theme="dark"] .ecamp__reason,
[data-bs-theme="dark"] .eresult__appreciation,
[data-bs-theme="dark"] .egrid-rubric__coef,
[data-bs-theme="dark"] .elevel.is-chosen .elevel__score,
[data-bs-theme="dark"] .elevel:has(input:checked) .elevel__score { color: var(--tc-red-light); }

/* ── Communication (registre du courrier + messagerie) ─────────────────────
   Écran partagé employé / Capital Humain : mêmes surcharges pour les deux. */
[data-bs-theme="dark"] .mail-kpi,
[data-bs-theme="dark"] .mail-seg,
[data-bs-theme="dark"] .mail-eye,
[data-bs-theme="dark"] .mail-sheet,
[data-bs-theme="dark"] .mail-card,
[data-bs-theme="dark"] .mail-input,
[data-bs-theme="dark"] .msg-shell,
[data-bs-theme="dark"] .msg-item,
[data-bs-theme="dark"] .msg-read__actions,
[data-bs-theme="dark"] .msg-bubble {
    background: var(--tc-surface);
    color: var(--tc-ink);
    border-color: var(--tc-border);
}

[data-bs-theme="dark"] .mail-input { border: 1px solid var(--tc-border); }
[data-bs-theme="dark"] .mail-row { border-bottom-color: var(--tc-border); }
[data-bs-theme="dark"] .mail-row--head { background: var(--tc-surface-soft); border-bottom-color: var(--tc-border); }
[data-bs-theme="dark"] .mail-card__bar,
[data-bs-theme="dark"] .mail-card__foot,
[data-bs-theme="dark"] .mail-sheet__grid,
[data-bs-theme="dark"] .mail-ack,
[data-bs-theme="dark"] .mail-flag,
[data-bs-theme="dark"] .msg-rail,
[data-bs-theme="dark"] .msg-list,
[data-bs-theme="dark"] .msg-list__head,
[data-bs-theme="dark"] .msg-list__search,
[data-bs-theme="dark"] .msg-receipts,
[data-bs-theme="dark"] .msg-read__head { border-color: var(--tc-border); }

[data-bs-theme="dark"] .mail-flag { background: var(--tc-surface-soft); }
[data-bs-theme="dark"] .mail-drop { border-color: var(--tc-border); }
[data-bs-theme="dark"] .mail-seg.is-active { color: var(--tc-red-light); border-color: var(--tc-red-border); }
[data-bs-theme="dark"] .mail-eye:hover { border-color: var(--tc-red-border); }

[data-bs-theme="dark"] .mail-type--inbound { color: var(--tc-green-ink); background: var(--tc-green-bg); }
[data-bs-theme="dark"] .mail-type--outbound { color: var(--tc-info-ink); background: var(--tc-info-bg); }
[data-bs-theme="dark"] .mail-type--internal { color: var(--tc-amber-ink); background: var(--tc-amber-bg); }

[data-bs-theme="dark"] .mail-row a.mail-row__chrono:hover,
[data-bs-theme="dark"] .mail-back:hover,
[data-bs-theme="dark"] .mail-row__clip:hover,
[data-bs-theme="dark"] .mail-modal__chrono-value,
[data-bs-theme="dark"] .msg-folder.is-active,
[data-bs-theme="dark"] .msg-folder__count,
[data-bs-theme="dark"] .msg-drop:hover,
[data-bs-theme="dark"] .msg-receipt.is-read { color: var(--tc-red-light); }

[data-bs-theme="dark"] .msg-switch { background: var(--tc-border); }
[data-bs-theme="dark"] .msg-item.is-read { background: var(--tc-surface-soft); }
[data-bs-theme="dark"] .msg-item:hover { background: var(--tc-surface-alt); }
[data-bs-theme="dark"] .msg-item__avatar,
[data-bs-theme="dark"] .msg-read__avatar { background: var(--tc-red); color: var(--tc-on-primary); }
[data-bs-theme="dark"] .msg-star { color: var(--tc-ink-4); }
[data-bs-theme="dark"] .msg-read__body,
[data-bs-theme="dark"] .msg-bubble__body { color: var(--tc-ink-2); }
[data-bs-theme="dark"] .pager__link { background: var(--tc-surface); border-color: var(--tc-border); }

/* Rayon des boutons aligné sur le design (7–8px, au lieu de 6/4px Bootstrap) */
.btn { --bs-btn-border-radius: 8px; }
.btn-sm { --bs-btn-border-radius: 7px; }

/* Boutons de marque (fond plein / contour) */
.btn-tc, .btn-tc-outline, .btn-tc-outline-danger, .btn-tc-danger { display: inline-flex; align-items: center; gap: 7px; font-weight: 600; font-size: 12.5px; border-radius: 8px; cursor: pointer; transition: background .12s, border-color .12s, color .12s, box-shadow .12s, transform .12s; text-decoration: none; }
/* Un libellé de bouton ne se coupe jamais en plein milieu : sur une rangée
   étroite, mieux vaut que le bouton passe à la ligne entière — le conteneur
   porte `flex-wrap` — qu'un mot coupé en deux, illisible. */
.btn-tc, .btn-tc-outline, .btn-tc-outline-danger, .btn-tc-danger { white-space: nowrap; }
/* L'encre posée sur la couleur de marque est CALCULÉE (`--tc-on-primary`), pas
   blanche par défaut : sur une charte jaune, du blanc sur le jaune donne un
   contraste de 1,4 — le libellé du bouton disparaît. Voir BrandPalette. */
.btn-tc { padding: 9px 16px; color: var(--tc-on-primary); background: var(--tc-red); border: none; }
.btn-tc:hover { background: var(--tc-red-hover); color: var(--tc-on-primary); }
.btn-tc-outline { padding: 9px 15px; color: var(--tc-ink-2); background: #fff; border: 1px solid #DEE2E6; }
.btn-tc-outline:hover { background: var(--tc-bg); color: var(--tc-ink-2); }
/* Variante "rejet doux" (ex. Rejeter) : contour rouge, remplissage pâle au
   survol, sans inversion de couleur. Rouge SÉMANTIQUE (--tc-danger-*), donc
   indépendant de la charte : ce bouton dit « je rejette », pas « ma marque ». */
.btn-tc-outline-danger { padding: 9px 15px; color: var(--tc-danger-ink); background: #fff; border: 1px solid var(--tc-danger-border); }
.btn-tc-outline-danger:hover { background: var(--tc-danger-bg); color: var(--tc-danger-ink); }
/* Action destructive : au repos le danger reste discret, puis se renforce au
   survol. */
.btn-tc-danger { padding: 9px 15px; color: var(--tc-danger-ink); background: #fff; border: 1px solid var(--tc-danger-border); box-shadow: 0 1px 2px rgba(22, 50, 60, .05); }
.btn-tc-danger:hover:not(:disabled) { color: #fff; background: var(--tc-danger-ink); border-color: var(--tc-danger-ink); box-shadow: 0 4px 10px rgba(192, 57, 43, .2); transform: translateY(-1px); }
.btn-tc-danger:focus-visible { outline: 3px solid var(--tc-danger-border); outline-offset: 2px; }
.btn-tc-danger:disabled, .btn-tc-danger[disabled] { opacity: .5; cursor: not-allowed; box-shadow: none; }
.btn-tc-danger svg { width: 15px; height: 15px; flex: 0 0 auto; }

/* Actions compactes du référentiel bancaire. */
.bank-actions { display: inline-flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 6px; }
.bank-actions form { margin: 0; }
.bank-action.btn-tc-outline,
.bank-action.btn-tc-outline-danger { min-height: 32px; padding: 6px 10px; border-radius: 7px; font-size: 11.5px; line-height: 1; gap: 6px; }
.bank-action svg { width: 14px; height: 14px; flex: 0 0 auto; }
.bank-action:focus-visible { outline: 3px solid var(--tc-red-border); outline-offset: 2px; }

/* Boutons primaires aux couleurs de l'entreprise */
.btn-primary {
    --bs-btn-bg: var(--tc-red);
    --bs-btn-border-color: var(--tc-red);
    --bs-btn-hover-bg: var(--tc-red-hover);
    --bs-btn-hover-border-color: var(--tc-red-hover);
    --bs-btn-active-bg: var(--tc-red-active);
    --bs-btn-active-border-color: var(--tc-red-active);
    --bs-btn-disabled-bg: var(--tc-red);
    --bs-btn-disabled-border-color: var(--tc-red);
    /* Les quatre `--bs-btn-*-color` manquaient : Bootstrap gardait donc SON
       blanc sur tous les états (repos, survol, actif, désactivé) alors que le
       fond, lui, suivait la charte. Sur une charte claire, tous les boutons
       primaires de l'application affichaient du blanc sur jaune. */
    --bs-btn-color: var(--tc-on-primary);
    --bs-btn-hover-color: var(--tc-on-primary);
    --bs-btn-active-color: var(--tc-on-primary);
    --bs-btn-disabled-color: var(--tc-on-primary);
    /* L'anneau de focus suivait la charte cramoisie d'origine (220, 20, 60) et
       restait rouge quel que soit le réglage. Bootstrap le compose en
       `rgba(var(--bs-btn-focus-shadow-rgb), .5)` : le triplet de la charte
       courante convient, même format. */
    --bs-btn-focus-shadow-rgb: var(--bs-primary-rgb);
}

/* Cartes thémées (padding 20px, radius 12px, bord #E9ECEF — comme le prototype) */
.card {
    --bs-card-border-color: var(--tc-border);
    --bs-card-border-radius: .75rem;
    --bs-card-cap-bg: transparent;
    --bs-card-spacer-x: 1.25rem;
    --bs-card-spacer-y: 1.25rem;
    --bs-card-bg: #fff;
}

/* Bootstrap fait hériter les cellules de --bs-body-bg (gris) : on remet
   un fond transparent pour laisser voir le blanc de la carte. */
.table { --bs-table-bg: transparent; }

/* Sections numérotées de la modale de création rapide */
/* ---- Modale de création rapide d'un employé ---- */
.quick-modal .modal-dialog { max-width: 680px; }
.quick-modal .modal-content { background: #fff; border: none; border-radius: 16px; box-shadow: 0 24px 60px rgba(16, 20, 26, .22); max-height: calc(100vh - 2rem); }
.quick-modal .modal-header { align-items: center; gap: 13px; padding: 20px 24px 14px; border-bottom: 1px solid var(--tc-border); }
.quick-modal .modal-header .btn-close { margin: 0 0 0 auto; }
.quick-modal__icon { width: 40px; height: 40px; border-radius: 11px; background: var(--tc-red-subtle); color: var(--tc-accent-ink); display: inline-flex; align-items: center; justify-content: center; flex: none; }
.quick-modal__icon--danger { background: var(--tc-danger-bg); color: var(--tc-danger-ink); }
.quick-modal .modal-title { font-size: 16px; color: var(--tc-ink); }
.quick-modal__subtitle { font-size: 12.5px; color: var(--tc-ink-3); margin-top: 2px; }
.quick-modal .modal-body { padding: 20px 24px; max-height: calc(100vh - 170px); overflow-y: auto; }
.quick-modal .modal-footer { border-top: 1px solid var(--tc-border); padding: 14px 24px; gap: 8px; }

/* Récapitulatif d'émission en lot : une ligne par salarié retenu, ses
   particularités de paie, et le lien vers sa fiche. */
.bulk-recap-row { padding: 12px 0; border-bottom: 1px solid var(--tc-border); }
.bulk-recap-row:last-child { border-bottom: none; padding-bottom: 0; }
.bulk-recap-row:first-child { padding-top: 0; }
.bulk-recap-flags { list-style: none; padding-left: 42px; margin: 0; }
.bulk-recap-flags li { position: relative; font-size: 12px; color: var(--tc-ink-3); padding-left: 16px; margin-bottom: 3px; }
.bulk-recap-flags li::before { content: ''; position: absolute; left: 0; top: 6px; width: 6px; height: 6px; border-radius: 50%; background: var(--tc-amber, #E8A317); }

/* Aperçu du bulletin : en-tête et pied classiques, corps entièrement occupé par
   le document. La hauteur est fixée car un cadre PDF en hauteur automatique se
   replierait à zéro ; le corps prend ensuite la place restante entre l'en-tête
   et le pied. Sur mobile, la modale passe en plein écran
   (modal-fullscreen-md-down) et rend la main sur la hauteur et les angles. */
.payslip-preview .modal-dialog { max-width: 900px; }
.payslip-preview .modal-content { height: 86vh; }
.payslip-preview .modal-body { padding: 0; background: #525659; overflow: hidden; flex: 1 1 auto; min-height: 0; }
@media (max-width: 767.98px) {
    .payslip-preview .modal-dialog { max-width: none; }
    .payslip-preview .modal-content { height: 100%; border-radius: 0; }
}

/* Filtres de période de l'espace employé (« Mes bulletins de paie »). Le rendu
   natif des selects varie d'un navigateur à l'autre et jurerait à côté des
   champs plats du reste de l'application : on le neutralise et on redessine le
   chevron. */
.payslip-select {
    width: 100%;
    padding: 11px 38px 11px 12px;
    font: 500 13.5px Inter, sans-serif;
    color: var(--tc-ink);
    background-color: var(--tc-surface);
    border: 1px solid var(--tc-border);
    border-radius: 9px;
    outline: none;
    box-sizing: border-box;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    color-scheme: light;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23355A66' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 16px 16px;
}
.payslip-select:focus { border-color: var(--tc-red); }
[data-bs-theme="dark"] .payslip-select {
    color-scheme: dark;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23DFEFF2' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
}
.payslip-select option { color: var(--tc-ink); background-color: var(--tc-surface); }

/* Mode de règlement : trois pastilles côte à côte, sur le modèle des cartes de
   choix du reste de l'application. */
.cpay-modes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.cpay-mode { display: flex; align-items: center; gap: 7px; padding: 9px 10px; border: 1px solid #CED4DA; border-radius: 9px; cursor: pointer; margin: 0; font-weight: 600; font-size: 12px; color: var(--tc-ink-2); transition: border-color .12s, background .12s; }
.cpay-mode:hover { border-color: var(--tc-ink-4); }
.cpay-mode:has(.form-check-input:checked) { border: 1.5px solid var(--tc-red); background: var(--tc-red-subtle); color: var(--tc-ink); }
.cpay-mode .form-check-input { margin: 0; flex: none; }
.cpay-mode .form-check-input:checked { background-color: var(--tc-red); border-color: var(--tc-red); }
@media (max-width: 991.98px) { .cpay-modes { grid-template-columns: 1fr; } }

.quick-section { display: flex; align-items: center; gap: 9px; margin-bottom: 14px; }
.quick-section__num { width: 22px; height: 22px; border-radius: 50%; background: var(--tc-red); color: var(--tc-on-primary); display: inline-flex; align-items: center; justify-content: center; font: 700 12px/1 var(--tc-font-sans, Inter); flex: none; }
.quick-section__title { font-weight: 700; font-size: 13.5px; color: var(--tc-ink); }

/* Libellés compacts + astérisque rouge sur les champs requis. */
.quick-modal .form-label,
.quick-modal legend { font-weight: 600; font-size: 12.5px; color: var(--tc-ink-2); margin-bottom: 5px; padding: 0; float: none; width: auto; }
.quick-modal .form-label.required::after,
.quick-modal legend.required::after { content: ' *'; color: var(--tc-accent-ink); font-weight: 700; }
.quick-modal .form-control,
.quick-modal .form-select { font-size: 13.5px; color: var(--tc-ink); border: 1px solid #CED4DA; border-radius: 9px; padding: 9px 12px; }
.quick-modal .form-control::placeholder { color: var(--tc-ink-4); }
.quick-modal .form-control:focus,
.quick-modal .form-select:focus { border-color: var(--tc-red-light); box-shadow: 0 0 0 3px var(--tc-red-soft); }

/* Sexe : deux pastilles côte à côte (au lieu de radios empilés). */
.quick-sexe > div { display: flex; gap: 10px; }
.quick-sexe .form-check { flex: 1; min-height: 0; margin: 0; padding: 10px 12px; border: 1px solid var(--tc-border); border-radius: 9px; display: flex; align-items: center; gap: 8px; cursor: pointer; }
.quick-sexe .form-check:has(.form-check-input:checked) { border: 1.5px solid var(--tc-red); background: var(--tc-red-subtle); }
.quick-sexe .form-check-input { float: none; margin: 0; }
.quick-sexe .form-check-input:checked { background-color: var(--tc-red); border-color: var(--tc-red); }
.quick-sexe .form-check-label { font-size: 13px; color: var(--tc-ink); cursor: pointer; }

/* État de succès (employé créé, contrat à rattacher). */
.quick-success { text-align: center; padding: 34px 28px 30px; }
.quick-success__icon { width: 66px; height: 66px; border-radius: 50%; background: var(--tc-green-bg); color: var(--tc-green-ink); display: inline-flex; align-items: center; justify-content: center; margin-bottom: 18px; }
.quick-success__title { font-size: 18px; font-weight: 700; color: var(--tc-ink); margin: 0 0 8px; }
.quick-success__text { font-size: 13.5px; line-height: 1.5; color: var(--tc-ink-3); margin: 0 auto 18px; max-width: 430px; }
.quick-success__text strong { color: var(--tc-ink-2); font-weight: 700; }
.quick-success__badge { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 600; color: var(--tc-amber-ink); background: var(--tc-amber-bg); border-radius: 999px; padding: 6px 14px; margin-bottom: 24px; }
.quick-success__actions { display: flex; justify-content: center; gap: 10px; }

/* ===== Page « Rattacher un contrat » ===== */
.cbreadcrumb { display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 600; }
.cbreadcrumb a { color: var(--tc-ink-3); text-decoration: none; }
.cbreadcrumb a:hover { color: var(--tc-ink-2); }
.cbreadcrumb span[aria-hidden] { color: var(--tc-ink-4); }
.cbreadcrumb__current { color: var(--tc-accent-ink); }
.cpage-title { font-size: 24px; font-weight: 700; letter-spacing: -.02em; color: var(--tc-ink); margin: 0 0 4px; }
.cpage-subtitle { font-size: 13.5px; color: var(--tc-ink-3); margin: 0; }
.cpage-subtitle strong { color: var(--tc-ink-2); font-weight: 600; }

.contract-grid { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 20px; align-items: start; }
.contract-grid > :first-child { min-width: 0; }
@media (max-width: 1199px) { .contract-grid { grid-template-columns: minmax(0, 1fr) 280px; } }
@media (max-width: 992px) { .contract-grid { grid-template-columns: 1fr; } }

.ccard { background: #fff; border: 1px solid var(--tc-border); border-radius: 14px; padding: 22px 24px; box-shadow: 0 1px 3px rgba(0,0,0,0.04); }
.ccard__title { font-size: 15.5px; font-weight: 700; color: var(--tc-ink); margin: 0 0 4px; }
.ccard__hint { font-size: 12.5px; color: var(--tc-ink-3); margin: 0 0 16px; }
.ccard__head-icon { display: flex; align-items: flex-start; gap: 11px; margin-bottom: 16px; }
.ccard__head-icon > svg { width: 32px; height: 32px; padding: 7px; border-radius: 9px; background: var(--tc-red-subtle); color: var(--tc-accent-ink); flex: none; }

/* Étapes du formulaire */
.cstep { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 20px; }
.cstep__num { width: 32px; height: 32px; border-radius: 50%; background: var(--tc-red); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 14px; flex: none; }

/* Grille des types de contrat */
.ctype-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 12px; }
.ctype-card { position: relative; cursor: pointer; padding: 0; border: 2px solid var(--tc-border); border-radius: 12px; background: #fff; transition: all 0.2s ease; overflow: hidden; }
.ctype-card:hover { border-color: var(--tc-red-light); box-shadow: 0 4px 12px rgba(220, 53, 69, 0.1); transform: translateY(-2px); }
/* L'état « sélectionné » se déduit du radio coché, jamais d'une classe posée par
   du JavaScript. Le radio est `opacity: 0` : sans ce `:has()`, une carte cochée
   gardait la bordure grise, et les champs qui se remplissaient au passage
   donnaient l'impression que le clic n'avait pas pris (Retenues & gains). Le
   states.display: flex de `.ctype-card__body` fait que le texte ne colle plus au
   bord, et la pastille de sélection se pose dessus grâce au z-index. */
.ctype-card:has(input:checked) { border-color: var(--tc-red); background: linear-gradient(135deg, var(--tc-red-subtle) 0%, #fff 100%); }
.ctype-card:has(input:checked) .ctype-card__label { color: var(--tc-accent-ink); }
.ctype-card:has(input:checked)::before {
    content: '';
    position: absolute;
    top: 12px;
    right: 12px;
    width: 20px;
    height: 20px;
    background: var(--tc-red);
    border: 2px solid var(--tc-red);
    border-radius: 50%;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
    background-size: 12px;
    background-position: center;
    background-repeat: no-repeat;
    z-index: 1;
}
.ctype-card input { position: absolute; opacity: 0; }
.ctype-card__body { display: flex; flex-direction: column; gap: 6px; padding: 16px 18px; transition: all 0.2s ease; position: relative; }
.ctype-card__header { display: flex; align-items: center; gap: 10px; }
.ctype-card__label { font-weight: 700; font-size: 14px; color: var(--tc-ink); }
.ctype-card__desc { font-size: 12.5px; color: var(--tc-ink-3); line-height: 1.4; }
/* Clavier : le radio est invisible (`opacity: 0`), le focus doit donc être rendu
   par la carte — sans quoi on ne sait plus où l'on se trouve au tabulage. */
.ctype-card:focus-within { outline: 2px solid var(--tc-red); outline-offset: 2px; }

/* Indicateur de sélection (non sélectionné) */
.ctype-card::after {
    content: '';
    position: absolute;
    top: 12px;
    right: 12px;
    width: 20px;
    height: 20px;
    border: 2px solid var(--tc-border);
    border-radius: 50%;
    transition: all 0.2s ease;
    z-index: 0;
}
.ctype-card:has(input:checked)::after {
    display: none;
}

/* Champs de formulaire */
.cfield { margin-bottom: 8px; }
.cfield .form-label { font-weight: 600; font-size: 12.5px; color: var(--tc-ink-2); margin-bottom: 5px; display: block; }
.cfield .form-label.required::after { content: ' *'; color: var(--tc-accent-ink); font-weight: 700; }
.cfield .form-control, .cfield .form-select { font-size: 13.5px; color: var(--tc-ink); border: 1px solid #CED4DA; border-radius: 9px; padding: 10px 13px; transition: all 0.2s ease; }
.cfield .form-control:focus, .cfield .form-select:focus { border-color: var(--tc-red-light); box-shadow: 0 0 0 3px var(--tc-red-soft); }
.cfield .form-text { font-size: 11.5px; color: var(--tc-ink-3); margin-top: 5px; }
.cfield.is-disabled { opacity: .5; }

/* Montant monétaire */
.cmoney { position: relative; display: flex; align-items: stretch; }
.cmoney input { border-top-right-radius: 0; border-bottom-right-radius: 0; padding-right: 55px; }
.cmoney__unit { position: absolute; right: 1px; top: 1px; bottom: 1px; padding: 0 14px; background: linear-gradient(135deg, var(--tc-bg) 0%, #f8f9fa 100%); border: 1px solid #CED4DA; border-left: none; border-radius: 0 9px 9px 0; display: flex; align-items: center; font-size: 12px; font-weight: 600; color: var(--tc-ink-2); pointer-events: none; }

/* Période d'essai */
.ctrial { margin-top: 20px; padding: 20px; background: linear-gradient(135deg, var(--tc-bg) 0%, #f8f9fa 100%); border-radius: 12px; border: 1px solid var(--tc-border-soft, #F1F3F5); }
.ctrial__toggle { display: flex; align-items: center; gap: 12px; cursor: pointer; padding: 4px; }
.ctrial__toggle input[type="checkbox"] { width: 22px; height: 22px; cursor: pointer; accent-color: var(--tc-red); }
.ctrial__title { font-weight: 700; font-size: 13px; color: var(--tc-ink); }
.ctrial__law { font-size: 11.5px; color: var(--tc-ink-3); margin-left: auto; background: var(--tc-amber-bg); padding: 4px 8px; border-radius: 6px; }
.ctrial__panel { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--tc-border-soft, #F1F3F5); }
.ctrial__panel .cfield { margin-bottom: 12px; }
.ctrial__end { display: flex; align-items: baseline; gap: 6px; padding-bottom: 9px; font-size: 12.5px; color: var(--tc-ink-3); }
.ctrial__end strong { font-size: 13.5px; color: var(--tc-ink); }
.ctrial__notice { display: flex; align-items: flex-start; gap: 8px; margin-top: 13px; padding: 12px 14px; background: var(--tc-amber-bg); border: 1px solid var(--tc-amber-border); border-radius: 10px; font-size: 12px; line-height: 1.45; color: var(--tc-amber-ink); }
.ctrial__notice svg { flex: none; margin-top: 1px; }

/* Note légale */
.clegal-note { display: flex; align-items: flex-start; gap: 8px; margin-top: 16px; padding: 12px 14px; background: var(--tc-amber-bg); border: 1px solid var(--tc-amber-border); border-radius: 10px; font-size: 12px; line-height: 1.45; color: var(--tc-amber-ink); }
.clegal-note svg { flex: none; margin-top: 1px; }

/* Pièces jointes au contrat (collection répétable). */
.cdoc-row { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.2fr) minmax(0, 1fr) auto; gap: 10px; align-items: end; padding: 12px 0; border-top: 1px solid var(--tc-border-soft, #F1F3F5); }
.cdoc-row:first-child { border-top: none; padding-top: 0; }
.cdoc-row .form-label { font-weight: 600; font-size: 11.5px; color: var(--tc-ink-3); margin-bottom: 4px; }
.cdoc-row .form-control, .cdoc-row .form-select { font-size: 13px; border: 1px solid var(--tc-border); border-radius: 9px; padding: 8px 11px; transition: all 0.2s ease; }
.cdoc-row .form-control:focus, .cdoc-row .form-select:focus { border-color: var(--tc-red-light); box-shadow: 0 0 0 3px var(--tc-red-soft); }
.cdoc-row__remove { border: 1px solid var(--tc-border); background: var(--tc-surface); color: var(--tc-ink-3); border-radius: 9px; padding: 8px 13px; font-size: 12.5px; font-weight: 600; cursor: pointer; transition: all 0.2s ease; }
.cdoc-row__remove:hover { border-color: var(--tc-red); color: var(--tc-accent-ink); background: var(--tc-red-subtle); }
.cdoc-chip { display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; border: 1px solid var(--tc-border); border-radius: 999px; background: var(--tc-bg); color: var(--tc-ink-2); font-size: 11.5px; font-weight: 600; text-decoration: none; transition: all 0.2s ease; }
.cdoc-chip:hover { border-color: var(--tc-red); color: var(--tc-accent-ink); }
.cdoc-empty { font-size: 12.5px; color: var(--tc-ink-4); margin: 0 0 12px; padding: 16px; text-align: center; background: var(--tc-bg); border-radius: 10px; border: 1px dashed var(--tc-border); }
.cdoc-add { margin-top: 12px; border: 1px dashed #CED4DA; background: linear-gradient(135deg, #fff 0%, var(--tc-bg) 100%); color: var(--tc-ink-2); border-radius: 10px; padding: 12px 18px; font-size: 12.5px; font-weight: 600; cursor: pointer; transition: all 0.2s ease; width: 100%; }
.cdoc-add:hover { border-color: var(--tc-red); color: var(--tc-accent-ink); background: var(--tc-red-subtle); transform: translateY(-1px); }

/* Pièces jointes d'un contrat : une carte par pièce, sur la page de détail. */
.cdoc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 12px; }
.cdoc-card { display: flex; gap: 12px; padding: 14px; border: 1px solid var(--tc-border); border-radius: 12px; background: var(--tc-surface); color: var(--tc-ink-2); text-decoration: none; transition: all 0.2s ease; }
.cdoc-card:hover { border-color: var(--tc-red); box-shadow: 0 4px 14px rgba(0, 0, 0, 0.06); transform: translateY(-1px); }
.cdoc-card__icon { display: inline-flex; align-items: center; justify-content: center; width: 38px; height: 38px; flex-shrink: 0; border-radius: 10px; background: var(--tc-red-subtle); color: var(--tc-accent-ink); }
.cdoc-card__body { display: flex; flex-direction: column; gap: 5px; min-width: 0; flex: 1; }
.cdoc-card__head { display: flex; flex-direction: column; gap: 2px; }
.cdoc-card__type { font-size: 13px; font-weight: 700; color: var(--tc-ink); }
.cdoc-card__label { font-size: 12px; color: var(--tc-ink-2); overflow-wrap: anywhere; }
.cdoc-card__file { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; color: var(--tc-ink-3); overflow-wrap: anywhere; }
.cdoc-card__file svg { flex-shrink: 0; }
.cdoc-card__meta { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 11px; color: var(--tc-ink-4); }

/* En-têtes de sous-sections dans une carte de contrat (pièces, avenants…). */
.camend-head { display: flex; align-items: center; gap: 8px; margin: 22px 0 14px; padding-bottom: 8px; border-bottom: 1px solid var(--tc-border-soft, #F1F3F5); }
.camend-head__label { font: 600 10px/1 var(--tc-font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--tc-ink-4); }
.camend-head__count { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 6px; border-radius: 999px; background: var(--tc-red-subtle); color: var(--tc-accent-ink); font-size: 11px; font-weight: 700; }

/* Frise verticale des avenants et du journal. */
.ctimeline { list-style: none; margin: 0; padding: 0; position: relative; }
.ctimeline__item { position: relative; display: flex; gap: 14px; padding: 0 0 18px; }
.ctimeline__item:last-child { padding-bottom: 0; }
.ctimeline__item::before { content: ''; position: absolute; left: 6px; top: 18px; bottom: -2px; width: 2px; background: var(--tc-border-soft, #F1F3F5); }
.ctimeline__item:last-child::before { display: none; }
.ctimeline__dot { position: relative; z-index: 1; flex: none; width: 14px; height: 14px; margin-top: 2px; border-radius: 50%; background: var(--tc-ink-4); box-shadow: 0 0 0 4px var(--tc-surface); }
.ctimeline__dot--icon { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; margin-top: 0; margin-left: -2px; color: #fff; }
.ctimeline__dot.tone-success { background: #1E7E34; }
.ctimeline__dot.tone-info { background: #0B5ED7; }
.ctimeline__dot.tone-warn { background: var(--tc-amber-ink, #B7791F); }
.ctimeline__dot.tone-danger { background: var(--tc-red); }
.ctimeline__body { flex: 1; min-width: 0; background: var(--tc-bg); border: 1px solid var(--tc-border-soft, #F1F3F5); border-radius: 11px; padding: 11px 14px; }
.ctimeline__header { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ctimeline__title { font-size: 13px; font-weight: 600; color: var(--tc-ink); }
.ctimeline__date { font-size: 12px; color: var(--tc-ink-3); }
.ctimeline__variation { margin-left: auto; font-size: 13px; font-weight: 700; }
.ctimeline__variation.is-up { color: #1E7E34; }
.ctimeline__variation.is-down { color: var(--tc-red); }
.ctimeline__variation.is-flat { color: var(--tc-ink-3); }
.ctimeline__meta { margin-top: 6px; font-size: 11.5px; color: var(--tc-ink-4); }
.ctimeline__reason { margin: 8px 0 0; padding: 0 0 0 12px; border-left: 3px solid var(--tc-red-subtle); font-size: 12.5px; font-style: italic; color: var(--tc-ink-2); }
.ctimeline__fields { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.ctimeline__field { display: inline-flex; align-items: center; gap: 6px; padding: 4px 9px; border-radius: 8px; background: var(--tc-surface); border: 1px solid var(--tc-border-soft, #F1F3F5); font-size: 11.5px; }
.ctimeline__field-name { color: var(--tc-ink-3); }
.ctimeline__value { font-weight: 600; color: var(--tc-ink); }

/* Avant → après d'un avenant. */
.camend-diff { display: inline-flex; align-items: center; gap: 8px; margin-top: 8px; font-size: 13px; font-variant-numeric: tabular-nums; }
.camend-diff svg { color: var(--tc-ink-4); }
.camend-diff__from { color: var(--tc-ink-3); text-decoration: line-through; text-decoration-color: var(--tc-ink-4); }
.camend-diff__to { font-weight: 700; color: var(--tc-accent-ink); }

/* Panneau d'actions d'un contrat : chaque bouton respire et occupe la largeur. */
.cactions { display: flex; flex-direction: column; gap: 10px; }
.cactions > * { width: 100%; }
.cactions > form { margin: 0; }
.cactions .btn-tc,
.cactions .btn-tc-outline,
.cactions .btn-tc-outline-danger,
.cactions .btn-tc-danger,
.cactions .btn { justify-content: center; width: 100%; padding-top: 9px; padding-bottom: 9px; }

/* Enveloppe d'un bouton désactivé portant une infobulle.
   Un `<button disabled>` ne reçoit plus aucun événement souris : l'infobulle ne
   s'afficherait jamais. Le déclencheur est donc posé sur cette enveloppe, qui
   reste, elle, survolable. */
.ctooltip-wrap { display: inline-block; cursor: help; }
.cactions .ctooltip-wrap { display: block; width: 100%; }
.ctooltip-wrap > button { width: 100%; }

/* Infobulles : fond encre, texte clair, coins arrondis et ombre douce.
   On surcharge Bootstrap (qui les fait noir uni) pour rester dans la charte ;
   la largeur est bornée pour qu'un motif de refus long reste lisible. */
.tooltip { --bs-tooltip-max-width: 280px; --bs-tooltip-font-size: 11.5px; }
.tooltip .tooltip-inner { background: var(--tc-ink); color: #fff; padding: 7px 11px; border-radius: 9px; line-height: 1.45; text-align: left; box-shadow: 0 6px 20px rgba(22, 50, 60, 0.22); }
.tooltip.bs-tooltip-top .tooltip-arrow::before { border-top-color: var(--tc-ink); }
.tooltip.bs-tooltip-bottom .tooltip-arrow::before { border-bottom-color: var(--tc-ink); }
.tooltip.bs-tooltip-start .tooltip-arrow::before { border-left-color: var(--tc-ink); }
.tooltip.bs-tooltip-end .tooltip-arrow::before { border-right-color: var(--tc-ink); }

@media (max-width: 767.98px) {
    .cdoc-row { grid-template-columns: 1fr; align-items: stretch; }
}

/* Encart DGT (amber). */
.cdgt { margin-top: 16px; padding: 16px 18px; background: var(--tc-amber-bg); border: 1px solid var(--tc-amber-border); border-radius: 12px; }
.cdgt__head { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 12.5px; color: var(--tc-amber-ink); margin-bottom: 10px; }
.cdgt__note { font-size: 11.5px; line-height: 1.45; color: var(--tc-amber-ink); margin: 8px 0 0; }

/* Boutons d'action du formulaire */
.btn-tc { background: var(--tc-red); color: #fff; border: none; border-radius: 9px; padding: 10px 20px; font-weight: 600; font-size: 13.5px; transition: all 0.2s ease; }
.btn-tc:hover { background: var(--tc-accent-ink); transform: translateY(-1px); box-shadow: 0 4px 12px rgba(220, 53, 69, 0.3); }
.btn-tc-outline { background: transparent; color: var(--tc-ink-2); border: 1px solid var(--tc-border); border-radius: 9px; padding: 10px 20px; font-weight: 600; font-size: 13.5px; transition: all 0.2s ease; }
.btn-tc-outline:hover { border-color: var(--tc-red); color: var(--tc-accent-ink); background: var(--tc-red-subtle); }

/* Champs (labels compacts + focus rouge, cohérent avec la modale). */
.ccard .form-label { font-weight: 600; font-size: 12.5px; color: var(--tc-ink-2); margin-bottom: 5px; }
.ccard .form-label.required::after { content: ' *'; color: var(--tc-accent-ink); font-weight: 700; }
.ccard .form-control, .ccard .form-select { font-size: 13.5px; color: var(--tc-ink); border: 1px solid #CED4DA; border-radius: 9px; padding: 9px 12px; }
.ccard .form-control:focus, .ccard .form-select:focus { border-color: var(--tc-red-light); box-shadow: 0 0 0 3px var(--tc-red-soft); }
.ccard .form-text { font-size: 11.5px; color: var(--tc-ink-3); }

/* Form fields in contract grid - responsive columns. */
@media (max-width: 767px) {
    .contract-grid .row.g-3 > [class*="col-"] { flex: 0 0 100%; max-width: 100%; }
}

/* Terme calculé : la date de fin d'un contrat à durée conventionnée se lit,
   elle ne se saisit pas. */
.cfield input.is-computed { background: var(--tc-bg); color: var(--tc-ink-2); font-weight: 600; cursor: default; }
.cfield__computed { display: flex; align-items: center; gap: 5px; margin-top: 6px; font-size: 11.5px; font-weight: 600; color: #1E7E34; }

/* Récapitulatif (colonne de droite). */
.crecap { position: sticky; top: 76px; }
.crecap .ccard { box-shadow: 0 2px 8px rgba(0,0,0,0.06); }
.crecap__person { display: flex; align-items: center; gap: 12px; padding-bottom: 18px; margin-bottom: 8px; border-bottom: 1px solid var(--tc-border-soft, #F1F3F5); }
.crecap__avatar { width: 42px; height: 42px; border-radius: 50%; background: linear-gradient(135deg, var(--tc-sidebar) 0%, var(--tc-accent-ink) 100%); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-weight: 700; font-size: 14px; flex: none; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
.crecap__name { font-weight: 700; font-size: 14px; color: var(--tc-ink); }
.crecap__role { font-size: 12px; color: var(--tc-ink-3); margin-top: 2px; }
.crecap__list { margin: 16px 0 0; }
.crecap__row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 0; width: 100%; border-bottom: 1px solid var(--tc-border-soft, #F1F3F5); }
.crecap__row:last-child { border-bottom: none; }
.crecap__list dt,
.crecap__row dt { font-size: 12.5px; color: var(--tc-ink-3); font-weight: 500; margin: 0; flex: 0 0 160px; }
.crecap__list dd,
.crecap__row dd { font-size: 12.5px; color: var(--tc-ink); font-weight: 600; margin: 0; text-align: right; flex: 1 1 auto; }
.crecap__list--money .crecap__row { padding: 8px 0; }
.crecap__row--total { margin-top: 8px; padding: 12px 0 !important; border-top: 2px solid var(--tc-border); border-bottom: none; background: linear-gradient(135deg, var(--tc-red-subtle) 0%, #fff 100%); border-radius: 8px; padding: 12px 14px !important; width: 100%; }
.crecap__row--total dt { font-weight: 700 !important; color: var(--tc-ink) !important; }
.crecap__row--total dd { font-size: 16px !important; font-weight: 700 !important; color: var(--tc-accent-ink) !important; }
.crecap__legal-title { margin-top: 20px; font: 600 9.5px/1 var(--tc-font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--tc-ink-4); padding-bottom: 8px; border-bottom: 1px solid var(--tc-border-soft, #F1F3F5); }
.crecap__legal { list-style: none; padding: 0; margin: 16px 0 0; }
.crecap__legal li { position: relative; padding-left: 20px; font-size: 12.5px; color: var(--tc-ink-2); margin-bottom: 10px; line-height: 1.5; }
.crecap__legal li::before { content: '✓'; position: absolute; left: 0; top: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--tc-red); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: 700; }

/* Encart CNSS mis en avant (déclaration sociale). */
.quick-cnss { background: var(--tc-green-bg); border: 1px solid var(--tc-green-border); border-radius: 12px; padding: 15px 16px; }
.quick-cnss__head { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 13px; color: var(--tc-green-ink); margin-bottom: 5px; }
.quick-cnss__text { font-size: 12px; color: var(--tc-green-ink); margin: 0 0 12px; }
.quick-cnss .mb-3 { margin-bottom: 0 !important; }

/* Menu d'actions d'une ligne de tableau (contrôleur Stimulus « dropdown ») */
.app-actions { position: relative; display: inline-block; }
.actions-menu { position: absolute; top: calc(100% + 4px); right: 0; z-index: 1030; width: 190px; background: var(--tc-surface); border: 1px solid var(--tc-border); border-radius: 12px; box-shadow: 0 12px 30px rgba(16, 20, 26, .14); padding: 6px; }
.actions-menu[hidden] { display: none; }
.actions-menu__item { display: flex; align-items: center; gap: 9px; padding: 8px 10px; border-radius: 8px; text-decoration: none; font-weight: 600; font-size: 12.5px; color: var(--tc-ink-2); }
.actions-menu__item:hover { background: var(--tc-bg); }
/* Les entrées déclenchant une modale sont des <button>, pas des <a> : sans
   cette règle, le bouton garderait ses styles natifs (bordure, fond). */
button.actions-menu__item { width: 100%; border: 0; background: none; cursor: pointer; font: inherit; text-align: left; }

/* Grilles reprises telles quelles du prototype (mobile-first) */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(232px, 1fr)); gap: 16px; }
.two-col { display: grid; gap: 16px; grid-template-columns: 1fr; }
@media (min-width: 992px) {
    .two-col { grid-template-columns: 1.6fr 1fr; align-items: start; }
    .two-col.two-col--14 { grid-template-columns: 1.4fr 1fr; }
    .two-col.two-col--even { grid-template-columns: 1fr 1fr; }
}

.text-mono { font-family: var(--tc-font-mono); }
.eyebrow { font: 500 .75rem/1 var(--tc-font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--tc-accent-ink); }
.min-w-0 { min-width: 0; }

/* =========================================================
   SHELL APPLICATIF (espaces authentifiés) — mobile-first
   ========================================================= */
.app-shell { display: flex; flex-direction: column; min-height: 100vh; }

/* ---- Sidebar ---- */
.app-sidebar {
    background: var(--tc-sidebar);
    color: var(--tc-on-sidebar);
    border-right: 1px solid var(--tc-sidebar-border);
    --bs-offcanvas-width: 248px;
    --bs-offcanvas-bg: var(--tc-sidebar);
    --bs-offcanvas-color: var(--tc-on-sidebar);
    --bs-offcanvas-border-color: var(--tc-sidebar-border);
}
.app-sidebar__brand { padding: 20px 18px 14px; display: flex; align-items: center; gap: 11px; }
/* Pastille du logo. Le blanc est VOLONTAIREMENT en dur, et c'est le seul blanc
   du fichier qui le reste : les logos sont téléversés en PNG à fond
   transparent, le plus souvent avec des traits sombres. Les poser sur
   `--tc-surface` les ferait disparaître en thème sombre (surface presque
   noire sous un logo noir). Cette pastille est un plateau d'exposition, pas une
   surface de thème — elle ne suit donc pas le mode nuit. */
.app-logo { width: 40px; height: 40px; border-radius: 12px; background: #fff; display: flex; align-items: center; justify-content: center; flex: none; padding: 6px; box-shadow: 0 8px 18px rgba(8, 34, 44, .18); }
/* Repli quand aucun logo n'est configuré : l'initiale du logiciel, aux mêmes
   dimensions, pour qu'aucune image cassée n'apparaisse. */
.app-logo--empty { font: 800 17px/1 var(--tc-font-sans, Inter); color: var(--tc-accent-on-light); letter-spacing: -.02em; }
.app-wordmark { font-weight: 800; font-size: 18px; letter-spacing: -.03em; color: var(--tc-on-sidebar); }
.app-wordmark span { color: var(--tc-red-light); }
/* Rappel de l'espace courant, au-dessus des sections. */
.app-sidebar__space { font: 600 9.5px/1 var(--tc-font-mono); letter-spacing: .16em; text-transform: uppercase; color: var(--tc-sidebar-section); padding: 14px 20px 8px; }
.app-sidebar__section { font: 600 9px/1 var(--tc-font-mono); letter-spacing: .14em; text-transform: uppercase; color: var(--tc-sidebar-section); padding: 15px 12px 7px; }

.app-nav { flex: 1; overflow-y: auto; padding: 0 12px; display: flex; flex-direction: column; gap: 3px; }
.app-nav__item { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 8px; font-weight: 500; font-size: 14px; text-decoration: none; color: var(--tc-sidebar-muted); transition: background .12s, color .12s; }
.app-nav__item:hover { background: var(--tc-sidebar-hover); color: var(--tc-on-sidebar); }
.app-nav__item.is-active { background: var(--tc-red-soft); color: var(--tc-on-sidebar); }
.app-nav__item svg { flex: none; }
/* Pastille de comptage (demandes à valider) : poussée à droite de l'entrée. */
/* Pastille d'attente : ton « attention », pas la couleur de marque. Le rouge
   de la barre latérale signale l'ALERTE (erreur, action bloquée) ; un compteur
   de demandes à trancher est une file de travail, et l'ambre la dit sans
   crier. Le fond et l'encre viennent du triple ambre du thème pour rester
   lisibles sur la barre sombre dans les deux modes. */
.app-nav__badge { margin-left: auto; background: var(--tc-amber-bg); color: var(--tc-amber-ink); border: 1px solid var(--tc-amber-border); font-weight: 700; font-size: 11px; line-height: 1; padding: 3px 7px; border-radius: 999px; flex: none; }

.app-sidebar__footer { padding: 14px; border-top: 1px solid var(--tc-sidebar-border); }
.app-sidebar__name { font-weight: 600; font-size: 13px; color: var(--tc-on-sidebar); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Le rôle est l'information la plus discrète du bloc : il suit la même
   dérivation que les autres textes atténués de la barre latérale, au lieu d'un
   gris neutre qui ignorait la couleur secondaire. */
.app-sidebar__role { font-weight: 500; font-size: 11px; color: var(--tc-sidebar-faint); }
.app-sidebar__build { font: 500 10px/1.4 var(--tc-font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--tc-sidebar-section); padding: 0 6px 8px; }
.app-version { display: inline-flex; align-items: center; gap: 6px; background: rgba(var(--bs-primary-rgb), .14); color: var(--tc-red-light); font: 600 11px/1 var(--tc-font-mono); letter-spacing: .04em; padding: 5px 10px; border-radius: 999px; margin-top: 6px; }

.app-avatar { border-radius: 50%; background: var(--tc-red); color: var(--tc-on-primary); display: inline-flex; align-items: center; justify-content: center; font-weight: 700; flex: none; text-transform: uppercase; }

/* Pastille de code (sigle, numéro de ligne corporate…) : élargie par le
 contenu, là où un cercle de taille fixe laissait déborder tout code de plus
 de deux signes. `min-width` la garde compacte pour les codes courts. */
.app-code { border-radius:999px; background: var(--tc-red); color: var(--tc-on-primary); display: inline-flex; align-items: center; justify-content: center; min-width:36px; height:36px; padding-left:10px; padding-right:10px; font-weight:700; font-size:12px; letter-spacing: .02em; flex: none; white-space: nowrap; }

/* ---- Main / topbar ---- */
.app-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.app-topbar { position: sticky; top: 0; z-index: 1020; height: 60px; flex: none; background: #fff; border-bottom: 1px solid var(--tc-border); display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 0 16px; }
.app-search { display: none; align-items: center; gap: 10px; background: var(--tc-bg); border: 1px solid var(--tc-border); border-radius: 999px; padding: 8px 14px; flex: 1; max-width: 360px; }
.app-search input { border: none; background: none; outline: none; font-weight: 500; font-size: 13px; color: var(--tc-ink); width: 100%; }
.app-iconbtn { width: 38px; height: 38px; border-radius: 9px; border: none; background: none; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; color: var(--tc-ink-3); position: relative; transition: background .12s; }
.app-iconbtn:hover { background: var(--tc-bg); }
.app-iconbtn__dot { position: absolute; top: 8px; right: 9px; width: 7px; height: 7px; border-radius: 50%; background: var(--tc-red); border: 1.5px solid var(--tc-surface); }
.app-iconbtn__dot--count { top: 5px; right: 4px; width: auto; min-width: 15px; height: 15px; padding: 0 4px; border-radius: 999px; font-size: 9.5px; font-weight: 700; line-height: 15px; color: #fff; display: inline-flex; align-items: center; justify-content: center; border-width: 0; }

/* ---- Menu utilisateur ---- */
.app-usermenu { position: relative; }
.app-userchip { appearance: none; font: inherit; color: inherit; text-align: left; display: flex; align-items: center; gap: 10px; cursor: pointer; padding: 5px 11px 5px 6px; border-radius: 999px; border: 1px solid var(--tc-border); background: #fff; transition: background .12s; }
.app-userchip:hover { background: var(--tc-bg); }
.app-userchip__name { font-weight: 700; font-size: 12.5px; color: var(--tc-ink); }
.app-userchip__meta { font: 600 9.5px/1 var(--tc-font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--tc-ink-2); }
.app-userchip__status { position: absolute; bottom: 0; right: 0; width: 9px; height: 9px; border-radius: 50%; background: var(--tc-green-ink); border: 2px solid var(--tc-surface); }
.app-menu { position: absolute; top: 54px; right: 0; width: 288px; max-width: calc(100vw - 24px); background: var(--tc-surface); border: 1px solid var(--tc-border); border-radius: 14px; box-shadow: 0 18px 44px rgba(16, 20, 26, .17); z-index: 1030; overflow: hidden; }
.app-menu[hidden] { display: none; }
.app-menu__head { display: flex; align-items: center; gap: 12px; padding: 16px; border-bottom: 1px solid var(--tc-border); }
.app-menu__body { padding: 10px 12px 12px; }
.app-menu__item { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 9px; text-decoration: none; font-weight: 600; font-size: 12.5px; color: var(--tc-ink-2); }
.app-menu__item:hover { background: var(--tc-bg); }
.app-menu__item--danger { color: var(--tc-danger-ink); }
.app-menu__item--danger:hover { background: var(--tc-danger-bg); }
.app-menu__empty { padding: 12px 10px; font-size: 12.5px; color: var(--tc-ink-3); }
button.app-menu__item { width: 100%; border: none; background: none; cursor: pointer; text-align: left; }
button.app-menu__item:hover { background: var(--tc-bg); }
.app-menu__item--wrap { align-items: flex-start; }
.app-menu__item.is-unread { background: var(--tc-surface-soft); }
.app-menu__text { line-height: 1.35; white-space: normal; }
.app-notif-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.ccard--tinted { background: var(--tc-surface-soft); }

/* ── Page Notifications (/notifications) ── */
.notif-row__message { font-size: 13.5px; line-height: 1.45; color: var(--tc-ink); overflow-wrap: anywhere; }
a.notif-row__message:hover { color: var(--tc-accent-ink); }
.notif-row__actions { flex-wrap: wrap; justify-content: flex-end; }
@media (max-width: 767.98px) {
    .notif-row { flex-wrap: wrap; }
    .notif-row__body { flex: 1 1 calc(100% - 28px); }
    .notif-row__actions { width: 100%; justify-content: flex-start; padding-left: 21px; }
    .notif-row__actions .btn { flex: 1 1 auto; justify-content: center; }
}
.app-menu__sep { height: 1px; background: var(--tc-border); margin: 10px 4px; }
.app-menu__label { font: 600 9.5px/1 var(--tc-font-mono); letter-spacing: .1em; text-transform: uppercase; color: var(--tc-ink-4); padding: 6px 10px 8px; }

/* ---- Sélecteur d'espace (menu utilisateur) ---- */
.app-space { display: flex; align-items: center; gap: 11px; padding: 9px 10px; border-radius: 10px; text-decoration: none; }
.app-space:hover { background: var(--tc-bg); }
.app-space.is-active { background: var(--tc-red-subtle); }
.app-space__icon { width: 36px; height: 36px; border-radius: 9px; background: var(--tc-bg); color: var(--tc-ink-3); display: inline-flex; align-items: center; justify-content: center; flex: none; }
.app-space.is-active .app-space__icon { background: var(--tc-red); color: var(--tc-on-primary); }
.app-space__text { flex: 1; min-width: 0; }
.app-space__title { display: block; font-weight: 600; font-size: 13px; color: var(--tc-ink); }
.app-space.is-active .app-space__title { color: var(--tc-accent-ink); }
.app-space__sub { display: block; font-size: 11px; color: var(--tc-ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.app-space__mark { flex: none; color: var(--tc-accent-ink); }
.app-space__arrow { flex: none; color: var(--tc-ink-4); }

/* ---- Contenu ---- */
.app-content { flex: 1; padding: 20px 16px; background: var(--tc-bg); }
.app-content__inner { max-width: 100%; margin: 0; }
@media (min-width: 992px) {
    .app-content { padding: 28px 32px; }
    .app-content__inner { max-width: 1600px; margin: 0 auto; }
}

/* ---- Composants dashboard ---- */
.stat-label { font: 600 10.5px/1 var(--tc-font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--tc-ink-4); }
.stat-icon { width: 34px; height: 34px; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; flex: none; }
.stat-value { font-weight: 700; font-size: 30px; letter-spacing: -.02em; color: var(--tc-ink); }
.stat-unit { font-weight: 600; font-size: 13px; color: var(--tc-ink-4); }

/* ---- Cartes KPI (Rapports) : compactes, aux valeurs exactes du design ---- */
.kpi-grid { display: grid; grid-template-columns: 1fr; gap: 14px; }
.kpi-card { background: #fff; border: 1px solid var(--tc-border); border-radius: 12px; padding: 17px 19px; }
.kpi-label { font-weight: 600; font-size: 10.5px; line-height: 1; font-family: var(--tc-font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--tc-ink-4); }
.kpi-value { font-weight: 700; font-size: 26px; letter-spacing: -.01em; color: var(--tc-ink); }
.kpi-sub { font-weight: 500; font-size: 12px; color: var(--tc-ink-3); }

/* ---- Graphe de turnover (SVG maison) ----
   L'infobulle est en CSS pur : le survol d'une zone affiche le <g> qui la
   contient. Pas de JavaScript pour un graphe de 40 rectangles — et le repli
   clavier passe par `tabindex`, qui déclenche les mêmes sélecteurs que
   `:hover`. */
.turnover-chart-wrap { overflow-x: auto; }
.turnover-chart { display: block; width: 100%; min-width: 520px; height: auto; }
.turnover-chart__grid { stroke: var(--tc-border); stroke-width: 1; stroke-dasharray: 3 4; }
.turnover-chart__axis-line { stroke: var(--tc-border); stroke-width: 1; }
.turnover-chart__axis,
.turnover-chart__tick { fill: var(--tc-ink-4); font-size: 10px; font-weight: 500; }
.turnover-chart__bar--hires { fill: var(--tc-ink); }
.turnover-chart__bar--departures { fill: var(--tc-red); }
.turnover-chart__slot { cursor: default; outline: none; }
.turnover-chart__slot:hover .turnover-chart__bar,
.turnover-chart__slot:focus-visible .turnover-chart__bar { opacity: .78; }
.turnover-chart__tip { opacity: 0; pointer-events: none; transition: opacity .12s ease; }
.turnover-chart__tip rect { fill: var(--tc-ink); }
.turnover-chart__tip-label { fill: #fff; font-size: 10px; font-weight: 500; }
.turnover-chart__tip-value { fill: #fff; font-size: 11.5px; font-weight: 700; }
.turnover-chart__slot:hover .turnover-chart__tip,
.turnover-chart__slot:focus-visible .turnover-chart__tip { opacity: 1; }

@media (min-width: 576px) { .kpi-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 992px) { .kpi-grid { grid-template-columns: repeat(4, 1fr); } }

.pill { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; font-size: 12px; padding: 5px 10px; border-radius: 8px; }
.pill--round { border-radius: 999px; font-size: 11px; padding: 4px 10px; }
.pill__dot { width: 6px; height: 6px; border-radius: 50%; }

.tone-success { background: var(--tc-green-bg); color: var(--tc-green-ink); }
.tone-info { background: var(--tc-info-bg); color: var(--tc-info-ink); }
.tone-warn { background: var(--tc-amber-bg); color: var(--tc-amber-ink); }
.tone-danger { background: var(--tc-danger-bg); color: var(--tc-danger-ink); }
.tone-muted { background: var(--tc-bg); color: var(--tc-ink-4); }
.tone-neutral { background: var(--tc-bg); color: var(--tc-ink-2); }

/* Suivi des demandes de modification dans l'espace salarié */
.profile-requests__header { width: 100%; display: flex; align-items: center; gap: 12px; padding: 18px; border: 0; border-radius: inherit; background: transparent; text-align: left; cursor: pointer; }
.profile-requests__header:hover { background: var(--tc-surface-soft); }
.profile-requests__header:focus-visible { position: relative; z-index: 1; outline: 2px solid var(--tc-accent-ink); outline-offset: -3px; }
.profile-requests__icon { width: 42px; height: 42px; display: inline-flex; align-items: center; justify-content: center; flex: none; border-radius: 12px; background: var(--tc-surface-alt); color: var(--tc-accent-ink); }
.profile-requests__heading { min-width: 0; flex: 1; }
.profile-requests__title { display: block; margin: 0; color: var(--tc-ink); font-size: 14px; font-weight: 700; letter-spacing: -.01em; }
.profile-requests__heading p { margin: 3px 0 0; color: var(--tc-ink-4); font-size: 12px; }
.profile-requests__counts { display: flex; flex: none; flex-wrap: wrap; justify-content: flex-end; gap: 6px; }
.profile-requests__count { padding: 5px 9px; border-radius: 999px; background: var(--tc-amber-bg); color: var(--tc-amber-ink); font-size: 11px; font-weight: 700; white-space: nowrap; }
.profile-requests__count--approved { background: var(--tc-green-bg); color: var(--tc-green-ink); }
.profile-requests__count--rejected { background: var(--tc-danger-bg); color: var(--tc-danger-ink); }
.profile-requests__chevron { display: inline-flex; align-items: center; justify-content: center; flex: none; color: var(--tc-ink-4); transition: transform .18s ease; }
.profile-requests__header[aria-expanded="true"] .profile-requests__chevron { transform: rotate(180deg); }
.profile-requests__list { display: grid; gap: 9px; padding: 14px 18px 18px; border-top: 1px solid var(--tc-border); }
.profile-request { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 13px 14px; border: 1px solid var(--tc-border); border-radius: 10px; background: var(--tc-surface-soft); }
.profile-request__content { min-width: 0; }
.profile-request__title { color: var(--tc-ink); font-size: 13px; font-weight: 650; }
.profile-request__date { margin-top: 3px; color: var(--tc-ink-4); font-size: 11.5px; }
.profile-request__comment { margin: 7px 0 0; color: var(--tc-ink-3); font-size: 12px; }
.profile-request__actions { display: flex; align-items: center; justify-content: flex-end; flex: none; gap: 10px; }
.profile-request__cancel { display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 6px 9px; border: 1px solid transparent; border-radius: 7px; background: transparent; color: var(--tc-danger-ink); font-size: 11.5px; font-weight: 600; cursor: pointer; transition: background .12s, border-color .12s; }
.profile-request__cancel:hover { border-color: var(--tc-danger-border); background: var(--tc-danger-bg); }
.profile-request__cancel:focus-visible { outline: 2px solid var(--tc-danger-ink); outline-offset: 2px; }
.profile-request-modal .modal-content { overflow: hidden; border: 1px solid var(--tc-border); border-radius: 14px; background: var(--tc-surface); box-shadow: 0 20px 50px rgba(16, 20, 26, .18); }
.profile-request-modal .modal-header { gap: 11px; padding: 18px 20px; border-bottom: 1px solid var(--tc-border); }
.profile-request-modal__icon { width: 38px; height: 38px; display: inline-flex; align-items: center; justify-content: center; flex: none; border-radius: 10px; background: var(--tc-danger-bg); color: var(--tc-danger-ink); }
.profile-request-modal .modal-title { color: var(--tc-ink); font-size: 15px; font-weight: 700; }
.profile-request-modal .modal-body { padding: 18px 20px; color: var(--tc-ink-3); font-size: 13px; line-height: 1.55; }
.profile-request-modal .modal-footer { gap: 8px; padding: 13px 20px; border-top: 1px solid var(--tc-border); }
@media (max-width: 575.98px) {
    .profile-requests__header { align-items: flex-start; gap: 9px; padding: 15px; }
    .profile-requests__icon { width: 36px; height: 36px; }
    .profile-requests__heading p { font-size: 11px; }
    .profile-requests__counts { margin-left: auto; max-width: 55%; }
    .profile-requests__count { padding: 4px 7px; font-size: 10px; }
    .profile-requests__chevron { margin-top: 4px; }
    .profile-requests__list { padding: 12px 15px 15px; }
    .profile-request { align-items: flex-start; flex-direction: column; gap: 11px; }
    .profile-request__actions { width: 100%; justify-content: space-between; }
}

.heatmap { display: grid; grid-template-columns: repeat(24, 1fr); gap: 3px; }
.heatmap span { aspect-ratio: 1; border-radius: 2px; }

/* ---- Cartes « Exports disponibles » (grille 3 colonnes) ---- */
.export-grid { display: grid; grid-template-columns: 1fr; gap: 16px; }
.export-card { background: #fff; border: 1px solid var(--tc-border); border-radius: 13px; padding: 18px; display: flex; flex-direction: column; gap: 12px; }
.export-icon { width: 40px; height: 40px; border-radius: 10px; background: var(--tc-bg); color: var(--tc-ink-2); display: inline-flex; align-items: center; justify-content: center; flex: none; }
@media (min-width: 768px) { .export-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 992px) { .export-grid { grid-template-columns: repeat(3, 1fr); } }

/* ---- Sous-en-tête (barre d'onglets pleine largeur, collée à la topbar) ---- */
.app-subheader { flex: none; background: #fff; border-bottom: 1px solid var(--tc-border); padding: 0 16px; }

/* ═══════════════════════════════════════════════════════════════════════════
   BARRES D'ONGLETS — comportement commun, défini UNE fois.

   Toute barre d'onglets défile horizontalement plutôt que de se tasser ou de
   pousser la page en largeur. Sur téléphone, six onglets ne tiennent pas : sans
   cette règle, soit les libellés se coupent, soit c'est la PAGE entière qui
   défile en x et l'on perd la lecture du contenu.

   La règle porte sur les quatre familles existantes plutôt que sur une seule :
   `.ch-tabs` et `.val-tabs` sont dessinées en ligne dans leurs gabarits, et une
   nouvelle barre qui reprendrait l'une d'elles hériterait sinon d'une copie
   figée. La barre de défilement est masquée — sur mobile elle se superpose au
   trait de l'onglet actif — mais le geste, lui, reste possible.
   ═══════════════════════════════════════════════════════════════════════════ */
.page-tabs, .tc-subtabs, .ch-tabs, .val-tabs {
    overflow-x: auto;
    overflow-y: hidden;
    flex-wrap: nowrap;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.page-tabs::-webkit-scrollbar, .tc-subtabs::-webkit-scrollbar,
.ch-tabs::-webkit-scrollbar, .val-tabs::-webkit-scrollbar { display: none; }

/* Un onglet ne se coupe pas et ne se comprime pas : il sort du cadre, et l'on
   défile jusqu'à lui. */
.page-tab, .tc-subtab, .ch-tab, .val-tab { white-space: nowrap; flex: 0 0 auto; }

/* ── Signes de défilement d'une barre d'onglets ─────────────────────────────
   Une barre qui défile en silence se lit comme une barre qui s'arrête : l'onglet
   coupé net au bord devient un défaut d'écran au lieu d'une invitation. Deux
   chevrons, posés sur les bords, disent qu'il reste à voir et permettent d'y
   aller — un peu comme les flèches d'un carrousel.

   Le balcon est fabriqué par `tabs_scroll_controller` : les chevrons ne peuvent
   pas vivre DANS la barre, ils défileraient avec elle. Ils restent posés en
   absolu dessus, d'où ce conteneur `position: relative`.

   Un chevron sans rien à montrer est RETIRÉ (`hidden`), pas transparent : il
   sort alors de la tabulation et de l'accessibilité, ce qu'un `opacity: 0` ne
   ferait pas. Un bouton inerte qui ne mène nulle part apprend au lecteur à
   ignorer les indications.
*/
.tabs-scroll { position: relative; }
.tabs-scroll__nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    display: none;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    color: var(--tc-ink-2);
    background: var(--tc-surface);
    border: 1px solid var(--tc-border);
    border-radius: 50%;
    box-shadow: 0 2px 8px rgba(16, 20, 26, .12);
    cursor: pointer;
    transition: color .12s ease, background .12s ease;
}
.tabs-scroll__nav--previous { left: 4px; }
.tabs-scroll__nav--next { right: 4px; }
.tabs-scroll__nav:hover { color: var(--tc-accent-ink); background: var(--tc-surface-soft); }
/* `hidden` doit l'emporter sur le `display` du media query plus bas : sans
   cette règle, un chevron sans rien à montrer restait cliquable sur mobile. */
.tabs-scroll__nav[hidden] { display: none; }

/* L'ombre des chevrons est posée en noir translucide : en mode sombre, elle
   disparaîtrait sur le fond foncé, et la pastille semblerait plate. */
[data-bs-theme="dark"] .tabs-scroll__nav { box-shadow: 0 2px 10px rgba(0, 0, 0, .45); }

@media (max-width: 991.98px) {
    /* Téléphone seulement : sur un écran large la barre se lit en entier, et
       les chevrons n'encombrent que la lecture. La règle est ici, et non dans
       le contrôleur : celui-ci mesure le débordement, il ne décide pas de la
       place à l'écran. */
    .tabs-scroll__nav { display: inline-flex; }
}

/* ---- Onglets de page (in-page tabs) ---- */
.page-tabs { display: flex; gap: 4px; }
.page-tab { appearance: none; border: none; background: none; cursor: pointer; padding: 12px 4px; margin-right: 20px; font-weight: 600; font-size: 14px; color: var(--tc-ink-3); text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; transition: color .12s; }
.page-tab:hover { text-decoration: none; }
.page-tab:hover { color: var(--tc-ink); }
.page-tab.is-active { color: var(--tc-accent-ink); border-bottom-color: var(--tc-red); }
/* Pastille d'un onglet de module : même ton « attention » que la barre
   latérale, mais collée au libellé de l'onglet qu'elle concerne. Elle compte
   ce que l'onglet ouvre, jamais la file du module entier. */
.page-tab__badge { display: inline-flex; align-items: center; margin-left: 7px; vertical-align: middle; background: var(--tc-amber-bg); color: var(--tc-amber-ink); border: 1px solid var(--tc-amber-border); font-weight: 700; font-size: 11px; line-height: 1; padding: 3px 7px; border-radius: 999px; }

/* ---- Sélecteur de période : boutons pilules séparés (comme le design) ---- */
.period-seg { display: inline-flex; gap: 6px; flex-wrap: wrap; }
/* `button` ET `a` : certains sélecteurs de période (portée d'une duplication)
   sont des liens — un GET, rien n'est écrit — et doivent se présenter
   exactement comme les boutons équivalents. */
.period-seg button,
.period-seg a { appearance: none; cursor: pointer; padding: 8px 14px; border-radius: 8px; border: 1px solid var(--tc-border); background: #fff; font-weight: 600; font-size: 12.5px; color: var(--tc-ink-3); transition: background .12s, color .12s; }
.period-seg button.is-active,
.period-seg a.is-active { background: var(--tc-red-subtle); color: var(--tc-accent-ink); border-color: var(--tc-red-border); }

/* ---- Filtre de dates : un seul conteneur blanc bordé ---- */
/* `flex-wrap` : la plage « Du → Au » + bouton fait ~370 px à l naturel. Sous
   cette largeur, le conteneur se replie sur plusieurs lignes au lieu de sortir
   de l'écran — c'était la seule chose qui manquait ici. Les enfants, eux, gardent
   leur taille (`flex: none`) : un élément flex se comprime par défaut, et les
   champs de date se seraient aplatis pour tenir sur une seule ligne. */
.date-filter { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 7px; max-width: 100%; background: #fff; border: 1px solid var(--tc-border); border-radius: 9px; padding: 5px 6px 5px 12px; }
.date-filter > * { flex: none; }
.date-filter__label { font: 600 10px/1 var(--tc-font-mono); letter-spacing: .05em; text-transform: uppercase; color: var(--tc-ink-4); }
.date-filter input[type="date"] { border: 1px solid #DEE2E6; border-radius: 7px; padding: 6px 9px; font-weight: 500; font-size: 12px; color: var(--tc-ink); background: #fff; }

/* ============================================================================
   BARRE DE FILTRES — un composant, commun à toutes les pages

   Ces barres étaient écrites page par page, chacune à sa façon. Deux symptômes,
   tous deux dus au même défaut — aucun `flex-wrap` ni `min-width: 0` :

   — les barres en `d-flex gap-2` (utilisateurs, planning, évaluation) ne se
     repliaient pas : le `min-width:240px` du champ de recherche les pousserait
     hors de l'écran, 37 à 77 px de débordement mesurés sous 390 px ;
   — les barres en `flex-wrap` se repliaient, mais en écrasant : un élément
     flex se comprime avant de passer à la ligne, et les <select> se
     retroussaient à 100-150 px, deux ou trois par ligne, libellés tronqués.

   Ici la règle est posée UNE fois, en mobile-first :

   — smartphone : un contrôle par ligne (`flex: 1 1 100%`). La cible tactile
     fait toute la largeur, ce qui est aussi le seul moyen de lire un <select>
     dont le libellé est long ;
   — à partir de md : la barre redevient une rangée, chaque contrôle reprend sa
     largeur intrinsèque (`width: auto`) et la recherche prend la place
     restante ;
   — `min-width: 0` sur tous les enfants : sans lui, un <select> au libellé
     long refuse de se réduire et repousse toute la barre hors de l'écran.

   Les marges restent à la charge des utilitaires Bootstrap (`mb-3`) de la page :
   une barre placée dans un en-tête ne doit pas en hériter.
   ============================================================================ */
.app-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; max-width: 100%; }
.app-filters > * { flex: 1 1 100%; min-width: 0; max-width: 100%; }
/* Les boutons gardent leur taille naturelle : « Appliquer » n'a pas besoin de
   toute la largeur, et les rare actions manuelles se rangent côte à côte. */
.app-filters > .btn, .app-filters > button { flex: 0 0 auto; }
/* La recherche de la topbar est masquée sous lg (réservée à la barre du haut) ;
   dans une barre de filtres elle doit rester visible, d'où cet appel. */
.app-filters .app-search { display: flex; max-width: none; }
/* Le groupe de boutons « période » et le filtre de dates ne doivent pas déborder
   : ils se replient sur plusieurs lignes plutôt que de dépasser l'écran. */
.app-filters .period-seg, .app-filters .date-filter { flex-wrap: wrap; }
.app-filters .date-filter { width: 100%; }
/* Champ étiqueté (page du calendrier des congés, liste des bulletins). */
.app-filters__field { display: flex; flex-direction: column; gap: 7px; }
.app-filters__field > label { font: 600 12.5px var(--tc-font-sans, Inter); color: var(--tc-ink-2); }

/* Variante « carte » : la barre dans son propre panneau blanc bordé, comme le
   dessinaient les pages qui avaient déjà ce cadre en dur dans un style inline. */
.app-filters--card { align-items: flex-end; gap: 14px; padding: 16px; margin-bottom: 18px; background: var(--tc-surface); border: 1px solid var(--tc-border); border-radius: 14px; }
/* Variante « empilée » : deux niveaux de filtres (choix de période, puis
   bornes de dates) superposés et alignés à droite. Sur téléphone la colonne
   se déplie, pleine largeur, et les boutons de période se partagent la ligne. */
.app-filters--stack { flex-direction: column; align-items: flex-end; }

@media (min-width: 768px) {
    .app-filters { align-items: flex-end; gap: 10px; }
    /* Rangée : chaque contrôle reprend sa largeur naturelle au lieu d'une ligne. */
    .app-filters > * { flex: 0 1 auto; width: auto; }
    .app-filters .form-select, .app-filters .form-control, .app-filters .payslip-select, .app-filters .mail-input { width: auto; }
    /* La recherche, elle, occupe la place restante — c'est le seul contrôle
       qui s'étire, et seulement s'il le demande (.app-filters__grow) ou s'il
       EST une recherche. */
    .app-filters .app-search, .app-filters input[type="search"], .app-filters__grow { flex: 1 1 220px; max-width: 420px; }
    .app-filters .date-filter { width: auto; }
    .app-filters--card > * { flex: 0 1 auto; }
    .app-filters--card .app-filters__field { flex: 1 1 200px; }
}

@media (max-width: 767.98px) {
    .app-filters--stack { align-items: stretch; }
    .app-filters--stack .period-seg { display: flex; }
    .app-filters--stack .period-seg button { flex: 1 1 0; }
}

/* Les filtres des annuaires employés et contrats se redistribuent selon la
   largeur disponible, sans colonnes fixes ni débordement mobile. */
.directory-filters.directory-filters { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr)); align-items: end; gap: 10px; }
.directory-filters.directory-filters > * { width: 100%; min-width: 0; max-width: none; }
.directory-filters.directory-filters .form-select,
.directory-filters.directory-filters .form-control,
.directory-filters.directory-filters .app-search { width: 100%; max-width: none; }

/* =========================================================
   ≥ lg : sidebar fixe, contenu défilant indépendamment
   ========================================================= */
@media (min-width: 992px) {
    html, body { height: 100%; overflow: hidden; }
    .app-shell { flex-direction: row; height: 100vh; overflow: hidden; }
    /* Bootstrap force `background: transparent !important` sur .offcanvas-lg au-delà
       de lg : on réimpose le fond sombre de la sidebar. */
    .app-sidebar { display: flex !important; flex-direction: column; width: 248px; flex: none; height: 100vh; transform: none !important; visibility: visible !important; background-color: var(--tc-sidebar) !important; border-right: 1px solid var(--tc-sidebar-border); }
    /* `min-height: 0` est indispensable : un enfant de flexbox refuse par
       défaut de descendre sous la hauteur de son contenu. Sans lui, une page
       longue déborde du panneau, la page entière se met à défiler, et la barre
       latérale — pourtant fixe — remonte avec elle. */
    .app-main { height: 100vh; min-height: 0; }
    .app-content { overflow-y: auto; min-height: 0; padding: 28px 32px; }

    /* ── Messagerie : plein écran ──
       Cet écran-là ne défile pas ; ce sont ses volets qui défilent. On chaîne
       donc la hauteur du panneau jusqu'à la coque, et `min-height: 0` à chaque
       étage — sans lui, un enfant de flexbox refuse de descendre sous la
       hauteur de son contenu et tout le calcul retombe à plat.
       C'est ce qui garde les boutons Répondre / Transférer au bas de l'écran,
       quelle que soit la longueur du fil. */
    .app-content:has(.msg-page) { overflow: hidden; display: flex; }
    .app-content:has(.msg-page) .app-content__inner { display: flex; flex-direction: column; flex: 1; min-height: 0; width: 100%; }
    .msg-page { display: flex; flex-direction: column; flex: 1; min-height: 0; }
    .msg-page .msg-shell { flex: 1; min-height: 0; }
    .app-topbar { padding: 0 24px; }
    .app-subheader { padding: 0 32px; }
    .app-search { display: flex; }
}

/* Menu de langue : drapeaux dans les options, menu compact. */
.app-flag { font-size: 15px; line-height: 1; }
/* `min-width` était sans effet : `.app-menu` fixe déjà `width`. Le menu des
   langues faisait donc 288px comme les autres, et son bord gauche sortait de
   l'écran sur téléphone — il est ancré sous un bouton du milieu de la barre. */
.app-menu--compact { width: 200px; }
.app-menu__item.is-active { color: var(--tc-accent-ink); font-weight: 600; }

/* ═══════════════════════════════════════════════════════════════════════════
   Espace employé — « Mon espace »

   Sous-onglets (.tc-subtabs) : ce dessin était défini en double, en ligne dans
   templates/leave/index.html.twig. Il est promu ici pour que les deux écrans
   partagent la même règle plutôt que deux copies qui divergeront.
   ═══════════════════════════════════════════════════════════════════════════ */
.tc-subtabs { display: flex; gap: 0; border-bottom: 1px solid var(--tc-border); margin-bottom: 22px; overflow-x: auto; }
.tc-subtab {
    display: inline-flex; align-items: center; gap: 7px; padding: 11px 16px;
    font: 600 13.5px Inter, sans-serif; border: none; background: none;
    color: var(--tc-ink-3); cursor: pointer; text-decoration: none;
    border-radius: 8px 8px 0 0; white-space: nowrap;
    border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tc-subtab:hover { color: var(--tc-ink); text-decoration: none; }
.tc-subtab.is-active { background: var(--tc-red-subtle); color: var(--tc-accent-ink); border-bottom-color: var(--tc-red); }

/* En-tête de fiche : grille nommée, et non file de flex.

   En flex, l'avatar de 76px partageait sa ligne avec le bloc de texte : sur un
   téléphone la colonne tombait à ~180px, le nom s'étalait sur trois lignes et
   les méta se coupaient au milieu d'un mot. Chaque élément a donc SA zone, et
   le repli sous 576px les réempile — nom à côté de l'avatar, méta puis actions
   en pleine largeur. `min-width: 0` empêche un mot insécable de souffler la
   piste et d'élargir la page ; le repli des méta ne se déclenche que si ce mot
   ne tient VRAIMENT pas. */
.prof-head {
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
        'avatar name actions'
        'avatar meta actions';
    align-items: start;
    column-gap: 14px;
    padding: 0 22px;
}
.prof-head > .prof-avatar { grid-area: avatar; align-self: center; }
.prof-head__name { grid-area: name; min-width: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.prof-head__name h1 { overflow-wrap: anywhere; }
.prof-head__meta { grid-area: meta; min-width: 0; }
.prof-head__actions { grid-area: actions; display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }

/* En-tête de fiche : avatar carré arrondi avec témoin de présence. */
.prof-avatar {
    width: 76px; height: 76px; border-radius: 16px; background: var(--tc-red);
    display: flex; align-items: center; justify-content: center;
    color: var(--tc-on-primary); font: 700 26px Inter, sans-serif; letter-spacing: -.02em;
    position: relative; flex: none;
}
.prof-avatar img { width: 100%; height: 100%; border-radius: 16px; object-fit: cover; }
.prof-avatar__dot { position: absolute; right: -2px; bottom: -2px; width: 16px; height: 16px; border-radius: 50%; border: 3px solid #fff; }
.prof-badge { font: 500 10px 'JetBrains Mono', monospace; letter-spacing: .1em; text-transform: uppercase; color: var(--tc-accent-ink); background: var(--tc-red-subtle); padding: 3px 8px; border-radius: 5px; }
.prof-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 18px; font: 600 13px Inter, sans-serif; color: var(--tc-ink-2); }
/* `overflow-wrap: anywhere` : une méta n'a pas toujours d'espace où se couper
   (poste ou direction en un seul mot long). Sans lui, le mot débordait de sa
   colonne au lieu de passer à la ligne. */
.prof-meta__item { display: inline-flex; align-items: center; gap: 7px; overflow-wrap: anywhere; }
.prof-meta__muted { font-weight: 400; color: var(--tc-ink-4, #ADB5BD); }

/* Bandeau de chiffres : colonnes séparées par un filet vertical. */
.prof-stats { display: grid; grid-template-columns: repeat(4, 1fr); border-top: 1px solid var(--tc-border); margin-top: 18px; }
.prof-stats > div { padding: 16px 22px; }
.prof-stats > div + div { border-left: 1px solid var(--tc-border); }
@media (max-width: 767.98px) {
    .prof-stats { grid-template-columns: repeat(2, 1fr); }
    .prof-stats > div:nth-child(odd) { border-left: none; }
    .prof-stats > div:nth-child(n+3) { border-top: 1px solid var(--tc-border); }
}

/* Liste « libellé / valeur » précédée d'une pastille d'icône. */
.prof-section { font: 500 10.5px 'JetBrains Mono', monospace; letter-spacing: .1em; text-transform: uppercase; color: var(--tc-ink-4, #ADB5BD); margin: 0 0 6px; }
.prof-row { display: flex; align-items: center; gap: 12px; padding: 11px 0; border-bottom: 1px solid #F1F3F5; }
.prof-row:last-child { border-bottom: none; }
.prof-row__icon { width: 34px; height: 34px; border-radius: 10px; background: #F4F5F7; display: flex; align-items: center; justify-content: center; color: var(--tc-ink-3); flex: none; }
.prof-row__icon--accent { background: var(--tc-red-subtle); color: var(--tc-accent-ink); }
.prof-row__label { font: 500 11px Inter, sans-serif; color: var(--tc-ink-4, #ADB5BD); }
.prof-row__value { font: 700 13.5px Inter, sans-serif; color: var(--tc-ink); }
.prof-row__value--empty { font-weight: 500; color: var(--tc-ink-4, #ADB5BD); }

/* Fil d'activité : filet vertical ponctué de pastilles. */
.prof-timeline { position: relative; padding-left: 18px; }
.prof-timeline::before { content: ''; position: absolute; left: 3px; top: 6px; bottom: 6px; width: 1px; background: var(--tc-border); }
.prof-timeline__item { position: relative; padding: 0 0 16px; }
.prof-timeline__item:last-child { padding-bottom: 0; }
.prof-timeline__dot { position: absolute; left: -18px; top: 4px; width: 7px; height: 7px; border-radius: 50%; background: var(--tc-red); }
.prof-chip { display: inline-block; background: #F4F5F7; color: var(--tc-ink-2); font: 500 11.5px Inter, sans-serif; padding: 4px 9px; border-radius: 6px; }

/* Valeur non modifiable, présentée comme un champ désactivé (maquette). */
.prof-value-box { background: #F8F9FA; border: 1px solid #F1F3F5; border-radius: 9px; padding: 11px 13px; font: 600 13.5px Inter, sans-serif; color: var(--tc-ink); }
.prof-btn-block { display: block; width: 100%; text-align: center; padding: 11px 14px; font: 600 13px Inter, sans-serif; color: var(--tc-on-primary); background: var(--tc-red); border: none; border-radius: 9px; cursor: pointer; }
.prof-btn-block:hover { background: var(--tc-red-hover); }
.prof-btn-soft { display: inline-flex; align-items: center; gap: 6px; padding: 9px 14px; font: 600 12.5px Inter, sans-serif; color: var(--tc-accent-ink); background: var(--tc-red-subtle); border: none; border-radius: 8px; cursor: pointer; text-decoration: none; }
.prof-btn-soft:hover { background: var(--tc-red-border); color: var(--tc-accent-ink); }

/* Accordéons de la fiche signalétique. */
.prof-accordion { background: #fff; border: 1px solid var(--tc-border); border-radius: 14px; overflow: hidden; }
.prof-accordion__head { display: flex; align-items: center; gap: 11px; width: 100%; padding: 15px 18px; background: none; border: none; cursor: pointer; text-align: left; }
.prof-accordion__body { padding: 0 18px 18px; border-top: 1px solid #F1F3F5; padding-top: 16px; }

/* Repli de la fiche sous 768px — le seuil des chiffres, ci-dessus.

   L'en-tête abandonne ses trois colonnes pour deux : le nom se range à côté de
   l'avatar, puis les méta et les actions prennent toute la largeur. La raison
   tient à la largeur RÉELLE de la carte, qui n'est pas celle de l'écran : sur
   une tablette de 600px sans barre latérale, la carte fait 568px, et les
   actions (263px) et l'avatar (76px) ne laissent au nom qu'une centaine de
   pixels — de quoi casser un nom de famille au milieu d'un mot. Superposées,
   les zones ne se disputent plus la largeur.

   Les chiffres gardent leurs deux colonnes, déjà bordées par la règle des
   768px. */
@media (max-width: 767.98px) {
    .prof-head {
        grid-template-columns: auto minmax(0, 1fr);
        grid-template-areas:
            'avatar name'
            'meta meta'
            'actions actions';
    }
}

/* Gouttières resserrées sur téléphone : les 22px de l'en-tête et des chiffres
   (18px pour les accordéons) mangent près d'un cinquième d'un écran de 360px,
   alors que la carte y fait déjà moins de 330px. */
@media (max-width: 575.98px) {
    .prof-head { padding: 0 16px; }
    .prof-head__name { margin-bottom: 6px; }
    .prof-stats > div { padding: 13px 16px; }
    .prof-accordion__head { padding: 13px 15px; }
    .prof-accordion__body { padding: 14px 15px 15px; }
}

/* Matrice des accès. */
.prof-flag { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 5px; font: 600 10.5px 'JetBrains Mono', monospace; background: #F1F3F5; color: #CED4DA; }
.prof-flag.is-on { background: var(--tc-red); color: var(--tc-on-primary); }
.prof-chmod { font: 500 11px 'JetBrains Mono', monospace; color: var(--tc-ink-3); letter-spacing: .06em; }
.prof-chmod__octal { display: block; font-size: 11px; color: var(--tc-accent-ink); }

/* Champ texte plat, même dessin que .payslip-select mais sans le chevron : un
   input n'ouvre pas de liste, lui en donner l'apparence induirait en erreur. */
.tc-input {
    width: 100%;
    padding: 11px 13px;
    font: 500 13.5px Inter, sans-serif;
    color: var(--tc-ink);
    background-color: #fff;
    border: 1px solid #DEE2E6;
    border-radius: 9px;
    outline: none;
    box-sizing: border-box;
}
.tc-input:focus { border-color: var(--tc-red); }
.tc-input:disabled { background-color: #F8F9FA; color: var(--tc-ink-3); }

/* Seconde rangée d'onglets, collée à la première dans le sous-en-tête (module
   Congés & absences : Absence / Congé / Mes Titres). Même dessin que les
   onglets de tête, en un cran plus discret — c'est une subdivision, pas une
   navigation de même rang. */
.page-tabs--sub { border-top: 1px solid var(--tc-border); }
.page-tabs--sub .page-tab { padding: 10px 4px; font-size: 13px; }

/* ── Accès utilisateurs : permissions par rôle ────────────────────────────
   Une grille de modules, chacun listant ses permissions cochables. Une
   permission verrouillée reste VISIBLE et grisée : la masquer laisserait
   croire qu'elle n'existe pas. */
.aperm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 18px; }
.aperm-module { min-width: 0; }
.aperm-module__title { font-weight: 700; font-size: 11.5px; letter-spacing: .04em; text-transform: uppercase; color: var(--tc-ink-3); padding-bottom: 7px; margin-bottom: 9px; border-bottom: 1px solid var(--tc-border); }
.aperm { display: flex; align-items: flex-start; gap: 9px; padding: 6px 0; margin: 0; cursor: pointer; }
.aperm .form-check-input { margin: 2px 0 0; flex: none; }
.aperm .form-check-input:checked { background-color: var(--tc-red); border-color: var(--tc-red); }
.aperm__label { display: block; font-weight: 600; font-size: 12.5px; color: var(--tc-ink); }
.aperm__hint { display: block; font-size: 11.5px; line-height: 1.4; color: var(--tc-ink-4); }
.aperm--locked { cursor: not-allowed; opacity: .5; }

/* Barre de filtre des rôles : la recherche garde sa largeur naturelle et les
   autres contrôles se rangent à sa droite. */
.access-filter-bar { padding: 12px 16px; }
.access-filter-toggle { display: inline-flex; align-items: center; gap: 8px; margin: 0; font-weight: 600; font-size: 12.5px; color: var(--tc-ink-2); cursor: pointer; }
.access-filter-toggle .form-check-input { margin: 0; }
.access-filter-count { font-size: 12.5px; color: var(--tc-ink-3); white-space: nowrap; }
.access-filter-count b { color: var(--tc-ink); }

/* Bandeau de synthèse d'une carte de rôle : permissions actives, comptes qui
   portent le rôle, et les deux actions de coche globale. */
.access-role-meta { display: flex; align-items: center; gap: 24px; flex-wrap: wrap; margin: 14px 0 18px; padding: 12px 0; border-top: 1px solid var(--tc-border); border-bottom: 1px solid var(--tc-border); }
.access-role-meta__item { display: flex; flex-direction: column; gap: 4px; }
.access-role-meta__value { font-size: 13px; font-weight: 600; color: var(--tc-ink); }
.access-role-bulk { display: flex; gap: 8px; margin-left: auto; flex-wrap: wrap; }
.access-role-bulk .btn-tc-outline,
.access-role-card .btn-sm { padding: 6px 11px; font-size: 11.5px; border-radius: 7px; }
.access-role-card .ccard__hint { max-width: 72ch; }
.access-role-card .aperm--checked { background: var(--tc-danger-bg); border-radius: 6px; margin-left: -6px; margin-right: -6px; padding-left: 6px; padding-right: 6px; }

/* En-tête de module : le titre garde la ligne, les compteurs et les actions
   « Tout / Aucun » se replient dessous sur les écrans étroits. */
.aperm-module__head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding-bottom: 7px; margin-bottom: 9px; border-bottom: 1px solid var(--tc-border); flex-wrap: wrap; }
.aperm-module__head .aperm-module__title { padding-bottom: 0; margin-bottom: 0; border-bottom: none; }
.aperm-module__tools { display: flex; align-items: center; gap: 6px; }
.aperm-module__count { font: 600 10.5px var(--tc-font-mono); color: var(--tc-ink-4); background: var(--tc-bg); padding: 2px 6px; border-radius: 999px; }
.aperm-module__toggle { border: none; background: none; padding: 2px 4px; font: 600 10.5px var(--tc-font-sans, Inter); color: var(--tc-ink-3); cursor: pointer; border-radius: 4px; }
.aperm-module__toggle:hover,
.aperm-module__toggle.is-active { color: var(--tc-red); background: var(--tc-danger-bg); }

/* Sélecteur de rôle modèle : un rôle coché pré-remplit sa politique dans la
   grille des permissions, qu'on ajuste ensuite à la main. */
.access-roles { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 20px; }
.access-roles__label { width: 100%; font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--tc-ink-3); }
.access-role { display: inline-flex; align-items: center; gap: 8px; padding: 7px 12px; border: 1px solid var(--tc-border); border-radius: 8px; background: var(--tc-surface); font-size: 12.5px; font-weight: 600; color: var(--tc-ink-2); cursor: pointer; user-select: none; transition: border-color .12s, box-shadow .12s; }
.access-role:hover { border-color: var(--tc-red); }
.access-role input { margin: 0; accent-color: var(--tc-red); cursor: pointer; }
.access-role:has(input:checked) { border-color: var(--tc-red); box-shadow: 0 0 0 1px var(--tc-red) inset; color: var(--tc-ink); }
.access-role__count { font-size: 10.5px; font-weight: 700; color: var(--tc-ink-3); background: var(--tc-bg); padding: 1px 7px; border-radius: 999px; }
.access-role:has(input:checked) .access-role__count { color: var(--tc-accent-ink); }

/* ── Grille d'évaluation : rubriques, niveaux et barèmes ──────────────────
   Le libellé du niveau porte l'essentiel : c'est lui qui rend une note
   défendable. Il occupe donc la largeur, les chiffres l'encadrent. */
.egrid-rubric { padding: 14px 0; border-top: 1px solid var(--tc-border); }
.egrid-rubric:first-of-type { border-top: none; padding-top: 0; }
.egrid-rubric__head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 9px; }
.egrid-rubric__name { font-weight: 700; font-size: 13.5px; color: var(--tc-ink); }
.egrid-rubric__coef { font-size: 11.5px; font-weight: 600; color: var(--tc-accent-ink); background: var(--tc-red-subtle); border-radius: 999px; padding: 2px 9px; }
.egrid-rubric__max { font-size: 11.5px; color: var(--tc-ink-4); margin-left: auto; }
.egrid-levels { list-style: none; margin: 0; padding: 0; counter-reset: none; }
.egrid-levels li { display: grid; grid-template-columns: 26px minmax(0, 1fr) 52px; gap: 10px; align-items: baseline; padding: 5px 0; }
.egrid-level__points { width: 26px; height: 22px; border-radius: 6px; background: var(--tc-bg); color: var(--tc-ink-2); font-weight: 700; font-size: 12px; display: inline-flex; align-items: center; justify-content: center; }
.egrid-level__label { font-size: 12.5px; color: var(--tc-ink-2); line-height: 1.45; }
.egrid-level__score { font-size: 12px; font-weight: 700; color: var(--tc-ink); text-align: right; }

.escale { list-style: none; margin: 0; padding: 0; }
.escale li { display: flex; align-items: baseline; gap: 10px; padding: 6px 0; border-top: 1px solid var(--tc-border); }
.escale li:first-child { border-top: none; }
.escale__range { min-width: 92px; font-size: 12px; font-weight: 600; color: var(--tc-ink-3); font-variant-numeric: tabular-nums; }
.escale__label { font-size: 13px; font-weight: 700; color: var(--tc-ink); }

/* ── Campagnes d'évaluation ───────────────────────────────────────────────
   La ligne de campagne est cliquable dans son entier : la cible est la
   campagne, pas un lien perdu au bout de la ligne. */
.ecamp-list { display: flex; flex-direction: column; }
.ecamp { display: flex; align-items: center; gap: 16px; padding: 14px 0; border-top: 1px solid var(--tc-border); text-decoration: none; color: inherit; }
.ecamp:first-child { border-top: none; padding-top: 0; }
.ecamp:hover { background: var(--tc-bg); }
.ecamp__main { flex: 1 1 auto; min-width: 0; }
.ecamp__title { font-weight: 700; font-size: 13.5px; color: var(--tc-ink); }
.ecamp__meta { font-size: 12px; color: var(--tc-ink-4); margin-top: 2px; }
.ecamp__reason { font-size: 12px; color: var(--tc-accent-ink); margin-top: 4px; }
.ecamp__side { flex: 0 0 150px; text-align: right; }
.ecamp__score { font-weight: 700; font-size: 17px; color: var(--tc-ink); font-variant-numeric: tabular-nums; }
.ecamp__score span { font-size: 12px; font-weight: 600; color: var(--tc-ink-4); }
.ecamp__appreciation { font-size: 11.5px; color: var(--tc-ink-4); margin-top: 2px; }
.ecamp__progress { height: 6px; border-radius: 999px; background: var(--tc-border); overflow: hidden; }
.ecamp__progress span { display: block; height: 100%; border-radius: 999px; background: var(--tc-red); }

/* Niveaux d'une rubrique : on note en lisant une phrase, pas un chiffre —
   le libellé occupe donc la largeur, et toute la ligne est cliquable. */
.elevels { display: flex; flex-direction: column; gap: 4px; }
.elevel { position: relative; display: grid; grid-template-columns: 26px minmax(0, 1fr) 46px; gap: 10px; align-items: baseline; padding: 7px 10px; border: 1px solid transparent; border-radius: 8px; cursor: pointer; }
.elevel:hover { background: var(--tc-bg); }
.elevel input { position: absolute; opacity: 0; pointer-events: none; }
.elevel__points { width: 26px; height: 22px; border-radius: 6px; background: var(--tc-bg); color: var(--tc-ink-2); font-weight: 700; font-size: 12px; display: inline-flex; align-items: center; justify-content: center; }
.elevel__label { font-size: 12.5px; color: var(--tc-ink-2); line-height: 1.45; }
.elevel__score { font-size: 12px; font-weight: 700; color: var(--tc-ink-4); text-align: right; font-variant-numeric: tabular-nums; }
/* Deux sélecteurs pour le même état : `is-chosen` vient du serveur, `:has()`
   suit le clic. Sans le second, cocher ne changeait rien à l'écran tant qu'on
   n'avait pas enregistré — on croyait la sélection impossible. */
.elevel.is-chosen,
.elevel:has(input:checked) { border-color: var(--tc-red); background: var(--tc-red-subtle); }
.elevel.is-chosen .elevel__points,
.elevel:has(input:checked) .elevel__points { background: var(--tc-red); color: var(--tc-on-primary); }
.elevel.is-chosen .elevel__label,
.elevel:has(input:checked) .elevel__label { color: var(--tc-ink); font-weight: 600; }
.elevel.is-chosen .elevel__score,
.elevel:has(input:checked) .elevel__score { color: var(--tc-accent-ink); }
.elevel:focus-within { outline: 2px solid var(--tc-red); outline-offset: 1px; }
.elevel.is-locked { cursor: default; }
.elevel.is-locked:hover { background: none; }
.elevel.is-locked.is-chosen:hover { background: var(--tc-red-subtle); }
.egrid-rubric legend.egrid-rubric__head { float: left; width: 100%; }

.eresult { display: flex; align-items: baseline; gap: 6px; }
.eresult__score { font-weight: 800; font-size: 30px; line-height: 1; color: var(--tc-ink); font-variant-numeric: tabular-nums; }
.eresult__max { font-size: 12.5px; color: var(--tc-ink-4); }
.eresult__appreciation { font-weight: 700; font-size: 14px; color: var(--tc-accent-ink); margin-top: 6px; }

.ehistory { list-style: none; margin: 0; padding: 0; }
.ehistory li { display: flex; gap: 10px; padding: 8px 0; border-top: 1px solid var(--tc-border); }
.ehistory li:first-child { border-top: none; }
.ehistory__dot { flex: none; width: 9px; height: 9px; border-radius: 999px; margin-top: 5px; background: currentColor; }
.ehistory__label { font-weight: 600; font-size: 12.5px; color: var(--tc-ink); }
.ehistory__meta { font-size: 11.5px; color: var(--tc-ink-4); margin-top: 1px; }
.ehistory__reason { font-size: 12px; color: var(--tc-ink-3); margin-top: 4px; font-style: italic; }

/* Courrier d'évaluation : présenté comme il sera imprimé — on signe ce qu'on lit. */
.eletter { font-size: 13.5px; line-height: 1.7; color: var(--tc-ink-2); }

.esignpad { position: relative; border: 1px dashed var(--tc-border); border-radius: 8px; background: var(--tc-bg); }
.esignpad canvas { display: block; width: 100%; height: 120px; touch-action: none; cursor: crosshair; }
.esignpad__clear { position: absolute; top: 6px; right: 8px; border: none; background: none; font-size: 11.5px; color: var(--tc-ink-4); cursor: pointer; }
.esignature { max-width: 100%; max-height: 80px; }


/* ── Mes évaluations : compteurs et parcours ──────────────────────────────
   Reprend la maquette d'origine. Le parcours en trois étapes répond à la seule
   question qu'on se pose en ouvrant l'écran : où en est mon évaluation, et qui
   la tient ? */
.ekpi-grid { display: grid; grid-template-columns: 1fr; gap: 16px; margin-bottom: 18px; }
@media (min-width: 768px) { .ekpi-grid { grid-template-columns: repeat(3, 1fr); } }
.ekpi { background: #fff; border: 1px solid var(--tc-border); border-radius: 14px; padding: 20px; display: flex; align-items: center; gap: 14px; }
.ekpi__icon { width: 42px; height: 42px; border-radius: 11px; display: inline-flex; align-items: center; justify-content: center; flex: none; }
.ekpi--done { background: #E7F5EC; color: #1E7E34; }
.ekpi--running { background: #EEE9FB; color: #6C4BD8; }
.ekpi--waiting { background: #FEF3E2; color: #B9770E; }
.ekpi__label { font-size: 10.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--tc-ink-4); margin-bottom: 3px; }
.ekpi__value { font-size: 26px; font-weight: 700; line-height: 1; letter-spacing: -.02em; color: var(--tc-ink); }

.ecard { background: #fff; border: 1px solid var(--tc-border); border-radius: 14px; overflow: hidden; }
.ecard__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 18px 22px; border-bottom: 1px solid var(--tc-border-soft, #F1F3F5); flex-wrap: wrap; }
.ecard__title { font-size: 16px; font-weight: 700; color: var(--tc-ink); }
.ecard__period { display: flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 500; color: var(--tc-ink-3); margin-top: 3px; }
.ecard__alert { display: flex; align-items: flex-start; gap: 8px; margin: 14px 22px 0; padding: 10px 12px; background: var(--tc-red-subtle); border-radius: 8px; font-size: 12.5px; color: var(--tc-accent-ink); }
.ecard__foot { display: flex; justify-content: flex-end; gap: 10px; padding: 16px 22px 20px; border-top: 1px solid var(--tc-border-soft, #F1F3F5); }
.ecard__foot .btn-tc, .ecard__foot .btn-tc-outline { display: inline-flex; align-items: center; gap: 7px; }

.esteps { display: flex; padding: 24px 22px 18px; }
.estep { flex: 1; text-align: center; padding: 0 6px; min-width: 0; }
.estep__rail { display: flex; align-items: center; }
.estep__line { flex: 1; height: 2px; background: var(--tc-border); }
.estep__line.is-done { background: var(--tc-red); }
.estep__line.is-blank { background: transparent; }
.estep__dot { width: 34px; height: 34px; border-radius: 50%; flex: none; display: flex; align-items: center; justify-content: center; background: var(--tc-bg); color: var(--tc-ink-4); border: 2px solid var(--tc-border); }
.estep.is-done .estep__dot { background: var(--tc-red); color: var(--tc-on-primary); border-color: var(--tc-red); }
.estep__label { font-size: 12.5px; font-weight: 700; color: var(--tc-ink); margin-top: 10px; }
.estep__hint { font-size: 11px; color: var(--tc-ink-3); margin-top: 3px; }
.estep__badge { display: inline-block; font-size: 10px; font-weight: 500; color: var(--tc-ink-3); background: var(--tc-bg); padding: 3px 9px; border-radius: 6px; margin-top: 7px; }

@media (max-width: 767px) {
    .esteps { flex-direction: column; gap: 18px; }
    .estep__line { display: none; }
    .estep__rail { justify-content: center; }
}

/* Les deux notes, côte à côte : c'est l'écart qui se discute en entretien. */
.escores { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.escore { background: var(--tc-bg); border-radius: 10px; padding: 12px 14px; }
.escore__label { font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--tc-ink-4); margin-bottom: 4px; }
.escore__value { font-size: 22px; font-weight: 800; color: var(--tc-ink); line-height: 1; font-variant-numeric: tabular-nums; }
.escore__value span { font-size: 12px; font-weight: 600; color: var(--tc-ink-4); }
.escore__value--empty { font-size: 13px; font-weight: 600; color: var(--tc-ink-4); }
.escore__gap { font-size: 12px; font-weight: 600; color: var(--tc-ink-3); margin: 10px 0 0; }
.escore__gap.is-up { color: var(--tc-green-ink); }
.escore__gap.is-down { color: var(--tc-danger-ink); }

/* Rappel de la note du salarié, au-dessus de la grille du responsable. */
.egrid-rubric__self { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12.5px; color: var(--tc-ink-2); margin: 0 0 8px; }
.egrid-rubric__gap { font-size: 11.5px; color: var(--tc-ink-4); margin: 6px 0 0; font-style: italic; }

/* Total vivant d'une grille : savoir où l'on en est sans avoir à enregistrer. */
.etally { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; background: #fff; border: 1px solid var(--tc-border); border-radius: 12px; padding: 14px 18px; margin-bottom: 16px; position: sticky; top: 0; z-index: 3; }
.etally__label { font-size: 10.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--tc-ink-4); }
.etally__value { font-size: 22px; font-weight: 800; color: var(--tc-ink); line-height: 1.1; font-variant-numeric: tabular-nums; }
.etally__max { font-size: 13px; font-weight: 600; color: var(--tc-ink-4); }
.etally__remaining { font-size: 12.5px; font-weight: 600; color: var(--tc-accent-ink); }

/* Récapitulatif d'une rubrique, en bout de son en-tête. */
.egrid-rubric__tally { margin-left: auto; font-size: 12px; font-weight: 700; color: var(--tc-ink-4); font-variant-numeric: tabular-nums; }
.egrid-rubric__tally.is-rated { color: var(--tc-accent-ink); }

@media (max-width: 575px) {
    .elevel { grid-template-columns: 26px minmax(0, 1fr); }
    .elevel__score { grid-column: 2; text-align: left; font-size: 11px; }
    .egrid-rubric__head { gap: 6px; }
    .egrid-rubric__tally { margin-left: 0; }
    .escores { grid-template-columns: 1fr; }
    .etally { position: static; }
}

/* ── Édition du courrier, avec son aperçu en regard ───────────────────────
   On écrit en voyant ce qu'on signe : l'aperçu reprend la mise en page du PDF,
   et suit la frappe. */
.eletter-edit { display: grid; grid-template-columns: 1fr; gap: 20px; align-items: start; }
@media (min-width: 1200px) { .eletter-edit { grid-template-columns: 1fr 1fr; } }

.eassist { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.eassist .btn-tc { display: inline-flex; align-items: center; gap: 8px; }

.eletter-preview { position: sticky; top: 0; }
.eletter-preview__bar { display: flex; align-items: baseline; gap: 10px; margin-bottom: 8px; }
.eletter-preview__title { font-size: 10.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--tc-ink-4); }
.eletter-preview__hint { font-size: 11.5px; color: var(--tc-ink-4); }

.eletter-paper { background: #fff; border: 1px solid var(--tc-border); border-radius: 10px; padding: 30px 34px; box-shadow: 0 1px 3px rgba(0, 0, 0, .05); max-height: calc(100vh - 190px); overflow-y: auto; }

/* Pied de page du courrier : le PDF le fixe en bas de chaque page, l'aperçu le
   pose simplement à la fin. */
.ltr-foot { margin-top: 26px; padding-top: 10px; border-top: 2px solid #E9ECEF; text-align: center; font-size: 8.5px; color: #333; line-height: 1.4; }
.ltr-foot__plane { width: 100%; max-height: 26px; margin-bottom: 6px; }
.ltr-foot__line { font-weight: 700; }

@media (max-width: 1199px) {
    .eletter-preview { position: static; }
    .eletter-paper { max-height: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MENUS DÉROULANTS SUR PETIT ÉCRAN

   Sous 576px, les menus s'alignent sur le bord de la BARRE plutôt que sur leur
   déclencheur. Ancré au bouton, un menu ouvert depuis le milieu de la barre
   déborde de l'écran : `right: 0` le fait grandir vers la gauche, sans rien
   pour l'arrêter. `position: static` sur l'enveloppe rend la barre — qui est
   `sticky`, donc positionnée — bloc conteneur du menu ; il ne peut alors plus
   sortir du cadre, quel que soit le bouton qui l'ouvre.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 575.98px) {
    .app-usermenu { position: static; }
    .app-menu { top: 56px; right: 12px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   REGISTRE DU COURRIER

   Valeurs reprises de la maquette (« EasyCH V3 — Espace RH »), promues en
   classes plutôt que recopiées en styles inline dans le gabarit : la même
   pastille, le même segment et la même grille servent aux trois sens du
   courrier, et un jour aux permanences.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Indicateurs de tête */
.mail-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-bottom: 20px; }
@media (max-width: 991.98px) { .mail-kpis { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 575.98px) { .mail-kpis { grid-template-columns: 1fr; } }
.mail-kpi { background: #fff; border: 1px solid var(--tc-border); border-radius: 12px; padding: 16px 18px; }
.mail-kpi__label { font: 600 10.5px/1 var(--tc-font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--tc-ink-4); margin-bottom: 8px; }
.mail-kpi__value { font: 700 24px Inter, sans-serif; color: var(--tc-ink); }
.mail-kpi__sub { font: 500 12px Inter, sans-serif; color: var(--tc-ink-3); margin-top: 3px; }

/* Bascules de type dans la modale d'enregistrement */
.mail-seg { display: inline-flex; align-items: center; padding: 8px 15px; font: 600 13px Inter, sans-serif; color: var(--tc-ink-3); background: #fff; border: 1px solid var(--tc-border); border-radius: 8px; cursor: pointer; text-decoration: none; }
.mail-seg:hover { color: var(--tc-ink); text-decoration: none; }
.mail-seg.is-active { color: var(--tc-accent-ink); background: var(--tc-red-subtle); border-color: var(--tc-red-border); }
.mail-seg--grow { flex: 1; justify-content: center; padding: 10px; border-radius: 9px; }
.mail-seg--small { flex: 1; justify-content: center; padding: 7px; font-size: 12px; border-radius: 7px; }

/* Tableau du registre : une grille, pour que l'en-tête et les lignes
   partagent EXACTEMENT les mêmes colonnes. */
.mail-row { display: grid; grid-template-columns: 1.2fr .8fr 2.2fr 1.9fr 1.2fr 70px; gap: 0; align-items: center; padding: 14px 20px; border-bottom: 1px solid #F4F5F7; font: 500 13px Inter, sans-serif; color: var(--tc-ink); }
.mail-row--head { font: 600 10.5px/1 var(--tc-font-mono); letter-spacing: .05em; text-transform: uppercase; color: var(--tc-ink-4); padding: 13px 20px; background: #FAFBFC; border-bottom: 1px solid #F1F3F5; }
.mail-row__chrono { font: 600 12.5px/1 var(--tc-font-mono); color: var(--tc-ink-2); }

.mail-row a.mail-row__chrono:hover { color: var(--tc-accent-ink); }
/* La date vit sous le n° chrono : elle mangeait une colonne entière pour six
   caractères, au détriment de l'objet qu'on lit vraiment. */
.mail-row__date { font: 500 11.5px Inter, sans-serif; color: var(--tc-ink-4); margin-top: 3px; }
/* De qui vers qui, sur deux lignes : le type ne suffit pas à le deviner. */
.mail-row__parties { font: 500 12.5px Inter, sans-serif; color: var(--tc-ink-2); padding-right: 12px; }
.mail-row__parties b { font-weight: 600; color: var(--tc-ink); }
/* Progression des accusés — la jauge d'une note de service. */
.mail-row__ack { font: 500 11.5px Inter, sans-serif; color: var(--tc-ink-4); margin-top: 4px; }

/* Type de courrier : trois tons, pour repérer d'un coup d'œil ce qui entre,
   ce qui sort et ce qui circule à l'intérieur. */
.mail-type { display: inline-flex; align-items: center; padding: 3px 9px; border-radius: 999px; font: 600 10.5px Inter, sans-serif; letter-spacing: .02em; }
.mail-type--inbound { color: #1E7E34; background: #E8F6EC; }
.mail-type--outbound { color: #1B5FAF; background: #E9F1FB; }
.mail-type--internal { color: #8A5A00; background: #FDF3E2; }

/* L'œil : voir le détail d'un courrier. */
.mail-eye { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 8px; color: var(--tc-ink-3); border: 1px solid var(--tc-border); background: #fff; }
.mail-eye:hover { color: var(--tc-accent-ink); border-color: var(--tc-red-border); background: var(--tc-red-subtle); }

/* « Tout le personnel » — le geste d'une note de service. */
.mail-all { display: inline-flex; align-items: center; gap: 6px; font: 500 12px Inter, sans-serif; color: var(--tc-ink-3); margin: 0 0 6px; cursor: pointer; }

/* ── Fiche d'un courrier ── */
.mail-sheet { background: #fff; border: 1px solid var(--tc-border); border-radius: 14px; padding: 22px 24px; display: flex; flex-direction: column; gap: 18px; }
.mail-back { display: inline-flex; align-items: center; gap: 5px; font: 600 12.5px Inter, sans-serif; color: var(--tc-ink-3); text-decoration: none; }
.mail-back:hover { color: var(--tc-accent-ink); }
.mail-sheet__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.mail-sheet__ref { font: 700 13px var(--tc-font-mono); color: var(--tc-ink-2); }
.mail-sheet__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; border-top: 1px solid #F1F3F5; padding-top: 16px; }
.mail-sheet__value { font: 500 13.5px Inter, sans-serif; color: var(--tc-ink); }
.mail-sheet__notes { font: 500 13px Inter, sans-serif; color: var(--tc-ink-2); margin: 0; }
/* Un accusé par destinataire : c'est là qu'on voit qui se fait attendre. */
.mail-ack-list { display: flex; flex-direction: column; border: 1px solid var(--tc-border); border-radius: 11px; overflow: hidden; }
.mail-ack { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 14px; border-bottom: 1px solid #F4F5F7; }
.mail-ack:last-child { border-bottom: none; }
.mail-ack__name { font: 500 13px Inter, sans-serif; color: var(--tc-ink); }
/* Trombone : le scan se relit depuis la liste, sans ouvrir de fiche. */
.mail-row__clip { display: inline-flex; margin-left: 4px; color: var(--tc-ink-4); vertical-align: middle; }
.mail-row__clip:hover { color: var(--tc-accent-ink); }
@media (max-width: 767.98px) {
    /* Sur téléphone la grille se déplie : six colonnes de 60px ne se lisent pas. */
    .mail-row, .mail-row--head { grid-template-columns: 1fr 1fr; row-gap: 4px; }
    .mail-row--head { display: none; }
}

/* Carte de la liste, et ses barres — segments, filtres, pied de page.
   La maquette les cale toutes sur 14px 18px : une seule classe, trois emplois. */
.mail-card { background: #fff; border: 1px solid var(--tc-border); border-radius: 14px; overflow: hidden; }
.mail-card__bar { padding: 14px 18px; border-bottom: 1px solid #F1F3F5; }
.mail-card__foot { padding: 15px 20px; border-top: 1px solid #F1F3F5; }

/* Champ de recherche de la barre de filtres */
.mail-search { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 200px; background: var(--tc-bg); border: 1px solid var(--tc-border); border-radius: 8px; padding: 9px 12px; margin: 0; }
.mail-search svg { flex: none; color: var(--tc-ink-4); }
.mail-search input { border: none; background: none; outline: none; font: 500 13px Inter, sans-serif; color: var(--tc-ink); width: 100%; }
.mail-search input::placeholder { color: var(--tc-ink-4); }

/* N° chrono annoncé dans la modale — un APERÇU, d'où le ton discret. */
.mail-modal__chrono { font: 500 12px Inter, sans-serif; color: var(--tc-ink-3); margin-top: 2px; }
.mail-modal__chrono-value { font: 600 12px var(--tc-font-mono); color: var(--tc-accent-ink); }

/* Zone de dépôt du PDF numérisé */
.mail-drop { display: block; border: 1.5px dashed #D7DCE1; border-radius: 11px; padding: 18px; text-align: center; cursor: pointer; color: var(--tc-ink-4); margin: 0; }
.mail-drop:hover { border-color: var(--tc-red); }
.mail-drop:has(input:focus-visible) { outline: 2px solid var(--tc-red); outline-offset: 2px; }
.mail-drop__title { font: 600 12.5px Inter, sans-serif; color: var(--tc-ink-2); }
.mail-drop__hint { font: 500 11px Inter, sans-serif; color: var(--tc-ink-4); margin-top: 2px; }

/* Encart « courrier confidentiel » */
.mail-flag { display: flex; align-items: flex-start; gap: 11px; padding: 13px 15px; background: #FAFBFC; border: 1px solid var(--tc-border); border-radius: 10px; cursor: pointer; }
.mail-flag input { width: 16px; height: 16px; margin-top: 1px; accent-color: var(--tc-red); }
.mail-flag__title { font: 600 13px Inter, sans-serif; color: var(--tc-ink); }
.mail-flag__hint { font: 500 11.5px Inter, sans-serif; color: var(--tc-ink-3); margin-top: 1px; }

/* Étiquette de champ, façon maquette */
.mail-label { font: 600 11px/1 var(--tc-font-mono); letter-spacing: .05em; text-transform: uppercase; color: var(--tc-ink-3); margin-bottom: 7px; display: block; }
.mail-input { width: 100%; padding: 9px 11px; font: 500 13px Inter, sans-serif; color: var(--tc-ink); background: #fff; border: 1px solid #DEE2E6; border-radius: 8px; box-sizing: border-box; }
.mail-input:focus { outline: none; border-color: var(--tc-red); }
/* Les filtres sont d'un cran plus petits que les champs de saisie. */
.mail-input--filter { width: auto; padding: 9px 12px; font-size: 12.5px; }

/* Pagination */
/* Pagination — LA MÊME PARTOUT (templates/_partials/pagination.html.twig). */
.pager { display: inline-flex; gap: 4px; }
.pager__link { width: 34px; height: 34px; border-radius: 8px; border: 1px solid #DEE2E6; background: #fff; color: var(--tc-ink-2); cursor: pointer; font: 600 13px Inter, sans-serif; display: inline-flex; align-items: center; justify-content: center; text-decoration: none; }
.pager__link:hover { background: var(--tc-bg); text-decoration: none; }
.pager__link.is-active { border: none; background: var(--tc-red); color: var(--tc-on-primary); }
.pager__link.is-disabled { color: var(--tc-ink-4); pointer-events: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   TIMELINE DE VALIDATION (détail d'une demande d'absence)

   Un rail vertical, une pastille par étape, un trait qui relie. Le trait ne
   descend PAS sous la dernière étape : un rail qui continue dans le vide
   laisserait croire qu'une étape est attendue alors que le parcours est clos.
   ═══════════════════════════════════════════════════════════════════════════ */
.ltimeline { display: flex; flex-direction: column; }
.ltimeline__item { display: flex; gap: 12px; }
.ltimeline__rail { display: flex; flex-direction: column; align-items: center; flex: none; width: 14px; }
.ltimeline__dot { width: 11px; height: 11px; border-radius: 50%; background: currentColor; margin-top: 4px; flex: none; }
.ltimeline__line { width: 2px; flex: 1; background: #EFF1F3; min-height: 20px; margin: 4px 0; }
.ltimeline__body { padding-bottom: 18px; min-width: 0; }
.ltimeline__title { font: 600 13.5px Inter, sans-serif; color: var(--tc-ink); }
.ltimeline__meta { font: 500 12.5px Inter, sans-serif; color: var(--tc-ink-2); margin-top: 2px; }
.ltimeline__date { font: 500 11.5px/1.4 var(--tc-font-mono); color: var(--tc-ink-4); margin-top: 3px; }
.ltimeline__comment { font: 400 12.5px Inter, sans-serif; color: var(--tc-ink-2); margin-top: 6px; padding: 8px 10px; background: var(--tc-bg); border-radius: 8px; }

/* Le dernier élément ne réserve pas d'espace pour un trait absent. */
.ltimeline__item:last-child .ltimeline__body { padding-bottom: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   ERREURS DE CHAMP

   Rendues par templates/form/app_theme.html.twig, sous le champ fautif. Les
   écrans composent leur mise en page à la main et n'appellent que
   `form_widget()` : sans le thème, aucune erreur ne s'affichait.
   ═══════════════════════════════════════════════════════════════════════════ */
.field-errors { margin-top: 6px; }
.field-error { display: flex; align-items: center; gap: 5px; font: 600 11.5px Inter, sans-serif; color: var(--tc-danger-ink); margin-top: 3px; }
.field-error svg { flex: none; }

/* Le champ fautif se voit AVANT qu'on lise le message : le cadre rouge situe
   l'erreur, le texte l'explique. */
.is-invalid,
input.is-invalid, select.is-invalid, textarea.is-invalid { border-color: var(--tc-danger-ink) !important; }
.is-invalid:focus { outline: none; border-color: var(--tc-danger-ink) !important; box-shadow: 0 0 0 3px rgba(var(--bs-danger-rgb), .12); }

/* ═══════════════════════════════════════════════════════════════════════════
   MODALE « NOUVEAU JOUR FÉRIÉ »

   Valeurs relevées sur la maquette. Le sélecteur de récurrence est un groupe de
   boutons radio déguisés en segments : trois choix seulement, tous visibles,
   plutôt qu'une liste déroulante qu'il faut ouvrir pour savoir ce qu'elle
   contient — et chacun change la suite du formulaire.
   ═══════════════════════════════════════════════════════════════════════════ */
.hol-label { display: block; font: 600 13px Inter, sans-serif; color: var(--tc-ink-2); margin-bottom: 7px; }
.hol-label__soft { font-weight: 500; color: var(--tc-ink-4); }

.hol-input { width: 100%; padding: 11px 13px; font: 500 13.5px Inter, sans-serif; color: var(--tc-ink); background: var(--tc-surface); border: 1px solid var(--tc-border); border-radius: 9px; box-sizing: border-box; }
.hol-input::placeholder { color: var(--tc-ink-4); }
.hol-input:focus { outline: none; border-color: var(--tc-red); box-shadow: 0 0 0 3px rgba(var(--bs-primary-rgb), .10); }

.hol-segments { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
/* Le bouton radio lui-même est masqué : c'est le segment qui le représente.
   Masqué ICI et non par une classe utilitaire empruntée ailleurs — le composant
   doit tenir seul, sans dépendre de ce qu'un autre fichier veut bien fournir. */
.hol-segment input[type="radio"] { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.hol-segment { position: relative; display: flex; align-items: center; justify-content: center; padding: 12px 8px; font: 600 13px Inter, sans-serif; color: var(--tc-ink-3); background: #fff; border: 1px solid var(--tc-border); border-radius: 9px; cursor: pointer; text-align: center; }
.hol-segment:hover { background: var(--tc-bg); }
.hol-segment.is-active,
.hol-segment:has(input:checked) { color: var(--tc-accent-ink); background: var(--tc-red-subtle); border-color: var(--tc-red-border); }
.hol-segment:has(input:focus-visible) { outline: 2px solid var(--tc-red); outline-offset: 2px; }

/* La conséquence du choix : discrète, mais toujours présente. */
.hol-hint { font: 500 12px Inter, sans-serif; color: var(--tc-ink-3); margin-top: 8px; min-height: 17px; }

.hol-dates { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 18px; }

/* Encart d'avertissement — ambre, comme dans la maquette. */
.hol-notice { display: flex; align-items: flex-start; gap: 9px; margin-top: 18px; padding: 13px 15px; background: #FEF9EE; border: 1px solid #F6E3BE; border-radius: 10px; font: 500 12px Inter, sans-serif; color: #8A5A08; line-height: 1.55; }
.hol-notice svg { flex: none; margin-top: 1px; color: #C99A2E; }
.hol-notice strong { font-weight: 700; }

@media (max-width: 575.98px) {
    /* Trois segments côte à côte deviennent illisibles sous 360px, et deux
       colonnes de dates n'y tiennent pas davantage. */
    .hol-segments { grid-template-columns: 1fr; }
    .hol-dates { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MESSAGERIE INTERNE

   Valeurs reprises de la maquette (« EasyCH V3 — Espace RH »). L'écran est le
   MÊME pour le Capital Humain et pour le salarié : une seule feuille de style,
   comme un seul gabarit.

   Trois colonnes — rail, liste, lecture — dans une hauteur FIXE : chaque volet
   défile chez lui. Une page qui défile en entier ferait disparaître le rail dès
   qu'on descend dans un message long.
   ═══════════════════════════════════════════════════════════════════════════ */
/* La coque ne DEVINE plus sa hauteur.
   Un `calc(100vh - 128px)` supposait connaître tout ce qui la précède —
   en-tête, sous-onglets, titre de page — et se trompait de cent pixels : les
   boutons du fil tombaient sous la ligne de flottaison. Elle prend maintenant
   ce qui RESTE, par une chaîne flex qui remonte jusqu'au panneau de contenu.
   Voir la règle `.app-content:has(.msg-page)` plus bas. */
.msg-shell { display: grid; grid-template-columns: 230px 350px 1fr; min-height: 420px; background: #fff; border: 1px solid var(--tc-border); border-radius: 14px; overflow: hidden; }

/* ── Rail : composer, dossiers, libellés ── */
.msg-rail { border-right: 1px solid #F1F3F5; display: flex; flex-direction: column; padding: 16px 12px; gap: 4px; overflow-y: auto; min-height: 0; }
.msg-rail__title { font: 600 9.5px/1 var(--tc-font-mono); letter-spacing: .12em; text-transform: uppercase; color: var(--tc-ink-4); padding: 16px 12px 8px; }

.msg-compose-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; padding: 11px; font: 600 13px Inter, sans-serif; color: var(--tc-on-primary); background: var(--tc-red); border: none; border-radius: 10px; cursor: pointer; margin-bottom: 10px; }
.msg-compose-btn:hover { background: var(--tc-red-hover); color: #fff; }

.msg-folder { display: flex; align-items: center; gap: 11px; padding: 9px 12px; border: none; border-radius: 9px; cursor: pointer; text-align: left; width: 100%; font: 600 13px Inter, sans-serif; background: none; color: var(--tc-ink-2); text-decoration: none; }
.msg-folder:hover { background: var(--tc-bg); color: var(--tc-ink-2); text-decoration: none; }
.msg-folder.is-active { background: var(--tc-red-subtle); color: var(--tc-accent-ink); }
.msg-folder__label { flex: 1; }
.msg-folder__count { font: 700 11px Inter, sans-serif; color: var(--tc-accent-ink); }
.msg-folder svg { flex: none; }

.msg-tag { display: flex; align-items: center; gap: 11px; padding: 7px 12px; font: 500 12.5px Inter, sans-serif; color: var(--tc-ink-2); }
.msg-tag__dot { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.msg-tag__dot--ch { background: var(--tc-red); }
.msg-tag__dot--management { background: #2A6FDB; }
.msg-tag__dot--team { background: var(--tc-green-ink); }

/* État de la liaison temps réel : un point et un mot, au pied du rail.
   Vert quand le hub est joint, gris sinon. Une panne de temps réel est
   silencieuse par nature — celle-ci se voit. */

/* Réglage des accusés de lecture — au pied du rail, là où il ne coupe rien. */
/* `margin-top: auto` : le réglage du son reste collé au bas du rail, que les libellés soient deux ou dix. */
.msg-receipts { margin-top: auto; padding: 8px 10px 4px; border-top: 1px solid #F1F3F5; display: flex; align-items: center; gap: 9px; }
.msg-receipts__label { flex: 1; font: 500 12px Inter, sans-serif; color: var(--tc-ink-2); }
.msg-switch { width: 38px; height: 22px; border-radius: 999px; border: none; background: #D7DCE1; cursor: pointer; position: relative; flex: none; padding: 0; }
.msg-switch[aria-pressed="true"] { background: var(--tc-red); }
.msg-switch__knob { position: absolute; top: 3px; left: 3px; width: 16px; height: 16px; border-radius: 50%; background: #fff; transition: left .12s; }
.msg-switch[aria-pressed="true"] .msg-switch__knob { left: 19px; }

/* ── Liste des messages ── */
.msg-list { border-right: 1px solid #F1F3F5; display: flex; flex-direction: column; overflow: hidden; }
.msg-list__head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 15px 18px; border-bottom: 1px solid #F1F3F5; font: 700 15px Inter, sans-serif; color: var(--tc-ink); }
.msg-list__search { padding: 12px 16px; border-bottom: 1px solid #F1F3F5; }
.msg-list__scroll { flex: 1; overflow-y: auto; min-height: 0; }

.msg-search { display: flex; align-items: center; gap: 8px; background: var(--tc-bg); border: 1px solid var(--tc-border); border-radius: 9px; padding: 8px 11px; }
.msg-search svg { flex: none; color: var(--tc-ink-4); }
.msg-search input { border: none; background: none; outline: none; font: 500 12.5px Inter, sans-serif; color: var(--tc-ink); width: 100%; }
.msg-search input::placeholder { color: var(--tc-ink-4); }

/* LU / NON LU, à la manière des messageries : le non-lu est en gras sur fond
   blanc, le lu retombe sur un gris discret. C'est l'inverse de l'intuition —
   on croit devoir souligner le non-lu d'une couleur — mais c'est ce que l'œil
   attend, et une boîte pleine de messages lus doit se fondre pour que le reste
   ressorte. */
.msg-item { display: flex; gap: 11px; padding: 13px 16px; border-bottom: 1px solid var(--tc-bg); background: #fff; text-decoration: none; color: inherit; }
.msg-item.is-read { background: #F6F8FA; }
.msg-item:hover { background: #EEF1F4; color: inherit; text-decoration: none; }
.msg-item.is-active, .msg-item.is-active:hover { background: var(--tc-red-subtle); }
/* Le point rouge du non-lu, comme sur la maquette. */
.msg-item.is-unread .msg-item__from::before { content: ''; display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--tc-red); margin-right: 7px; vertical-align: middle; }
.msg-item__avatar { width: 36px; height: 36px; border-radius: 50%; background: var(--tc-ink); color: #fff; display: flex; align-items: center; justify-content: center; font: 700 11px Inter, sans-serif; flex: none; }
.msg-item__link { display: flex; gap: 11px; flex: 1; min-width: 0; text-decoration: none; color: inherit; }
.msg-item__link:hover { text-decoration: none; color: inherit; }
.msg-item__body { flex: 1; min-width: 0; }
.msg-item__line { display: flex; align-items: center; gap: 8px; }
.msg-item__line--mid { gap: 7px; margin: 2px 0; }
.msg-item__line--foot { gap: 5px; min-width: 0; }
.msg-item__from { font: 600 13px Inter, sans-serif; color: var(--tc-ink); flex: 1; }
.msg-item__date { font: 500 11px Inter, sans-serif; color: var(--tc-ink-4); flex: none; }
.msg-item__subject { font: 500 12.5px Inter, sans-serif; color: var(--tc-ink); min-width: 0; }
.msg-item__snippet { font: 400 11.5px Inter, sans-serif; color: var(--tc-ink-4); }
.msg-item.is-unread .msg-item__from { font-weight: 700; }
.msg-item.is-unread .msg-item__subject { font-weight: 600; }
/* Le nom, l'objet et l'extrait se coupent plutôt que d'élargir la colonne. */
.msg-item__from, .msg-item__subject, .msg-item__snippet { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.msg-action { flex: none; align-self: flex-start; margin: 0; }
.msg-star { background: none; border: none; cursor: pointer; padding: 0; flex: none; align-self: flex-start; color: #D7DCE1; }

/* ── Brouillon dans la liste ──
   Même ligne qu'un fil ; seuls le crayon et l'objet en italique le signalent.
   La CORBEILLE n'apparaît qu'au survol : une suppression toujours visible sur
   chaque ligne invite à la faute, et jeter un brouillon ne se rattrape pas. */
.msg-item__avatar--draft { background: var(--tc-bg); color: var(--tc-ink-3); }
.msg-item__subject--untitled { font-style: italic; color: var(--tc-ink-4); }
.msg-action--drop { opacity: 0; transition: opacity .12s; }
.msg-item--draft:hover .msg-action--drop,
.msg-action--drop:focus-within { opacity: 1; }
.msg-drop { background: none; border: none; cursor: pointer; padding: 2px; color: var(--tc-ink-4); display: flex; }
.msg-drop:hover { color: var(--tc-accent-ink); }

/* Les pièces jointes d'un message, alignées sous son corps. */
.msg-files { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 0 41px; }
.msg-star.is-on { color: #F0B429; }

.msg-chip { display: inline-flex; align-items: center; font: 600 9px Inter, sans-serif; padding: 2px 7px; border-radius: 999px; flex: none; }
.msg-chip--lg { font-size: 10px; padding: 3px 9px; }

/* Coches d'accusé de lecture : la seconde chevauche la première, comme sur la maquette. */
.msg-receipt { display: inline-flex; align-items: center; gap: 3px; flex: none; font: 600 10px Inter, sans-serif; color: var(--tc-ink-4); }
.msg-receipt--lg { font-size: 11px; margin-top: 3px; }
.msg-receipt.is-read { color: var(--tc-accent-ink); }
.msg-receipt svg + svg { margin-left: -8px; }

/* ── Volet de lecture ── */
.msg-read { display: flex; flex-direction: column; overflow: hidden; }
.msg-read__head { padding: 20px 26px; border-bottom: 1px solid #F1F3F5; }
.msg-read__title { font: 700 19px Inter, sans-serif; letter-spacing: -.01em; color: var(--tc-ink); }
.msg-read__icon { width: 34px; height: 34px; border-radius: 8px; border: none; background: none; cursor: pointer; color: var(--tc-ink-4); display: flex; align-items: center; justify-content: center; }
.msg-read__icon:hover { background: var(--tc-bg); }
.msg-read__icon.is-on { color: #F0B429; }
.msg-read__avatar { width: 42px; height: 42px; border-radius: 50%; background: var(--tc-ink); color: #fff; display: flex; align-items: center; justify-content: center; font: 700 13px Inter, sans-serif; flex: none; }
.msg-read__from { font: 600 14px Inter, sans-serif; color: var(--tc-ink); }
.msg-read__position { font: 500 12px Inter, sans-serif; color: var(--tc-ink-4); }
.msg-read__to { font: 500 12px Inter, sans-serif; color: var(--tc-ink-3); }
.msg-read__date { font: 500 12px Inter, sans-serif; color: var(--tc-ink-4); }
.msg-read__body { flex: 1; overflow-y: auto; padding: 24px 26px; font: 400 14px/1.65 Inter, sans-serif; color: #343A40; white-space: pre-line; }
.msg-read__actions { padding: 14px 22px; border-top: 1px solid #F1F3F5; display: flex; gap: 10px; flex-wrap: wrap; background: #fff; flex: none; }

.msg-empty { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 24px; text-align: center; color: var(--tc-ink-4); font: 500 13px Inter, sans-serif; }

/* ── Le FIL ouvert ──
   Les messages s'ALIGNENT, tous sur la même marge, séparés d'un filet. Pas de
   cartes, pas de bulles, aucune couleur pour distinguer les siens : dans un
   échange, ce qu'on suit c'est la suite des prises de parole, et l'alternance
   de fonds colorés la hache au lieu de l'aider. Le nom suffit à dire qui parle. */
.msg-thread { flex: 1; overflow-y: auto; min-height: 0; padding: 0; }
.msg-bubble { padding: 16px 22px; border-bottom: 1px solid var(--tc-bg); background: #fff; }
.msg-bubble:last-child { border-bottom: none; }
.msg-bubble__head { display: flex; align-items: flex-start; gap: 11px; margin-bottom: 8px; }
.msg-bubble__from { font: 600 13px Inter, sans-serif; color: var(--tc-ink); }
.msg-bubble__to { display: block; font: 500 11px Inter, sans-serif; color: var(--tc-ink-4); margin-top: 1px; }
.msg-bubble__body { font: 400 13.5px/1.65 Inter, sans-serif; color: #343A40; white-space: pre-line; padding-left: 41px; }
.msg-bubble .msg-attachment { margin-left: 41px; margin-top: 8px; }
.msg-read__avatar--sm { width: 30px; height: 30px; font-size: 10px; }
/* Le compteur de messages du fil, dans la liste. */
.msg-item__count { display: inline-block; font: 700 10.5px Inter, sans-serif; color: var(--tc-ink-3); }
/* Le trombone signale les pièces jointes sans jamais rétrécir la ligne. */
.msg-item__clip { flex: none; }

/* ── Répondre DANS le fil ──
   Ni objet ni destinataires : la conversation les porte. */
.msg-reply { border-top: 1px solid var(--tc-border); padding: 12px 22px 14px; background: var(--tc-surface-soft); flex: none; }
.msg-reply__text { width: 100%; border: 1px solid var(--tc-border); border-radius: 10px; padding: 10px 12px; font: 400 13.5px/1.6 Inter, sans-serif; color: var(--tc-ink); background: var(--tc-surface); resize: vertical; box-sizing: border-box; }
.msg-reply__text:focus { outline: none; border-color: var(--tc-red); }
.msg-reply__foot { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.msg-reply__file { font: 500 11.5px Inter, sans-serif; color: var(--tc-ink-3); }

/* ── Fenêtre de rédaction ──
   Ancrée en bas à droite comme sur la maquette : elle laisse la boîte visible
   pendant qu'on écrit, ce qu'une modale plein écran interdirait. */
.msg-compose { position: fixed; right: 26px; bottom: 0; width: 548px; max-width: calc(100vw - 52px); background: #fff; border-radius: 13px 13px 0 0; box-shadow: 0 -6px 40px rgba(0, 0, 0, .22); z-index: 60; display: flex; flex-direction: column; max-height: 82vh; }
.msg-compose__head { display: flex; align-items: center; justify-content: space-between; padding: 13px 18px; background: #1C2024; border-radius: 13px 13px 0 0; font: 600 13px Inter, sans-serif; color: #fff; }
.msg-compose__close { width: 28px; height: 28px; border-radius: 7px; border: none; background: none; cursor: pointer; color: #fff; display: flex; align-items: center; justify-content: center; }
.msg-compose__close:hover { background: rgba(255, 255, 255, .12); }
.msg-compose__body { padding: 14px 18px; display: flex; flex-direction: column; overflow-y: auto; }
.msg-compose__row { display: flex; align-items: center; gap: 8px; border-bottom: 1px solid #F1F3F5; padding: 9px 0; }
.msg-compose__key { font: 500 12.5px Inter, sans-serif; color: var(--tc-ink-3); width: 30px; flex: none; }
.msg-compose__field { flex: 1; min-width: 0; border: none; outline: none; font: 500 13px Inter, sans-serif; color: var(--tc-ink); background: none; }
.msg-compose__subject { width: 100%; border: none; outline: none; font: 600 13px Inter, sans-serif; color: var(--tc-ink); background: none; box-sizing: border-box; }
.msg-compose__text { width: 100%; min-height: 200px; border: none; outline: none; font: 400 13.5px/1.6 Inter, sans-serif; color: var(--tc-ink); background: none; resize: none; padding: 12px 0; box-sizing: border-box; }
.msg-compose__foot { display: flex; align-items: center; gap: 10px; padding: 13px 18px; border-top: 1px solid #F1F3F5; }
.msg-compose__file { font: 500 11.5px Inter, sans-serif; color: var(--tc-ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.msg-compose__field::placeholder, .msg-compose__subject::placeholder, .msg-compose__text::placeholder { color: var(--tc-ink-4); }

/* ── Destinataires en ÉTIQUETTES ──
   Le nom seul, dans une pastille qu'on retire d'un clic. Le poste alourdissait
   chaque étiquette pour une information qu'on a déjà au moment de choisir. */
.msg-people { flex: 1; min-width: 0; }
.msg-people + .ts-wrapper { flex: 1; min-width: 0; }
.chips-field .ts-wrapper { border: none; box-shadow: none; }
/* Tom Select pose son propre encadré bleu au focus : on le remplace par la
   ligne discrète du reste du formulaire. */
.chips-field .ts-wrapper.focus .ts-control,
.chips-field .ts-control:focus-within { border: none; box-shadow: none; outline: none; }
.chips-field .ts-wrapper.multi .ts-control > div { margin: 0; border-radius: 999px; }
.chips-field .ts-control { border: none; padding: 2px 0; box-shadow: none; background: none; gap: 6px; display: flex; flex-wrap: wrap; align-items: center; }
.chips-field .ts-control > input { font: 500 13px Inter, sans-serif; color: var(--tc-ink); min-width: 120px; }
.chips-field .ts-control > input::placeholder { color: var(--tc-ink-4); }
/* L'étiquette elle-même : fond doux, croix discrète, jamais de bleu de
   sélection. Le scope `.chips-field` est PARTAGÉ — la messagerie et le registre
   du courrier choisissent des personnes de la même façon, il n'y a aucune
   raison que leurs étiquettes diffèrent. */
/* Trois thèmes Tom Select sont chargés (default, bootstrap4, bootstrap5) et
   ARRIVENT APRÈS cette feuille : c'est le seul endroit du projet où `!important`
   se justifie, la cascade jouant contre nous quoi qu'on écrive comme sélecteur. */
.chips-field .ts-wrapper.multi .ts-control > div,
.chips-field .ts-wrapper.multi .ts-control > .item {
    display: inline-flex; align-items: center; gap: 6px;
    background: var(--tc-bg) !important; border: 1px solid var(--tc-border) !important;
    border-radius: 999px !important; padding: 3px 8px 3px 11px !important; margin: 0 !important;
    font: 600 11.5px Inter, sans-serif !important; color: var(--tc-ink-2) !important; text-shadow: none;
}
.chips-field .ts-wrapper.multi .ts-control > div.active,
.chips-field .ts-wrapper.multi .ts-control > .item.active {
    background: var(--tc-red-subtle) !important; border-color: var(--tc-red-border) !important; color: var(--tc-accent-ink) !important;
}
.chips-field .ts-wrapper.multi .ts-control > div .remove,
.chips-field .ts-wrapper.multi .ts-control > .item .remove {
    border: none; background: none; color: var(--tc-ink-4);
    padding: 0 0 0 2px; font-size: 14px; line-height: 1; text-decoration: none;
}
.chips-field .ts-wrapper.multi .ts-control > div .remove:hover,
.chips-field .ts-wrapper.multi .ts-control > .item .remove:hover { color: var(--tc-accent-ink); background: none; }

.chips-field .ts-dropdown { background: var(--tc-surface); border: 1px solid var(--tc-border); border-radius: 10px; box-shadow: 0 10px 30px rgba(16, 20, 26, .12); margin-top: 6px; overflow: hidden; }
.chips-field .ts-dropdown .option { font: 500 13px Inter, sans-serif; color: var(--tc-ink); padding: 9px 12px; }
.chips-field .ts-dropdown .option.active { background: var(--tc-red-subtle); color: var(--tc-accent-ink); }
.chips-field .ts-dropdown .no-results { font: 500 12.5px Inter, sans-serif; color: var(--tc-ink-4); padding: 9px 12px; }

/* Cc / Cci se déplient, comme dans Gmail. */
.msg-cc-links { display: inline-flex; gap: 10px; flex: none; }
.msg-compose__hint { font: 500 11.5px Inter, sans-serif; color: var(--tc-ink-4); margin: 6px 0 0; }
.msg-compose__none { font: 500 12.5px Inter, sans-serif; color: var(--tc-amber-ink); background: var(--tc-amber-bg); border: 1px solid var(--tc-amber-border); border-radius: 9px; padding: 10px 12px; margin: 0 0 6px; }

.msg-recipient { display: inline-flex; align-items: center; gap: 6px; background: var(--tc-bg); border-radius: 999px; padding: 3px 6px 3px 3px; font: 600 11.5px Inter, sans-serif; color: var(--tc-ink-2); flex: none; }
.msg-recipient__avatar { width: 18px; height: 18px; border-radius: 50%; background: var(--tc-ink); color: #fff; display: flex; align-items: center; justify-content: center; font: 700 8px Inter, sans-serif; }
.msg-cc-toggle { font: 600 12px Inter, sans-serif; color: var(--tc-ink-3); background: none; border: none; cursor: pointer; flex: none; }
.msg-attachment { display: inline-flex; align-items: center; gap: 7px; background: var(--tc-bg); border: 1px solid var(--tc-border); border-radius: 8px; padding: 7px 11px; font: 500 12px Inter, sans-serif; color: var(--tc-ink-2); text-decoration: none; }
.msg-attachment:hover { border-color: var(--tc-red); color: var(--tc-ink); text-decoration: none; }
.msg-icon-btn { width: 38px; height: 38px; border-radius: 8px; border: none; background: none; cursor: pointer; color: var(--tc-ink-3); display: flex; align-items: center; justify-content: center; margin: 0; flex: none; }
.msg-icon-btn:hover { background: var(--tc-bg); }

.msg-toast { position: fixed; bottom: 26px; left: 50%; transform: translateX(-50%); background: #1C2024; color: #fff; font: 600 13px Inter, sans-serif; padding: 13px 22px; border-radius: 11px; box-shadow: 0 12px 36px rgba(0, 0, 0, .28); z-index: 90; display: flex; align-items: center; gap: 9px; }
.msg-toast svg { color: #5BD08A; }

/* ── Écrans étroits ──
   Trois colonnes ne tiennent pas sous 1200px. Le rail passe en bandeau
   horizontal au-dessus des deux volets, puis tout s'empile sur téléphone : la
   hauteur fixe y devient un piège — on ne peut plus rien lire dans 200px. */
@media (max-width: 1199.98px) {
    .msg-shell { grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr); grid-template-rows: auto minmax(0, 1fr); }
    .msg-rail { grid-column: 1 / -1; flex-direction: row; align-items: center; flex-wrap: wrap; border-right: none; border-bottom: 1px solid #F1F3F5; padding: 12px; gap: 6px; }
    .msg-rail__title, .msg-tag { display: none; }
    .msg-compose-btn { margin-bottom: 0; }
    .msg-folder { width: auto; }
    .msg-receipts { margin-top: 0; padding: 0 0 0 6px; border-top: none; border-left: 1px solid #F1F3F5; }
    .msg-receipts__label { display: none; }
}

@media (max-width: 767.98px) {
    .msg-shell { grid-template-columns: minmax(0, 1fr); }
    .msg-list { border-right: none; border-bottom: 1px solid #F1F3F5; }
    .msg-list__scroll { max-height: 40dvh; }
    .msg-thread { max-height: 46dvh; }
    .msg-read__head, .msg-read__actions { padding-left: 16px; padding-right: 16px; }
    .msg-bubble { padding-left: 16px; padding-right: 16px; }
    .msg-reply { padding-left: 16px; padding-right: 16px; }
    .msg-compose { right: 0; left: 0; width: auto; max-width: none; border-radius: 13px 13px 0 0; }
}

@media (max-width: 575.98px) {
    .app-content:has(.msg-page) { overflow: visible; }
    .app-content:has(.msg-page) .app-content__inner { min-height: auto; }
    .msg-page { min-height: auto; }
    .msg-shell { border-radius: 12px; }
    .msg-rail { padding: 10px; gap: 8px; flex-wrap: wrap; justify-content: flex-start; }
    .msg-compose-btn { flex: 0 0 auto; width: 40px; height: 40px; padding: 0; font-size: 0; border-radius: 10px; }
    .msg-compose-btn__label { display: none; }
    .msg-folder { position: relative; flex: 0 0 auto; width: 40px; height: 40px; padding: 0; justify-content: center; gap: 0; }
    .msg-folder__label { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
    .msg-folder__count { position: absolute; top: -4px; right: -4px; min-width: 18px; height: 18px; padding: 0 4px; margin-left: 0; display: inline-flex; align-items: center; justify-content: center; font-size: 10px; line-height: 1; border-radius: 999px; }
    .msg-folder__count.d-none { display: none !important; }
    .msg-receipts { margin-left: auto; }
    .msg-list__scroll { max-height: 34dvh; }
    .msg-thread { max-height: none; }
    .msg-read__head { padding: 12px 14px; }
    .msg-read__title { font-size: 15px; }
    .msg-read__actions { padding: 12px 14px; flex-wrap: wrap; }
    .msg-read__actions .btn-tc, .msg-read__actions .btn-tc-outline { flex: 1 1 140px; justify-content: center; }
    .msg-bubble { padding: 12px 14px; }
    .msg-bubble__head { flex-wrap: wrap; }
    .msg-bubble__head > span:last-child { width: 100%; text-align: left; }
    .msg-reply { padding: 12px 14px calc(12px + env(safe-area-inset-bottom)); }
    .msg-reply__foot { flex-wrap: wrap; }
    .msg-compose__row { flex-wrap: wrap; gap: 6px; }
    .msg-compose__key { width: 42px; padding-top: 0; }
    .msg-cc-links { margin-left: 0; width: 100%; }
    .msg-compose__foot { flex-wrap: wrap; gap: 8px; padding-bottom: calc(14px + env(safe-area-inset-bottom)); }
    .msg-compose__foot .btn-tc { flex: 1 1 auto; justify-content: center; }
    .msg-toast { left: 12px; right: 12px; bottom: calc(12px + env(safe-area-inset-bottom)); transform: none; width: auto; justify-content: center; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   MES COURRIERS (espace salarié)

   Valeurs reprises de la maquette « EasyCH V3 — Espace Employé ». À ne pas
   confondre avec le REGISTRE DU COURRIER (.mail-*) : ici on est du côté du
   destinataire, en lecture seule.

   La modale présente un FAC-SIMILÉ de la lettre — en-tête, objet, corps en
   serif — posé sur un fond gris, comme une feuille sur un bureau. C'est ce que
   le salarié doit reconnaître : la pièce signée, pas une fiche qui la résume.
   ═══════════════════════════════════════════════════════════════════════════ */
.letter-counter { display: inline-flex; align-items: center; font: 600 11.5px Inter, sans-serif; padding: 5px 13px; border-radius: 999px; }
.letter-type { display: inline-flex; align-items: center; font: 600 10px Inter, sans-serif; padding: 2px 9px; border-radius: 999px; }

.letter-list { background: #fff; border: 1px solid var(--tc-border); border-radius: 14px; overflow: hidden; }
.letter-row { display: flex; align-items: center; gap: 14px; padding: 16px 18px; border-bottom: 1px solid var(--tc-bg); flex-wrap: wrap; }
.letter-row:last-child { border-bottom: none; }
.letter-row__icon { width: 38px; height: 38px; border-radius: 10px; background: var(--tc-bg); color: var(--tc-ink-3); display: flex; align-items: center; justify-content: center; flex: none; }
.letter-row__body { flex: 1; min-width: 220px; }
.letter-row__ref { font: 600 10.5px/1 var(--tc-font-mono); letter-spacing: .06em; color: #868E96; }
.letter-row__title { font: 700 14px Inter, sans-serif; color: var(--tc-ink); margin-top: 3px; }
.letter-row__meta { font: 500 12px Inter, sans-serif; color: #868E96; margin-top: 2px; }

.letter-ack { display: inline-flex; align-items: center; gap: 6px; font: 600 12px Inter, sans-serif; padding: 7px 14px; border-radius: 999px; flex: none; }
.letter-ack--lg { padding: 8px 15px; }

/* ── Fac-similé ── */
.letter-dialog { max-width: min(880px, 94vw); }
.letter-modal { border: none; border-radius: 16px; overflow: hidden; box-shadow: 0 24px 80px rgba(16, 20, 26, .4); }
.letter-modal__head { display: flex; align-items: center; gap: 12px; padding: 16px 22px; background: var(--tc-ink); flex-wrap: wrap; }
.letter-modal__ref { font: 600 10.5px/1 var(--tc-font-mono); letter-spacing: .06em; color: var(--tc-ink-4); }
.letter-modal__title { font: 700 14px Inter, sans-serif; color: #fff; flex: 1; min-width: 200px; }
.letter-modal__close { width: 32px; height: 32px; border-radius: 8px; border: none; background: none; cursor: pointer; color: var(--tc-ink-4); display: flex; align-items: center; justify-content: center; flex: none; }
.letter-modal__close:hover { background: #3a3f45; }
.letter-modal__stage { flex: 1; overflow-y: auto; background: #F1F3F5; padding: 26px; display: flex; justify-content: center; }
.letter-modal__foot { display: flex; align-items: center; gap: 12px; padding: 14px 22px; background: #fff; border-top: 1px solid var(--tc-border); flex-wrap: wrap; }
.letter-modal__issued { font: 500 12px Inter, sans-serif; color: #868E96; }

.letter-sheet { background: #fff; width: min(600px, 100%); box-shadow: 0 4px 24px rgba(16, 20, 26, .12); padding: 44px 48px; box-sizing: border-box; height: fit-content; }
.letter-sheet__head { display: flex; align-items: center; justify-content: space-between; gap: 16px; border-bottom: 3px solid var(--tc-red); padding-bottom: 12px; margin-bottom: 24px; }
.letter-sheet__brand { font: 800 17px Inter, sans-serif; letter-spacing: -.02em; color: var(--tc-ink); }
.letter-sheet__brand span { color: var(--tc-accent-ink); }
.letter-sheet__origin { font: 500 10.5px Inter, sans-serif; color: #868E96; text-align: right; }
.letter-sheet__kind { font: 700 13.5px Inter, sans-serif; letter-spacing: .04em; text-transform: uppercase; color: var(--tc-ink); text-align: center; margin-bottom: 6px; }
.letter-sheet__subject { font: 600 12.5px Inter, sans-serif; color: var(--tc-ink-2); text-align: center; margin-bottom: 22px; }
/* Le corps en serif : c'est la lettre, pas l'interface. */
.letter-sheet__para { font: 400 13px/1.75 'Source Serif 4', Georgia, serif; color: #343A40; margin: 0 0 13px; text-align: justify; }
.letter-sheet__foot { display: block; margin-top: 30px; font: 500 10px Inter, sans-serif; color: var(--tc-ink-4); border-top: 1px solid var(--tc-border); padding-top: 10px; text-align: center; }

@media (max-width: 575.98px) {
    .letter-modal__stage { padding: 14px; }
    .letter-sheet { padding: 24px 20px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   PERMANENCES DU SAMEDI

   Valeurs reprises de la maquette « EasyCH V3 — Espace RH ». Les indicateurs de
   tête réutilisent .mail-kpi : c'est la même carte, et en refaire une seconde
   n'aurait produit qu'un doublon à faire diverger.
   ═══════════════════════════════════════════════════════════════════════════ */
.duty-select { border: 1px solid var(--tc-border); border-radius: 8px; padding: 9px 13px; font: 600 12.5px Inter, sans-serif; color: var(--tc-ink-2); background: var(--tc-surface); }
.duty-select:focus { outline: none; border-color: var(--tc-red); }
.duty-pill { display: inline-flex; align-items: center; font: 600 11px Inter, sans-serif; padding: 4px 11px; border-radius: 999px; }
.duty-avatar { width: 26px; height: 26px; border-radius: 50%; background: var(--tc-ink); color: var(--tc-surface); display: inline-flex; align-items: center; justify-content: center; font: 700 9px Inter, sans-serif; flex: none; }
.duty-avatar--lg { width: 30px; height: 30px; font-size: 10px; }

/* Bandeau : le planning consolidé est RECONSTITUÉ, il faut le dire. */
.duty-notice { display: flex; align-items: center; gap: 10px; background: var(--tc-info-bg); border: 1px solid var(--tc-info-border); border-radius: 10px; padding: 12px 16px; margin-bottom: 16px; font: 500 12.5px Inter, sans-serif; color: var(--tc-info-ink); }
.duty-notice svg { flex: none; color: var(--tc-info-ink); }
.duty-notice__count { color: var(--tc-info-ink); font-weight: 600; }

/* ── Vue consolidée ── */
.duty-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.duty-card { background: var(--tc-surface); border: 1px solid var(--tc-border); border-radius: 14px; overflow: hidden; }
.duty-card__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 20px; border-bottom: 1px solid var(--tc-border); }
.duty-card__icon { width: 42px; height: 42px; border-radius: 11px; background: var(--tc-bg); color: var(--tc-ink-2); display: flex; align-items: center; justify-content: center; flex: none; }
.duty-card__date { font: 700 14.5px Inter, sans-serif; color: var(--tc-ink); text-transform: capitalize; }
.duty-card__count { font: 500 12px Inter, sans-serif; color: var(--tc-ink-3); }
.duty-card__supervisor { padding: 14px 20px; border-bottom: 1px solid var(--tc-bg); display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.duty-card__legend { font: 600 10px/1 var(--tc-font-mono); letter-spacing: .05em; text-transform: uppercase; color: var(--tc-ink-4); }
.duty-card__name { font: 600 12.5px Inter, sans-serif; color: var(--tc-ink); }
.duty-card__unassigned { font: 500 12px Inter, sans-serif; color: var(--tc-ink-4); font-style: italic; }
.duty-card__agents { padding: 14px 20px; display: flex; flex-wrap: wrap; gap: 8px; }

.duty-link { font: 600 11px Inter, sans-serif; color: var(--tc-ink-3); background: none; border: none; cursor: pointer; padding: 4px 8px; border-radius: 6px; }
.duty-link:hover { background: var(--tc-bg); }
.duty-designate { display: inline-flex; align-items: center; gap: 5px; font: 600 11.5px Inter, sans-serif; color: var(--tc-on-primary); background: var(--tc-red); border: none; cursor: pointer; padding: 6px 12px; border-radius: 7px; }
.duty-designate:hover { background: var(--tc-red-hover); }

.duty-agent { display: inline-flex; align-items: center; gap: 8px; background: var(--tc-surface-soft); border: 1px solid var(--tc-border); border-radius: 999px; padding: 4px 10px 4px 4px; }
.duty-agent__avatar { width: 24px; height: 24px; border-radius: 50%; background: var(--tc-border); color: var(--tc-ink-2); display: flex; align-items: center; justify-content: center; font: 700 9px Inter, sans-serif; flex: none; }
.duty-agent__name { font: 600 11.5px Inter, sans-serif; color: var(--tc-ink); }
.duty-agent__dept { font: 600 9px/1 var(--tc-font-mono); letter-spacing: .04em; text-transform: uppercase; padding: 3px 7px; border-radius: 5px; background: var(--tc-surface-alt); color: var(--tc-sidebar-section); border: 1px solid var(--tc-border); }

/* ── Soumissions ── */
.duty-stats { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }
.duty-stat { flex: 1; min-width: 130px; background: var(--tc-surface); border: 1px solid var(--tc-border); border-radius: 11px; padding: 13px 16px; }
.duty-stat__value { font: 700 20px Inter, sans-serif; }
.duty-stat__value--ok { color: var(--tc-green-ink); }
.duty-stat__value--info { color: var(--tc-info-ink); }
.duty-stat__value--warn { color: var(--tc-amber-ink); }
.duty-stat__label { font: 500 11.5px Inter, sans-serif; color: var(--tc-ink-3); margin-top: 2px; }

.duty-sub { background: var(--tc-surface); border: 1px solid var(--tc-border); border-radius: 13px; padding: 16px 20px; }
.duty-sub__avatar { width: 40px; height: 40px; border-radius: 10px; background: var(--tc-ink); color: var(--tc-surface); display: flex; align-items: center; justify-content: center; font: 700 11px Inter, sans-serif; flex: none; }
.duty-sub__dept { font: 700 14px Inter, sans-serif; color: var(--tc-ink); }
.duty-sub__code { font: 600 9.5px/1 var(--tc-font-mono); letter-spacing: .04em; padding: 3px 7px; border-radius: 5px; background: var(--tc-surface-alt); color: var(--tc-ink-3); }
.duty-sub__meta { font: 500 12px Inter, sans-serif; color: var(--tc-ink-3); margin-top: 3px; }
.duty-sub__who { color: var(--tc-ink); font-weight: 600; }
.duty-sub__role { color: var(--tc-ink-4); }
.duty-sub__empty { font: 500 12px Inter, sans-serif; color: var(--tc-ink-4); font-style: italic; margin-top: 8px; }
.duty-sub__days { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.duty-sub__count { font: 600 12px Inter, sans-serif; color: var(--tc-ink); }
.duty-sub__merged { display: inline-flex; align-items: center; gap: 5px; font: 600 11.5px Inter, sans-serif; color: var(--tc-green-ink); }

.duty-day { background: var(--tc-surface-soft); border: 1px solid var(--tc-border); border-radius: 9px; padding: 7px 11px; min-width: 120px; }
.duty-day__label { font: 600 9.5px/1 var(--tc-font-mono); letter-spacing: .04em; text-transform: uppercase; color: var(--tc-ink-4); margin-bottom: 4px; }
.duty-day__agents { font: 600 12px Inter, sans-serif; color: var(--tc-ink); }

/* ── Grille de saisie ── */
.duty-entry { background: var(--tc-surface); border: 1px solid var(--tc-border); border-radius: 14px; overflow: hidden; }
.duty-entry__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 20px; border-bottom: 1px solid var(--tc-border); flex-wrap: wrap; }
.duty-entry__dept { font: 700 14px Inter, sans-serif; color: var(--tc-ink); }
.duty-entry__hint { font: 600 11px Inter, sans-serif; padding: 3px 10px; border-radius: 999px; background: var(--tc-surface-alt); color: var(--tc-ink-3); }
.duty-entry__scroll { overflow-x: auto; }
.duty-entry__foot { display: flex; justify-content: flex-end; gap: 10px; padding: 15px 20px; background: var(--tc-surface-soft); }

.duty-table { width: 100%; border-collapse: collapse; min-width: 620px; }
.duty-table th { font: 600 10px/1 var(--tc-font-mono); letter-spacing: .05em; text-transform: uppercase; color: var(--tc-ink-4); padding: 12px 20px; background: var(--tc-surface-soft); border-bottom: 1px solid var(--tc-border); font-weight: 600; }
.duty-table td { padding: 13px 20px; border-bottom: 1px solid var(--tc-bg); vertical-align: middle; }
.duty-table tr:last-child td { border-bottom: none; }
.duty-table__name { display: block; font: 600 13px Inter, sans-serif; color: var(--tc-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.duty-table__position { display: block; font: 500 11px Inter, sans-serif; color: var(--tc-ink-4); }
.duty-table__last { font: 500 11.5px Inter, sans-serif; color: var(--tc-ink-3); white-space: nowrap; }

/* Case à cocher déguisée : la vraie reste là, focalisable et soumise. */
.duty-check { display: inline-flex; position: relative; cursor: pointer; margin: 0; }
.duty-check input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.duty-check__box { width: 24px; height: 24px; border-radius: 7px; border: 1.5px solid var(--tc-border); background: var(--tc-surface); color: transparent; display: flex; align-items: center; justify-content: center; transition: background .12s, border-color .12s; }
.duty-check input:checked + .duty-check__box { background: var(--tc-red); border-color: var(--tc-red); color: var(--tc-on-primary); }
.duty-check input:focus-visible + .duty-check__box { outline: 2px solid var(--tc-red); outline-offset: 2px; }

/* ── Modales des permanences ── */
.duty-modal { border: none; border-radius: 16px; overflow: hidden; box-shadow: 0 24px 60px rgba(0, 0, 0, .28); }
.duty-modal__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 20px 24px; border-bottom: 1px solid var(--tc-border); }
.duty-modal__title { font: 700 17px Inter, sans-serif; color: var(--tc-ink); }
.duty-modal__subtitle { font: 500 12px Inter, sans-serif; color: var(--tc-ink-3); margin-top: 2px; }
.duty-modal__close { width: 32px; height: 32px; border-radius: 8px; border: none; background: none; cursor: pointer; color: var(--tc-ink-4); display: flex; align-items: center; justify-content: center; flex: none; }
.duty-modal__close:hover { background: var(--tc-bg); }
.duty-modal__body { padding: 22px 24px; overflow-y: auto; display: flex; flex-direction: column; gap: 16px; }
.duty-modal__foot { display: flex; justify-content: flex-end; gap: 10px; padding: 16px 24px; border-top: 1px solid var(--tc-border); background: var(--tc-surface-soft); }

.duty-field__label { display: block; font: 600 11px/1 var(--tc-font-mono); letter-spacing: .05em; text-transform: uppercase; color: var(--tc-ink-3); margin-bottom: 7px; }
.duty-input { width: 100%; padding: 9px 11px; font: 500 13px Inter, sans-serif; color: var(--tc-ink); background: var(--tc-surface); border: 1px solid var(--tc-border); border-radius: 8px; box-sizing: border-box; }
.duty-input:focus { outline: none; border-color: var(--tc-red); }
.duty-input--area { min-height: 120px; padding: 11px; resize: vertical; line-height: 1.6; }
.duty-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }

.duty-recipients { display: flex; align-items: center; gap: 8px; border: 1px solid var(--tc-border); border-radius: 8px; padding: 9px 12px; background: var(--tc-surface-soft); flex-wrap: wrap; }
.duty-recipients__count { font: 500 12px Inter, sans-serif; color: var(--tc-ink-3); }

.duty-attachment { display: flex; align-items: center; gap: 11px; background: var(--tc-surface-soft); border: 1px solid var(--tc-border); border-radius: 10px; padding: 12px 15px; }
.duty-attachment__icon { width: 34px; height: 40px; border-radius: 6px; background: var(--tc-red-subtle); color: var(--tc-accent-ink); display: flex; align-items: center; justify-content: center; flex: none; }
.duty-attachment__name { display: block; font: 600 12.5px Inter, sans-serif; color: var(--tc-ink); }
.duty-attachment__hint { display: block; font: 500 11px Inter, sans-serif; color: var(--tc-ink-4); }
.duty-attachment__ok { font: 600 11px Inter, sans-serif; color: var(--tc-green-ink); flex: none; }

.duty-picks { border: 1px solid var(--tc-border); border-radius: 10px; overflow: hidden; }
.duty-pick { display: flex; align-items: center; gap: 10px; padding: 10px 13px; border-bottom: 1px solid var(--tc-bg); cursor: pointer; margin: 0; font: 500 12.5px Inter, sans-serif; color: var(--tc-ink); }
.duty-pick:last-child { border-bottom: none; }
.duty-pick input { width: 15px; height: 15px; accent-color: var(--tc-red); }

/* L'avertissement de rotation : discret, mais jamais absent. */
.duty-warning { display: flex; align-items: center; gap: 7px; margin-top: 9px; font: 500 11.5px Inter, sans-serif; color: var(--tc-amber-ink); }
.duty-warning svg { flex: none; }

@media (max-width: 991.98px) {
    .duty-grid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 575.98px) {
    .duty-fields { grid-template-columns: 1fr; }
    .duty-card__head, .duty-card__supervisor, .duty-card__agents { padding-left: 14px; padding-right: 14px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   DIFFUSIONS & ANNONCES

   Valeurs reprises de la maquette (« EasyCH V3 — Espace RH »), promues en
   classes plutôt que recopiées en styles inline dans le gabarit : la pastille
   d'initiales, la carte et les puces servent aux quatre blocs de l'écran et
   aux deux fenêtres de gestion.

   La couleur des pastilles de catégorie ne vit PAS ici : elle vient des
   `.tone-*` du nuancier (App\Enum\AnnouncementCategory::tone()), pour qu'une
   catégorie ajoutée demain n'ait pas à toucher cette feuille.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Deux colonnes qui se replient d'elles-mêmes : la pile à valider d'un côté,
   le suivi et les groupes de l'autre. */
.ann-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(380px, 1fr)); gap: 16px; align-items: start; }
.ann-column { display: flex; flex-direction: column; gap: 16px; }

.ann-card { background: var(--tc-surface); border: 1px solid var(--tc-border); border-radius: 14px; overflow: hidden; }
.ann-card--plain { padding: 18px 20px; }
.ann-card__head { display: flex; align-items: center; gap: 9px; padding: 15px 20px; border-bottom: 1px solid var(--tc-border); }
.ann-card__dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.ann-card__dot--pending { background: var(--tc-red); }
.ann-card__dot--done { background: #28A745; }
.ann-card__dot--groups { background: var(--tc-info-ink); }
.ann-card__title { font: 700 14px Inter, sans-serif; color: var(--tc-ink); }
.ann-card__count { margin-left: auto; font: 600 11px Inter, sans-serif; background: var(--tc-red-subtle); color: var(--tc-accent-ink); padding: 3px 9px; border-radius: 999px; }
.ann-card__note { font: 500 11px/1.5 Inter, sans-serif; color: var(--tc-ink-4); padding: 0 20px 14px; margin: 0; }
.ann-card__note--boxed { padding: 12px 20px 16px; }

/* Pastille d'initiales — le même rond noir dans les deux listes et dans la
   fenêtre de gestion, à deux tailles près. */
.ann-avatar { width: 32px; height: 32px; border-radius: 50%; background: var(--tc-ink); color: var(--tc-surface); display: flex; align-items: center; justify-content: center; font: 700 11px Inter, sans-serif; flex: none; }
.ann-avatar--sm { width: 30px; height: 30px; font-size: 10.5px; }

/* ── La pile à valider ── */
.ann-pending { padding: 15px 20px; border-bottom: 1px solid var(--tc-border); }
.ann-pending:last-of-type { border-bottom: none; }
.ann-pending__head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.ann-pending__who { flex: 1; min-width: 0; }
.ann-pending__name { font: 700 13px Inter, sans-serif; color: var(--tc-ink); }
.ann-pending__source { font: 500 11px Inter, sans-serif; color: var(--tc-ink-4); }
.ann-type { display: inline-flex; align-items: center; font: 600 10px Inter, sans-serif; padding: 3px 9px; border-radius: 999px; flex: none; }

/* Le RÉCIT du salarié : encadré, en lecture seule, filet gris à gauche pour
   qu'on ne le confonde pas avec le champ du dessous. `pre-line` respecte ses
   retours à la ligne — on raconte en paragraphes, pas en une phrase. */
.ann-pending__label { font: 600 10px/1 var(--tc-font-mono); letter-spacing: .07em; text-transform: uppercase; color: var(--tc-ink-4); margin: 12px 0 6px; display: block; }
.ann-pending__report { font: 500 12.5px/1.6 Inter, sans-serif; color: var(--tc-ink-2); background: var(--tc-surface-soft); border: 1px solid var(--tc-border); border-left: 3px solid var(--tc-ink-4); border-radius: 9px; padding: 10px 13px; margin: 0; white-space: pre-line; }

/* Le texte se relit et se corrige AVANT de partir : c'est un champ, pas un
   aperçu. `field-sizing` le fait grandir avec son contenu là où le navigateur
   le sait ; ailleurs, les deux lignes de la maquette tiennent. */
.ann-pending__text { display: block; width: 100%; box-sizing: border-box; resize: vertical; field-sizing: content; min-height: 42px; font: 500 12.5px/1.6 Inter, sans-serif; color: var(--tc-ink); background: var(--tc-surface-soft); border: 1px solid var(--tc-border); border-radius: 9px; padding: 10px 13px; outline: none; }
.ann-pending__text:focus { border-color: var(--tc-red-border); }

.ann-audience { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.ann-audience__label { font: 600 11px Inter, sans-serif; color: var(--tc-ink-3); flex: none; }
.ann-audience__select { flex: 1; min-width: 0; border: 1px solid var(--tc-border); border-radius: 8px; background: var(--tc-surface); font: 600 12px Inter, sans-serif; color: var(--tc-ink); cursor: pointer; padding: 7px 9px; }

.ann-actions { display: flex; align-items: center; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.ann-actions__hint { margin-left: auto; font: 500 11px Inter, sans-serif; color: var(--tc-ink-4); align-self: center; }
.ann-btn { display: inline-flex; align-items: center; gap: 6px; border: none; border-radius: 8px; padding: 9px 14px; cursor: pointer; font: 700 12px Inter, sans-serif; background: var(--tc-red); color: var(--tc-on-primary); }
.ann-btn:hover { background: var(--tc-red-hover); }
.ann-btn--ghost { border: 1px solid var(--tc-border); background: var(--tc-surface); color: var(--tc-ink-2); font-weight: 600; }
.ann-btn--ghost:hover { background: var(--tc-bg); }
.ann-empty { padding: 30px 20px; text-align: center; font: 500 12.5px Inter, sans-serif; color: var(--tc-ink-4); }

/* ── Ce qui est parti aujourd'hui ── */
.ann-done { display: flex; align-items: flex-start; gap: 10px; padding: 13px 20px; border-bottom: 1px solid var(--tc-border); }
.ann-done:last-child { border-bottom: none; }
.ann-done__body { flex: 1; min-width: 0; }
.ann-done__name { font: 700 12.5px Inter, sans-serif; color: var(--tc-ink); }
.ann-done__text { font: 500 12px Inter, sans-serif; color: var(--tc-ink-2); }
.ann-done__meta { font: 500 10.5px Inter, sans-serif; color: var(--tc-ink-4); margin-top: 2px; }
.ann-done__badge { display: inline-flex; align-items: center; gap: 5px; font: 600 10.5px Inter, sans-serif; color: var(--tc-green-ink); background: var(--tc-green-bg); padding: 4px 9px; border-radius: 999px; flex: none; }

/* ── Le carnet des groupes ── */
.ann-newgroup { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--tc-red-border); border-radius: 8px; padding: 6px 11px; cursor: pointer; font: 700 11.5px Inter, sans-serif; background: var(--tc-surface); color: var(--tc-accent-ink); text-decoration: none; }
.ann-newgroup:hover { background: var(--tc-red-subtle); color: var(--tc-accent-ink); }
.ann-groups { padding: 6px 0; }
.ann-group { display: flex; align-items: center; gap: 10px; padding: 10px 20px; border-top: 1px solid var(--tc-border); }
.ann-group__name { font: 600 12.5px Inter, sans-serif; color: var(--tc-ink); flex: 1; min-width: 0; }
.ann-group__count { font: 600 11px Inter, sans-serif; background: var(--tc-bg); color: var(--tc-ink-2); padding: 3px 9px; border-radius: 999px; flex: none; }
.ann-group__auto { font: 600 10px Inter, sans-serif; background: var(--tc-red-subtle); color: var(--tc-accent-ink); padding: 3px 8px; border-radius: 999px; flex: none; }
.ann-group__manage { border: 1px solid var(--tc-border); border-radius: 7px; padding: 5px 11px; cursor: pointer; font: 600 11px Inter, sans-serif; background: var(--tc-surface); color: var(--tc-ink-2); text-decoration: none; flex: none; }
.ann-group__manage:hover { background: var(--tc-bg); color: var(--tc-ink-2); }

/* ── Canaux de diffusion (informatif) ── */
.ann-channels__title { font: 700 13.5px Inter, sans-serif; color: var(--tc-ink); margin-bottom: 10px; }
.ann-channels__list { display: flex; flex-direction: column; gap: 7px; font: 500 12.5px/1.55 Inter, sans-serif; color: var(--tc-ink-2); margin: 0; padding: 0; list-style: none; }
.ann-channels__list li { display: flex; gap: 9px; }
.ann-channels__ok { color: var(--tc-green-ink); flex: none; }
.ann-channels__warn { color: var(--tc-amber-ink); flex: none; }

/* ── Fenêtres de gestion ──
   Pilotées par l'URL (`?groupe=…`, `?nouveau-groupe`), donc rendues seulement
   quand elles sont ouvertes : pas de modale Bootstrap préparée par groupe. Le
   voile est un LIEN de retour — la fenêtre se ferme sans une ligne de script. */
.ann-overlay { position: fixed; inset: 0; background: rgba(16, 20, 26, .5); z-index: 70; }
.ann-modal { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); width: min(480px, 94vw); max-height: 88vh; overflow-y: auto; z-index: 71; background: var(--tc-surface); border-radius: 16px; box-shadow: 0 24px 80px rgba(16, 20, 26, .4); }
.ann-modal--wide { width: min(500px, 94vw); }
.ann-modal__head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 15px 20px; background: var(--tc-sidebar); }
.ann-modal__title { font: 700 14px Inter, sans-serif; color: var(--tc-on-sidebar); }
.ann-modal__title span { font: 500 11.5px Inter, sans-serif; color: var(--tc-sidebar-section); }
.ann-modal__close { width: 30px; height: 30px; border-radius: 8px; border: none; background: none; cursor: pointer; color: var(--tc-sidebar-muted); display: flex; align-items: center; justify-content: center; text-decoration: none; }
.ann-modal__close:hover { background: var(--tc-sidebar-hover); color: var(--tc-on-sidebar); }
.ann-modal__body { padding: 18px 22px; display: flex; flex-direction: column; gap: 14px; }
.ann-modal__foot { display: flex; align-items: center; gap: 10px; padding: 14px 22px; border-top: 1px solid var(--tc-border); }
.ann-modal__label { font: 600 11px/1 var(--tc-font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--tc-ink-4); margin-bottom: 9px; display: block; }
.ann-modal__input { width: 100%; box-sizing: border-box; border: 1px solid var(--tc-border); border-radius: 10px; padding: 11px 14px; font: 500 13px Inter, sans-serif; color: var(--tc-ink); outline: none; }
.ann-modal__input:focus { border-color: var(--tc-red); }
/* Même boîte que le champ texte, mais habitée par le sélecteur à étiquettes
   (`.chips-field`, partagé avec la messagerie et le registre du courrier).
   Elle GRANDIT vers le bas au fil des noms retenus : c'est ce qui remplace le
   mur de pastilles qui remplissait la fenêtre. */
.ann-modal__field { width: 100%; box-sizing: border-box; border: 1px solid var(--tc-border); border-radius: 10px; padding: 7px 12px; background: var(--tc-surface); }
.ann-modal__field:focus-within { border-color: var(--tc-red); }

/* ── Décision sur un signalement (validation / refus) ──
   Modales Bootstrap `.quick-modal` portées par `.ann-decision`. Le contenu
   est structuré (bandeau, récapitulatif, aperçu du texte ou motif obligatoire)
   sans dépendre de styles inline. */
.ann-decision .modal-dialog { max-width: 560px; }
.ann-decision .modal-body { display: flex; flex-direction: column; gap: 14px; }
.ann-decision__icon--publish { background: var(--tc-green-bg); color: var(--tc-green-ink); }
.ann-decision__icon--reject { background: var(--tc-danger-bg); color: var(--tc-danger-ink); }
.ann-decision__lead { display: flex; align-items: flex-start; gap: 10px; padding: 11px 13px; border-radius: 10px; font: 500 12.5px/1.55 Inter, sans-serif; color: var(--tc-ink-2); background: var(--tc-surface-soft); border: 1px solid var(--tc-border); }
.ann-decision__lead svg { flex: none; margin-top: 1px; color: var(--tc-ink-3); }
.ann-decision__lead--reject { background: var(--tc-danger-bg); border-color: var(--tc-danger-border); color: var(--tc-danger-ink); }
.ann-decision__lead--reject svg { color: var(--tc-danger-ink); }
.ann-decision__recap { border: 1px solid var(--tc-border); border-radius: 12px; overflow: hidden; background: var(--tc-surface); }
.ann-decision__row { display: grid; grid-template-columns: 124px 1fr; gap: 10px; align-items: baseline; padding: 10px 14px; font: 500 13px/1.45 Inter, sans-serif; border-bottom: 1px solid var(--tc-border); }
.ann-decision__row:last-child { border-bottom: none; }
.ann-decision__key { font: 600 10.5px/1 var(--tc-font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--tc-ink-4); }
.ann-decision__val { color: var(--tc-ink); min-width: 0; word-break: break-word; }
.ann-decision__preview { border: 1px solid var(--tc-border); border-radius: 12px; overflow: hidden; }
.ann-decision__preview-head { display: flex; align-items: center; gap: 7px; padding: 9px 14px; font: 600 10.5px/1 var(--tc-font-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--tc-ink-3); background: var(--tc-surface-soft); border-bottom: 1px solid var(--tc-border); }
.ann-decision__preview-body { padding: 12px 14px; font: 500 13px/1.6 Inter, sans-serif; color: var(--tc-ink); background: var(--tc-surface); white-space: pre-wrap; min-height: 52px; }
.ann-decision__field { display: flex; flex-direction: column; gap: 6px; }
.ann-decision__label { font: 600 11px/1 var(--tc-font-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--tc-ink-3); }
.ann-decision__required { color: var(--tc-danger-ink); margin-left: 2px; }
.ann-decision__textarea { width: 100%; box-sizing: border-box; resize: vertical; min-height: 96px; border: 1px solid var(--tc-border); border-radius: 10px; padding: 11px 14px; font: 500 13px/1.55 Inter, sans-serif; color: var(--tc-ink); background: var(--tc-surface); outline: none; transition: border-color .15s, box-shadow .15s; }
.ann-decision__textarea::placeholder { color: var(--tc-ink-4); }
.ann-decision__textarea:focus { border-color: var(--tc-danger-ink); box-shadow: 0 0 0 3px var(--tc-danger-bg); }
.ann-decision__textarea:invalid:not(:placeholder-shown) { border-color: var(--tc-danger-border); }
.ann-decision__hint { margin: 0; font: 500 11.5px/1.45 Inter, sans-serif; color: var(--tc-ink-4); }
.ann-decision__submit { display: inline-flex; align-items: center; gap: 7px; }
.ann-decision__submit--reject { background: var(--tc-danger-ink) !important; border-color: var(--tc-danger-ink) !important; color: #fff !important; }
.ann-decision__submit--reject:hover { filter: brightness(.94); }
@media (max-width: 575.98px) {
    .ann-decision__row { grid-template-columns: 1fr; gap: 3px; }
}

.ann-members { padding: 8px 0; margin: 0; }
.ann-member { display: flex; align-items: center; gap: 11px; padding: 9px 20px; }
.ann-member__name { flex: 1; min-width: 0; font: 600 13px Inter, sans-serif; color: var(--tc-ink); }
.ann-member__drop { width: 28px; height: 28px; border-radius: 7px; border: 1px solid var(--tc-border); background: var(--tc-surface); cursor: pointer; color: var(--tc-ink-3); display: flex; align-items: center; justify-content: center; flex: none; }
.ann-member__drop:hover { background: var(--tc-red-subtle); color: var(--tc-accent-ink); }

.ann-pool { border-top: 1px solid var(--tc-border); padding: 14px 20px; }
/* La fournée se valide d'un geste, sous le champ qui l'a composée. */
.ann-pool__add { margin-top: 10px; }
/* Confirmation de création — le même dessin que les autres états de succès. */
.ann-created { padding: 34px 26px; display: flex; flex-direction: column; align-items: center; gap: 12px; text-align: center; }
.ann-created__icon { width: 60px; height: 60px; border-radius: 50%; background: var(--tc-green-bg); color: var(--tc-green-ink); display: flex; align-items: center; justify-content: center; }
.ann-created__title { font: 700 16px Inter, sans-serif; color: var(--tc-ink); }
.ann-created__text { font: 500 12.5px/1.6 Inter, sans-serif; color: var(--tc-ink-3); }
.ann-created__close { border: 1px solid var(--tc-border); border-radius: 9px; padding: 10px 20px; cursor: pointer; font: 600 13px Inter, sans-serif; background: var(--tc-surface); color: var(--tc-ink); margin-top: 6px; text-decoration: none; }
.ann-created__close:hover { background: var(--tc-border); color: var(--tc-ink); }

.ann-submit { display: inline-flex; align-items: center; gap: 8px; border: none; border-radius: 9px; padding: 11px 20px; cursor: pointer; font: 700 13px Inter, sans-serif; background: var(--tc-red); color: var(--tc-on-primary); }
.ann-submit:hover { background: var(--tc-red-hover); }
.ann-cancel { border: none; border-radius: 9px; padding: 11px 16px; cursor: pointer; font: 600 13px Inter, sans-serif; background: none; color: var(--tc-ink-3); text-decoration: none; }
.ann-cancel:hover { background: var(--tc-border); color: var(--tc-ink-3); }

@media (max-width: 575.98px) {
    .ann-grid { grid-template-columns: minmax(0, 1fr); }
    .ann-actions__hint { margin-left: 0; }
}

/* ── Signaler (espace salarié) ────────────────────────────────────────────────
   Le formulaire de dépôt et le suivi de ses propres signalements. Il réemploie
   les blocs de l'écran de validation (`.ann-card`, `.ann-type`, `.ann-empty`) :
   les deux côtés parlent des mêmes objets, ils doivent se ressembler.
   ────────────────────────────────────────────────────────────────────────── */
.ann-form { display: flex; flex-direction: column; gap: 14px; padding: 18px 20px; }
.ann-form__text { resize: vertical; min-height: 110px; line-height: 1.6; }
.ann-form__hint { font: 500 11.5px/1.5 Inter, sans-serif; color: var(--tc-ink-4); margin: 6px 0 0; }
/* Le rappel de ce qui va se passer ensuite : discret, mais jamais absent — on
   n'écrit pas la même chose selon qu'on croit publier ou déclarer. */
.ann-form__notice { display: flex; align-items: flex-start; gap: 9px; margin: 0; padding: 12px 14px; background: var(--tc-amber-bg); border: 1px solid var(--tc-amber-border); border-radius: 10px; font: 500 12px/1.5 Inter, sans-serif; color: var(--tc-amber-ink); }
.ann-form__notice svg { flex: none; margin-top: 1px; }
.ann-form .ann-submit { align-self: flex-start; }

.ann-report { padding: 15px 20px; border-bottom: 1px solid var(--tc-border); }
.ann-report:last-of-type { border-bottom: none; }
.ann-report__head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-bottom: 9px; }
.ann-report__when { font: 500 11.5px Inter, sans-serif; color: var(--tc-ink-4); }
.ann-report__state { margin-left: auto; font: 600 10.5px Inter, sans-serif; padding: 3px 9px; border-radius: 999px; }
.ann-report__text { font: 500 12.5px/1.6 Inter, sans-serif; color: var(--tc-ink-2); margin: 0; white-space: pre-line; }
/* Ce qui est réellement parti, détaché du récit par un filet vert : le texte
   diffusé n'est presque jamais celui qu'on a écrit. */
.ann-report__sent { margin-top: 12px; padding: 10px 13px; background: var(--tc-green-bg); border-radius: 9px; }
.ann-report__sent .ann-pending__label { margin: 0 0 5px; color: var(--tc-green-ink); }
.ann-report__message { font: 500 12.5px/1.6 Inter, sans-serif; color: var(--tc-ink); margin: 0; white-space: pre-line; }
.ann-report__meta { font: 500 10.5px Inter, sans-serif; color: var(--tc-green-ink); margin-top: 6px; }

/* =========================================================
   TABLEAU DE BORD EMPLOYÉ — deux colonnes de la maquette
   =========================================================
   1.6fr / 1fr à partir de « lg », empilées en dessous : la carte de chaleur
   des présences et la table des validations ont chacune besoin de leur
   largeur, et les serrer côte à côte sur un portable rendrait les deux
   illisibles. */
.dash-cols { display: grid; gap: 16px; grid-template-columns: minmax(0, 1fr); align-items: start; }

/* Sans `min-width: 0`, une piste de grille refuse de descendre sous la largeur
   intrinsèque de son contenu : la carte de chaleur et la table des validations
   imposaient leur largeur minimale, écrasant la colonne voisine sur portable et
   faisant déborder la page sous 375 px. */
.dash-cols > * { min-width: 0; }

@media (min-width: 992px) {
    .dash-cols { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); }
}

/* =========================================================
   ZONE DE DÉPÔT DE FICHIER
   =========================================================
   Le champ natif reste dans le DOM, masqué : c'est lui qui porte le fichier et
   que la validation lit. La surface pointillée est un `<label for>` — la
   tabulation atteint donc le champ et « Entrée » ouvre le sélecteur, sans un
   seul gestionnaire de clavier écrit à la main. */
.dropzone-field { display: block; }
.dropzone {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 6px; width: 100%; padding: 22px 18px; cursor: pointer;
    border: 1.5px dashed var(--tc-border); border-radius: 12px; background: #FAFBFC;
    text-align: center; transition: border-color .15s, background .15s;
}
.dropzone:hover { border-color: var(--tc-red-border); background: var(--tc-red-subtle); }
.dropzone.is-over { border-color: var(--tc-red); background: var(--tc-red-subtle); }

/* Le focus vit sur le champ masqué : c'est lui qui reçoit la tabulation, donc
   c'est de lui que l'anneau doit partir — sur la zone, il ne s'afficherait
   jamais. */
.dropzone-field:focus-within .dropzone { border-color: var(--tc-red); box-shadow: 0 0 0 3px var(--tc-red-subtle); }

.dropzone__icon { width: 38px; height: 38px; border-radius: 10px; background: #fff; border: 1px solid var(--tc-border); color: var(--tc-ink-3); display: inline-flex; align-items: center; justify-content: center; }
.dropzone__title { font-weight: 600; font-size: 13px; color: var(--tc-ink); }
.dropzone__hint { font-weight: 500; font-size: 11.5px; color: var(--tc-ink-4); }
.dropzone__file { font: 600 12px/1 var(--tc-font-mono); color: var(--tc-accent-ink); margin-top: 4px; word-break: break-all; }

/* Bascule de consentement du bandeau d'anniversaires. Le rail et la pastille
   sont dessinés en CSS plutôt qu'avec une case à cocher stylée : l'état est
   porté par `aria-pressed` sur le bouton, que les lecteurs d'écran annoncent. */
.bday-toggle { display: inline-flex; align-items: center; gap: 8px; border: 1px solid var(--tc-border); border-radius: 999px; padding: 7px 13px; cursor: pointer; font-weight: 600; font-size: 11.5px; color: var(--tc-ink-2); background: var(--tc-surface); transition: background .12s; }
.bday-toggle:hover { background: var(--tc-bg); }
.bday-toggle__switch { width: 26px; height: 15px; border-radius: 999px; background: #CED4DA; position: relative; flex: none; transition: background .15s; }
.bday-toggle__switch.is-on { background: #28A745; }
.bday-toggle__switch span { position: absolute; top: 2px; left: 2px; width: 11px; height: 11px; border-radius: 50%; background: #fff; transition: left .15s; }
.bday-toggle__switch.is-on span { left: 13px; }

/* Ligne « compteur » des cartes Communication et Évaluations : un libellé, une
   valeur, un chevron. Le bloc entier est cliquable — viser le seul chiffre
   demanderait une précision que personne n'a sur un écran tactile. */
.dash-row { display: flex; align-items: center; gap: 10px; width: 100%; text-decoration: none; background: var(--tc-surface-soft); border-radius: 10px; padding: 11px 13px; font-weight: 600; font-size: 12.5px; color: var(--tc-ink); transition: background .12s; }
.dash-row:hover { background: var(--tc-surface-alt); color: var(--tc-ink); }
.dash-row__dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.dash-row__value { font-weight: 800; font-size: 14px; color: var(--tc-ink); }

/* Ligne de la modale « Anniversaires du mois » côté employé : une date en
   pastille, l'identité, et rien de plus. Le bloc entier respire au lieu de
   s'étirer en largeur quand la liste est courte. */
.bday-month-row { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border: 1px solid var(--tc-border-soft, #F1F3F5); border-radius: 12px; background: var(--tc-surface-soft); transition: background .12s, border-color .12s; }
.bday-month-row:hover { background: var(--tc-surface); border-color: var(--tc-border); }
.bday-month-row__photo { width: 42px; height: 42px; border-radius: 12px; object-fit: cover; flex: none; }
.bday-month-row__avatar { width: 42px; height: 42px; border-radius: 12px; font-size: 12px; flex: none; }
.bday-month-row__date { display: flex; flex-direction: column; align-items: center; justify-content: center; flex: none; width: 48px; padding: 5px 0; border-radius: 10px; background: var(--tc-surface); border: 1px solid var(--tc-border-soft, #F1F3F5); }
.bday-month-row__day { font-weight: 800; font-size: 17px; line-height: 1; color: var(--tc-red); }
.bday-month-row__month { font-size: 9.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--tc-ink-4); margin-top: 3px; }

/* =========================================================
   CALENDRIER DE PRÉSENCE (six derniers mois)
   =========================================================
   Une colonne par SEMAINE, une ligne par jour de la semaine — la lecture
   habituelle d'une carte de chaleur. Sur un mois par ligne, deux congés posés
   au même jour de deux mois différents se retrouvaient l'un sous l'autre par
   hasard, ce qui dessinait une régularité qui n'existe pas.

   Les couleurs sont portées par les classes que App\Enum\AttendanceStatus
   déclare : le service décide de l'ÉTAT, la feuille de style de la teinte. */
.att-grid {
    display: grid;
    grid-auto-flow: column;
    grid-template-rows: repeat(7, 1fr);
    gap: 3px;
    /* La grille déborde plutôt qu'elle ne se comprime : vingt-six colonnes
       écrasées sous 300 px donneraient des pastilles illisibles. */
    overflow-x: auto;
    padding-bottom: 4px;
}
.att-cell { aspect-ratio: 1; min-width: 9px; border-radius: 2px; background: var(--tc-attendance-off); }
.att-cell--present { background: var(--tc-attendance-present); }
.att-cell--partial { background: var(--tc-attendance-partial); }
.att-cell--absent { background: var(--tc-attendance-absent); }
.att-cell--off { background: var(--tc-attendance-off); }

.att-legend { display: flex; align-items: center; justify-content: flex-end; gap: 6px; margin-top: 12px; font-weight: 500; font-size: 10.5px; color: var(--tc-ink-4); }
.att-legend__swatch { width: 9px; height: 9px; border-radius: 2px; flex: none; }

/* =========================================================
   JAUGE DE COMPLÉTION DU DOSSIER
   ========================================================= */
.prof-ring { position: relative; width: 78px; height: 78px; flex: none; }
.prof-ring__value { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 15px; color: var(--tc-ink); }
.prof-ring circle { transition: stroke-dashoffset .5s ease; }

.prof-missing { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; background: #F8F9FA; border: 1px solid #F1F3F5; border-radius: 10px; padding: 9px 13px; }
.prof-missing__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--tc-red); flex: none; }
.prof-missing__label { font-weight: 600; font-size: 13px; color: var(--tc-ink); }
.prof-missing__hint { font-weight: 500; font-size: 12px; color: var(--tc-ink-4); }
.prof-missing__required { font: 600 9.5px/1 var(--tc-font-mono); letter-spacing: .08em; background: var(--tc-red-subtle); color: var(--tc-accent-ink); padding: 3px 8px; border-radius: 999px; }

/* =========================================================
   ASSISTANT EASYCH (pastille flottante)
   ========================================================= */
.app-assistant { position: fixed; right: 26px; bottom: 26px; z-index: 80; }
.app-assistant__launcher {
    width: 56px; height: 56px; border-radius: 50%; border: none;
    background: var(--tc-red); color: var(--tc-on-primary); cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 10px 28px rgba(var(--bs-primary-rgb), .45);
    transition: transform .15s;
}
.app-assistant__launcher:hover { transform: scale(1.06); }
.app-assistant__launcher:focus-visible { outline: 3px solid var(--tc-red-light); outline-offset: 3px; }

.app-assistant__panel {
    position: absolute; right: 0; bottom: 70px;
    width: 380px; max-width: calc(100vw - 40px);
    background: #fff; border: 1px solid var(--tc-border); border-radius: 16px;
    box-shadow: 0 18px 44px rgba(16, 20, 26, .17);
    overflow: hidden;
}
.app-assistant__head { display: flex; align-items: center; gap: 10px; padding: 14px 16px; background: var(--tc-sidebar); color: var(--tc-on-sidebar); }
.app-assistant__avatar { width: 32px; height: 32px; border-radius: 10px; background: var(--tc-red); display: inline-flex; align-items: center; justify-content: center; flex: none; }
.app-assistant__name { font-weight: 700; font-size: 13.5px; color: #fff; }
.app-assistant__meta { font-weight: 500; font-size: 10.5px; color: var(--tc-sidebar-muted); }
.app-assistant__close { border: none; background: none; color: var(--tc-sidebar-muted); cursor: pointer; display: flex; padding: 4px; border-radius: 6px; }
/* L'en-tête porte DEUX boutons — reprendre à zéro, fermer. Seul le premier
   pousse vers la droite, sinon ils se sépareraient aux deux extrémités. */
.app-assistant__head > .app-assistant__close:first-of-type { margin-left: auto; }
.app-assistant__close:hover { background: var(--tc-sidebar-hover); color: #fff; }

/* ── Le fil de la conversation ──
   Hauteur BORNÉE et défilement interne : sans cela, une réponse un peu longue
   pousse le champ de saisie hors de l'écran, et l'on ne peut plus répondre. */
.app-assistant__thread { display: flex; flex-direction: column; gap: 9px; padding: 14px 14px 4px; height: 300px; max-height: 46vh; overflow-y: auto; overscroll-behavior: contain; }
.app-assistant__bubble { max-width: 88%; border-radius: 13px; padding: 9px 12px; font-size: 12.5px; line-height: 1.55; }
.app-assistant__bubble--bot { align-self: flex-start; background: var(--tc-bg); color: var(--tc-ink); border-bottom-left-radius: 4px; }
.app-assistant__bubble--you { align-self: flex-end; background: var(--tc-red); color: var(--tc-on-primary); border-bottom-right-radius: 4px; }
.app-assistant__text { margin: 0; white-space: pre-line; }
.app-assistant__list { margin: 7px 0 0; padding: 0 0 0 15px; display: flex; flex-direction: column; gap: 3px; }
.app-assistant__list li { font-size: 12px; color: var(--tc-ink-2); }
.app-assistant__bubble--you .app-assistant__list li { color: #fff; }
/* Les renvois vers les écrans qui font foi : toujours au pied de la réponse. */
.app-assistant__links { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.app-assistant__link { display: inline-flex; align-items: center; background: #fff; border: 1px solid var(--tc-border); border-radius: 999px; padding: 5px 11px; font-weight: 600; font-size: 11.5px; color: var(--tc-accent-ink); text-decoration: none; }
.app-assistant__link:hover { background: var(--tc-red-subtle); border-color: var(--tc-red-border); color: var(--tc-accent-ink); }

/* Les suggestions : personne ne devine ce qu'un assistant sait faire. */
.app-assistant__chips { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 14px 0; }
.app-assistant__chips:empty { display: none; }
.app-assistant__chip { border: 1px solid var(--tc-border); background: #fff; border-radius: 999px; padding: 6px 11px; font-weight: 600; font-size: 11.5px; color: var(--tc-ink-2); cursor: pointer; }
.app-assistant__chip:hover { background: var(--tc-red-subtle); border-color: var(--tc-red-border); color: var(--tc-accent-ink); }

.app-assistant__composer { display: flex; align-items: center; gap: 8px; margin: 10px 14px 0; padding: 7px 8px 7px 13px; background: var(--tc-bg); border: 1px solid var(--tc-border); border-radius: 12px; }
.app-assistant__composer:focus-within { border-color: var(--tc-red-border); }
.app-assistant__composer input { flex: 1; min-width: 0; border: none; background: none; outline: none; font-size: 12.5px; color: var(--tc-ink); }
.app-assistant__composer input::placeholder { color: var(--tc-ink-4); }
.app-assistant__send { width: 30px; height: 30px; border: none; border-radius: 9px; background: var(--tc-red); color: var(--tc-on-primary); cursor: pointer; display: flex; align-items: center; justify-content: center; flex: none; }
.app-assistant__send:hover { background: var(--tc-red-hover); }

.app-assistant__note { font-size: 10.5px; line-height: 1.5; color: var(--tc-ink-4); margin: 10px 0 0; padding: 0 14px 14px; }

/* Mode sombre : le panneau, les puces et les liens étaient sur fond blanc ; le
   teal --tc-red y devient illisible en texte, on passe à --tc-red-light. */
[data-bs-theme="dark"] .app-assistant__panel { background: var(--tc-surface); }
[data-bs-theme="dark"] .app-assistant__link,
[data-bs-theme="dark"] .app-assistant__chip { background: var(--tc-surface); }
[data-bs-theme="dark"] .app-assistant__link,
[data-bs-theme="dark"] .app-assistant__link:hover,
[data-bs-theme="dark"] .app-assistant__chip:hover { color: var(--tc-red-light); }

/* La pastille ne doit pas recouvrir le contenu sur petit écran. */
@media (max-width: 575.98px) {
    .app-assistant { right: 16px; bottom: 16px; }
    .app-assistant__launcher { width: 50px; height: 50px; }
}

/* ---------------------------------------------------------------------------
   EME — composition d'une campagne.

   Une ligne par exploitant, avec sa case « en lice » et son point focal. Les
   états se lisent d'un coup d'œil : ce qui est SORTI de la campagne s'efface,
   ce qui est en lice SANS ÉVALUATEUR se signale — c'est le seul manque qui
   empêche de lancer la saisie, et le découvrir au moment du refus fait
   remonter toute la liste.
   ------------------------------------------------------------------------- */
.ecomp { display: flex; flex-direction: column; }
.ecomp__row {
    display: grid;
    /* La case « en lice » est masquée et SORT du flux (position absolue) : elle
       n'occupe donc pas de colonne. En lui en réservant une, tout se décalait
       d'un cran et le nom atterrissait dans la colonne de 30 px. */
    grid-template-columns: 30px minmax(0, 1fr) 190px 34px;
    align-items: center;
    gap: 10px;
    padding: 8px 6px;
    border-top: 1px solid var(--tc-border);
    border-left: 2px solid transparent;
    transition: opacity .12s ease, background-color .12s ease;
}
.ecomp__row:first-child { border-top: none; }
.ecomp__row.is-out { opacity: .45; }
.ecomp__row.is-unassigned { border-left-color: var(--tc-danger-ink); background: var(--tc-danger-bg); }
.ecomp__pick { display: flex; align-items: center; margin: 0; }
.ecomp__who { min-width: 0; display: flex; flex-direction: column; }
.ecomp__name { font-weight: 600; font-size: 12.5px; color: var(--tc-ink); text-decoration: none; }
.ecomp__name:hover { color: var(--tc-accent-ink); text-decoration: underline; }
.ecomp__position { font-size: 11px; color: var(--tc-ink-4); }
.ecomp__state { text-decoration: none; justify-self: end; }

.ecomp__name { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ecomp__position { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

@media (max-width: 860px) {
    .ecomp__row { grid-template-columns: 30px minmax(0, 1fr) 34px; grid-template-areas: 'avatar who remove' '. assessor assessor'; }
    .ecomp__who { grid-area: who; }
    .ecomp__assessor { grid-area: assessor; }
    .ecomp__remove, .ecomp__restore { grid-area: remove; }
}

/* Les préalables au lancement d'une campagne. */
.echeck { list-style: none; margin: 0; padding: 0; }
.echeck__item { display: flex; align-items: center; gap: 8px; padding: 5px 0; font-size: 12.5px; color: var(--tc-ink-4); }
.echeck__item.is-done { color: var(--tc-ink); }
.echeck__mark { flex: none; display: inline-flex; color: var(--tc-ink-4); }
.echeck__item.is-done .echeck__mark { color: #28A745; }
.echeck__label { flex: 1 1 auto; }
.echeck__detail { font-variant-numeric: tabular-nums; font-weight: 600; font-size: 12px; }

/* ---------------------------------------------------------------------------
   EME — tableau croisé exploitants × axes.

   Les cases se lisent par rapport à la MOYENNE du groupe, pas dans l'absolu :
   un 16/20 est bon si le groupe est à 14, médiocre s'il est à 18. Le fond dit
   ce rapport, le chiffre reste lisible tel quel.
   ------------------------------------------------------------------------- */
.ecmp__who { position: sticky; left: 0; background: var(--tc-surface); z-index: 1; min-width: 150px; }
.ecmp__cell { font-variant-numeric: tabular-nums; font-size: 12.5px; border-radius: 6px; }
/* Écart à la moyenne : les deux familles SÉMANTIQUES, pas la charte. Elles
   portaient des littéraux (`rgba(40,167,69,.10)` / `#1c7430`) qui n'avaient
   aucune variante sombre : en mode sombre, le vert foncé s'affichait sur une
   surface presque noire, illisible. Les familles, elles, sont définies dans
   les deux thèmes. */
.ecmp__cell.is-up { background: var(--tc-green-bg); color: var(--tc-green-ink); font-weight: 600; }
.ecmp__cell.is-down { background: var(--tc-danger-bg); color: var(--tc-danger-ink); font-weight: 600; }
.ecmp__average td { border-top: 2px solid var(--tc-border); font-weight: 700; font-size: 12px; color: var(--tc-ink-4); font-variant-numeric: tabular-nums; }
.ecmp__key { display: inline-block; width: 10px; height: 10px; border-radius: 3px; }
.ecmp__key--up { background: var(--tc-green-ink); }
.ecmp__key--down { background: var(--tc-danger-ink); }

/* ---------------------------------------------------------------------------
   EME — saisie d'une grille.

   Un bouton DÉSACTIVÉ doit se voir comme tel : « Soumettre l'évaluation »
   restait rouge vif tant que la grille était incomplète, donc parfaitement
   cliquable à l'œil, et le clic ne faisait rien.

   Une note RAMENÉE au barème se signale : le serveur borne de toute façon, et
   le faire en silence laissait croire qu'un 9 avait été retenu sur une ligne
   notée sur 2.
   ------------------------------------------------------------------------- */
.btn-tc:disabled,
.btn-tc[disabled] { opacity: .45; cursor: not-allowed; box-shadow: none; }
.btn-tc-outline:disabled,
.btn-tc-outline[disabled] { opacity: .5; cursor: not-allowed; }

.form-control.is-clamped { border-color: var(--tc-danger-ink); background: var(--tc-danger-bg); }

/* ---------------------------------------------------------------------------
   Bouton TERTIAIRE — action discrète dans une ligne ou un pied de carte.

   La classe était employée par le module EME sans jamais avoir été définie :
   les boutons se rendaient bruts, gris système, bordure biseautée. Ils
   juraient au milieu d'écrans par ailleurs soignés.
   ------------------------------------------------------------------------- */
.btn-tc-ghost {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 7px 12px;
    font-weight: 600; font-size: 12.5px;
    color: var(--tc-ink-3);
    background: transparent;
    border: 1px solid transparent;
    border-radius: 8px;
    cursor: pointer;
    text-decoration: none;
    transition: background .12s, color .12s, border-color .12s;
}
.btn-tc-ghost:hover { background: var(--tc-bg); color: var(--tc-ink); border-color: var(--tc-border); }
.btn-tc-ghost:disabled, .btn-tc-ghost[disabled] { opacity: .45; cursor: not-allowed; }
.btn-tc-ghost.text-danger:hover { background: var(--tc-danger-bg); border-color: var(--tc-danger-border); }

/* ---------------------------------------------------------------------------
   EME — les écrans d'une campagne, présentés en cartes.

   Elles remplacent les sous-onglets : une carte peut dire ce qu'on y fait ET
   où ça en est — « 20 exploitants », « 12 / 20 arbitrées » — ce qu'un onglet
   ne portait pas.
   ------------------------------------------------------------------------- */
.eme-sections { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.eme-section {
    display: flex; align-items: center; gap: 13px;
    padding: 16px 18px;
    background: var(--tc-surface, #fff);
    border: 1px solid var(--tc-border);
    border-radius: 12px;
    text-decoration: none;
    transition: border-color .12s, box-shadow .12s, transform .12s;
}
.eme-section:hover {
    border-color: var(--tc-red);
    box-shadow: 0 4px 16px rgba(0, 0, 0, .06);
    transform: translateY(-1px);
}
.eme-section__icon {
    flex: none; width: 38px; height: 38px; border-radius: 11px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--tc-red-subtle); color: var(--tc-accent-ink);
}
.eme-section__body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.eme-section__label { font-weight: 700; font-size: 13.5px; color: var(--tc-ink); }
.eme-section__hint { font-size: 11.5px; color: var(--tc-ink-4); }
.eme-section__chevron { flex: none; color: var(--tc-ink-4); }
.eme-section:hover .eme-section__chevron { color: var(--tc-accent-ink); }

/* EME — les exploitants retirés de la campagne, prêts à revenir. */
.ecomp-retired { border-top: 1px dashed var(--tc-border); padding-top: 12px; }
.ecomp-retired__head { font-size: 11px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--tc-ink-4); margin-bottom: 6px; display: flex; align-items: center; gap: 6px; }
.ecomp__remove:hover { color: var(--tc-accent-ink); }
.ecomp__restore:hover { color: #1c7430; }

/* EME — l'état vide d'une liste qu'on vient de commencer à composer. */
.eme-empty { text-align: center; padding: 34px 20px; }
.eme-empty__icon { display: inline-flex; align-items: center; justify-content: center; width: 54px; height: 54px; border-radius: 16px; background: var(--tc-bg); color: var(--tc-ink-4); margin-bottom: 12px; }
.eme-empty__title { font-weight: 700; font-size: 13.5px; color: var(--tc-ink); }
.eme-empty__hint { font-size: 12px; color: var(--tc-ink-4); }

/* EME — personne n'est encore habilité pour ce rôle. */
.eme-nope { display: flex; gap: 11px; align-items: flex-start; padding: 14px; border: 1px dashed var(--tc-border); border-radius: 10px; background: var(--tc-bg); }
.eme-nope__icon { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; border-radius: 10px; background: #fff; color: var(--tc-ink-4); }

/* ---------------------------------------------------------------------------
   Champ à étiquettes ENCADRÉ, hors modale.

   `.chips-field` est volontairement sans bordure : dans la messagerie et le
   registre du courrier, c'est le conteneur qui fournit le cadre. Employé seul
   sur une page, le champ devenait invisible — un placeholder gris flottant au
   milieu d'une carte, que personne ne prend pour une zone de saisie.

   L'icône de loupe dit ce que le cadre ne dit pas : qu'on peut CHERCHER là.
   ------------------------------------------------------------------------- */
.chips-field--framed {
    position: relative;
    width: 100%;
    box-sizing: border-box;
    border: 1px solid var(--tc-border);
    border-radius: 10px;
    padding: 7px 12px 7px 34px;
    background: var(--tc-surface);
    transition: border-color .12s, box-shadow .12s;
}
.chips-field--framed:focus-within { border-color: var(--tc-red); box-shadow: 0 0 0 3px var(--tc-red-soft); }
.chips-field--framed::before {
    content: '';
    position: absolute;
    left: 12px;
    top: 50%;
    width: 15px;
    height: 15px;
    margin-top: -7px;
    pointer-events: none;
    background: currentColor;
    color: var(--tc-ink-4);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E") center / contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E") center / contain no-repeat;
}
/* La loupe se place au niveau de la PREMIÈRE ligne quand les étiquettes
   débordent sur plusieurs rangées : la centrer verticalement la ferait
   descendre au milieu d'un bloc de quinze noms. */
.chips-field--framed { min-height: 40px; }
.chips-field--framed:has(.ts-control > .item:nth-child(4))::before { top: 20px; margin-top: 0; }

/* ---------------------------------------------------------------------------
   EME — le diaporama de proclamation, projeté devant l'équipe.

   Tout y est dimensionné pour être lu À DISTANCE, depuis le fond d'une salle :
   les tailles sont volontairement plus grandes qu'ailleurs dans l'application,
   et une diapositive ne porte qu'une idée. C'est la contrainte d'un écran
   qu'on regarde debout, pas d'une page qu'on consulte assis.
   ------------------------------------------------------------------------- */
.eslide { max-width: 860px; width: 100%; }
.eslide--center { text-align: center; }
.eslide__eyebrow { font-size: 12px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--tc-red-light); margin-bottom: 12px; }
.eslide__title { font-weight: 800; font-size: 40px; line-height: 1.15; margin: 0 0 10px; }
.eslide__heading { font-weight: 800; font-size: 28px; margin: 0 0 22px; }
.eslide__banner { font-weight: 800; font-size: 56px; letter-spacing: .04em; margin: 0; }
.eslide__lead { font-size: 16px; color: #ADB5BD; margin: 0; }
.eslide__note { font-size: 13px; color: #868E96; margin-top: 16px; }
.eslide__words { font-size: 17px; line-height: 1.6; color: #E9ECEF; margin: 0; }

.eslide__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; }
.eslide__member { display: flex; align-items: center; gap: 11px; background: #1e2126; border-radius: 10px; padding: 12px 15px; }
.eslide__avatar { flex: none; width: 34px; height: 34px; border-radius: 999px; background: var(--tc-red); color: var(--tc-on-primary); display: inline-flex; align-items: center; justify-content: center; font-size: 11.5px; font-weight: 700; }
.eslide__member-name { display: block; font-weight: 700; font-size: 14px; }
.eslide__member-role { display: block; font-size: 11.5px; color: #868E96; }

.eslide__facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 12px; margin: 0; }
.eslide__facts div { background: #1e2126; border-radius: 10px; padding: 16px 18px; }
.eslide__facts dt { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: #868E96; }
.eslide__facts dd { margin: 6px 0 0; font-size: 22px; font-weight: 800; font-variant-numeric: tabular-nums; }

.eslide__names { columns: 2; column-gap: 32px; margin: 0; padding-left: 22px; font-size: 17px; line-height: 2; }

/* La légende des critères : chaque axe a SA couleur d'identité (fixe, celle
   du diaporama du CEME), son total de points, et ses sous-critères en clair —
   ce code couleur IDENTIFIE l'axe, il ne juge personne. Couleur portée par la
   variable `--eaxis-color`, posée en style inline par axe. */
.eaxis-legend { display: flex; flex-direction: column; gap: 12px; }
.eaxis-legend__row { display: flex; gap: 16px; background: #1e2126; border-radius: 12px; padding: 16px 20px; border-left: 5px solid var(--eaxis-color, var(--tc-red)); }
.eaxis-legend__code { flex: none; align-self: flex-start; width: 42px; height: 42px; border-radius: 10px; background: var(--eaxis-color, var(--tc-red)); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 14px; }
.eaxis-legend__body { flex: 1 1 auto; min-width: 0; }
.eaxis-legend__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.eaxis-legend__name { font-weight: 700; font-size: 17px; }
.eaxis-legend__max { flex: none; font-size: 13px; font-weight: 700; color: var(--eaxis-color, #868E96); font-variant-numeric: tabular-nums; }
.eaxis-legend__list { columns: 2; column-gap: 24px; margin: 8px 0 0; padding-left: 18px; font-size: 13px; color: #ADB5BD; line-height: 1.7; }

/* Le code couleur des PERFORMANCES (palier du CEME, sept crans) — celui
   qu'on retrouve ensuite sur chaque moyenne, chaque note et le rang de
   chaque lauréat. Distinct du code couleur des critères ci-dessus : celui-là
   identifie un axe, celui-ci juge un résultat. `--eapp-text` est la couleur
   de texte lisible SUR un fond plein `--eapp-color` (blanc, sauf sur le
   jaune de « bonne », trop clair pour du blanc). */
.eapp--exceptionnel { --eapp-color: #2ecc71; --eapp-text: #fff; --eapp-tint: rgba(46, 204, 113, .16); }
.eapp--honorable    { --eapp-color: #27ae60; --eapp-text: #fff; --eapp-tint: rgba(39, 174, 96, .16); }
.eapp--excellent    { --eapp-color: #16a085; --eapp-text: #fff; --eapp-tint: rgba(22, 160, 133, .16); }
.eapp--tres_bonne   { --eapp-color: #3498db; --eapp-text: #fff; --eapp-tint: rgba(52, 152, 219, .16); }
.eapp--bonne        { --eapp-color: #f1c40f; --eapp-text: #3d2e00; --eapp-tint: rgba(241, 196, 15, .18); }
.eapp--passable     { --eapp-color: #e67e22; --eapp-text: #fff; --eapp-tint: rgba(230, 126, 34, .18); }
.eapp--mediocre     { --eapp-color: #e74c3c; --eapp-text: #fff; --eapp-tint: rgba(231, 76, 60, .18); }
.eapp--none         { --eapp-color: #868E96; --eapp-text: #fff; --eapp-tint: rgba(134, 142, 150, .16); }

.eslide__scale { display: flex; flex-direction: column; gap: 8px; }
.eslide__step { display: flex; align-items: baseline; justify-content: space-between; background: #1e2126; border-radius: 9px; padding: 12px 18px; border-left: 4px solid var(--eapp-color, transparent); }
.eslide__step-name { font-weight: 700; font-size: 16px; color: var(--eapp-color, #fff); }
.eslide__step-range { font-size: 14px; color: #868E96; font-variant-numeric: tabular-nums; }

/* La diapositive d'un lauréat : portrait à gauche, notes à droite. */
.eslide--laureate { max-width: 940px; }
.elaureate { display: grid; grid-template-columns: 220px 1fr; gap: 34px; align-items: center; }
.elaureate__portrait { position: relative; width: 220px; height: 220px; border-radius: 18px; overflow: hidden; background: #1e2126; display: flex; align-items: center; justify-content: center; }
/* La photo se pose PAR-DESSUS les initiales : si le fichier manque, le
   navigateur retire l'image et les initiales réapparaissent d'elles-mêmes. */
.elaureate__portrait img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.elaureate__initials { font-size: 56px; font-weight: 800; color: #495057; }
.elaureate__portrait--solo { width: 190px; height: 190px; margin: 0 auto; }
.elaureate__rank { position: absolute; left: 0; bottom: 0; background: var(--eapp-color, var(--tc-red)); color: var(--eapp-text, #fff); font-weight: 800; font-size: 15px; padding: 6px 14px; border-radius: 0 12px 0 0; }
.elaureate__name { font-weight: 800; font-size: 34px; margin: 0 0 8px; }
.elaureate__score { font-weight: 800; font-size: 52px; line-height: 1; color: var(--eapp-color, var(--tc-red-light)); font-variant-numeric: tabular-nums; }
.elaureate__score span { font-size: 22px; color: #868E96; }
.elaureate__appreciation { font-weight: 700; font-size: 17px; margin-top: 6px; color: var(--eapp-color, #fff); }
.elaureate__axes { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.elaureate__axis { background: var(--eapp-tint, #1e2126); border-radius: 10px; padding: 10px 16px; text-align: center; min-width: 78px; }
.elaureate__axis-code { display: block; font-size: 11px; font-weight: 700; letter-spacing: .08em; color: #868E96; }
.elaureate__axis-score { display: block; font-size: 19px; font-weight: 800; font-variant-numeric: tabular-nums; margin-top: 2px; color: var(--eapp-color, #fff); }
.elaureate__deliveries { font-size: 14px; color: #ADB5BD; margin-top: 14px; }
.elaureate__reward { display: inline-block; background: var(--tc-red-soft); color: var(--tc-red-light); font-weight: 700; font-size: 14px; padding: 8px 16px; border-radius: 999px; margin-top: 14px; }

@media (max-width: 820px) {
    .elaureate { grid-template-columns: 1fr; justify-items: center; text-align: center; gap: 20px; }
    .eslide__names { columns: 1; }
    .eslide__banner { font-size: 38px; }
    .elaureate__score { font-size: 40px; }
}

/* ---------------------------------------------------------------------------
   EME — frise du parcours de campagne (variante de `.esteps`/.estep`).

   Une seule étape est « en cours » à la fois — c'est un état séquentiel — et
   c'est elle seule qui porte le bouton d'action. Les étapes franchies restent
   cochées à côté, ce qui distingue cette frise d'un simple fil d'ariane :
   elle montre le chemin PARCOURU, pas seulement le point où l'on est.
   ------------------------------------------------------------------------- */
.eme-timeline .estep.is-current .estep__dot { background: #fff; color: var(--tc-accent-ink); border-color: var(--tc-red); }
.eme-timeline .estep.is-current .estep__label { color: var(--tc-accent-ink); }
.estep__cta { margin-top: 12px; }
.estep__blocked { font-size: 11px; color: var(--tc-ink-4); margin: 8px 0 0; line-height: 1.4; }

@media (max-width: 767px) {
    .eme-timeline .estep__cta { display: flex; flex-direction: column; align-items: center; }
}

/* EME — la ligne de l'historique qu'on est en train de regarder. */
.eme-history-row--active { background: var(--tc-red-subtle); }

/* ---------------------------------------------------------------------------
   Planning — infobulle des barres d'absence (contrôleur `planning-bar`).

   Suit la souris (position fixed) car la grille défile horizontalement : une
   infobulle ancrée à la barre sortirait de la zone visible. Le contenu est
   alimenté sans aller-retour serveur depuis les data-* de la barre.
   ------------------------------------------------------------------------- */
.planning-bar-tip {
    display: none;
    position: fixed;
    z-index: 1090;
    max-width: 320px;
    background: #fff;
    border: 1px solid var(--tc-border, #E4E7EC);
    border-radius: 10px;
    box-shadow: 0 10px 30px rgba(16, 20, 26, .16);
    padding: 10px 12px;
    font-size: 12px;
    color: var(--tc-ink, #31343C);
    pointer-events: none;
}
.planning-bar-tip__row {
    display: flex;
    align-items: center;
    gap: 7px;
    line-height: 1.5;
}
.planning-bar-tip__row + .planning-bar-tip__row {
    margin-top: 3px;
}
.planning-bar-tip__dot {
    width: 8px;
    height: 8px;
    border-radius: 3px;
    flex: none;
}

/* `[hidden]` doit l'emporter sur `display: flex` : sans cette règle, un élément
   masqué par l'attribut restait visible — le contrôleur retire la ligne « motif »
   de l'infobulle en le marquant `hidden`, et le motif d'un collègue s'affichait
   quand même. */
.planning-bar-tip__row[hidden] {
    display: none;
}

/* Mode sombre : l'infobulle du planning était sur fond blanc. Le texte et la
   bordure utilisent déjà les tokens ; seul le fond manquait, et l'ombre devait
   être renforcée pour détacher l'infobulle du fond foncé. */
[data-bs-theme="dark"] .planning-bar-tip {
    background: var(--tc-surface);
    box-shadow: 0 10px 30px rgba(0, 0, 0, .55);
}

/* Pastille de type dans l'en-tête de la modale de détail. */
.planning-modal__dot {
    width: 9px;
    height: 9px;
    border-radius: 3px;
    display: inline-block;
}

/* ---- Planning de travail : cartes collaborateurs ---- */
/* La liste des plannings était un tableau : une ligne par salarié, sans photo
   ni contexte. Des cartes avec avatar rendent l'identité immédiatement
   reconnaissable et laissent respirer les statuts. */
.ws-cards { display: grid; grid-template-columns: 1fr; gap: 10px; }
@media (min-width: 992px) {
    .ws-cards { grid-template-columns: repeat(2, 1fr); }
}
.ws-cards--compact { grid-template-columns: 1fr; }
@media (min-width: 768px) {
    .ws-cards--compact { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1200px) {
    .ws-cards--compact { grid-template-columns: repeat(3, 1fr); }
}

.ws-card {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border: 1px solid var(--tc-border);
    border-radius: 12px;
    background: var(--tc-surface);
    color: inherit;
    text-decoration: none;
    min-width: 0;
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.ws-card:hover {
    border-color: var(--tc-red);
    box-shadow: 0 6px 18px rgba(22, 50, 60, .08);
    transform: translateY(-1px);
}

.ws-card__avatar {
    flex: none;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--tc-red);
    color: var(--tc-on-primary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 14px;
    text-transform: uppercase;
    position: relative;
}
.ws-card__avatar img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

.ws-card__body { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.ws-card__name { font-weight: 700; font-size: 14px; color: var(--tc-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ws-card__meta { font-size: 11.5px; color: var(--tc-ink-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-height: 15px; }
.ws-card__tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }

.ws-card__total { flex: none; text-align: right; display: flex; flex-direction: column; align-items: flex-end; }
.ws-card__hours { font-weight: 800; font-size: 16px; color: var(--tc-ink); line-height: 1.1; }
.ws-card__unit { font-size: 10.5px; color: var(--tc-ink-4); text-transform: uppercase; letter-spacing: .04em; }

.ws-card--add { border-style: dashed; background: var(--tc-surface-soft); }
.ws-card--add:hover { background: var(--tc-surface); }
.ws-card__cta {
    flex: none;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(var(--bs-primary-rgb), .12);
    color: var(--tc-red);
}

/* Liste compacte des collaborateurs flexibles. */
.ws-mini-list { display: flex; flex-direction: column; gap: 2px; }
.ws-mini {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 7px 0;
    border-bottom: 1px solid var(--tc-border);
    min-width: 0;
}
.ws-mini:last-child { border-bottom: 0; }
.ws-mini__avatar {
    flex: none;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    overflow: hidden;
    background: var(--tc-red);
    color: var(--tc-on-primary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 11px;
    text-transform: uppercase;
    position: relative;
}
.ws-mini__avatar img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ws-mini__name { flex: 1; font-weight: 600; font-size: 13px; color: var(--tc-ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

/* ---- Planning de travail : carte portant des actions ---- */
/* Les lignes de duplication portent des boutons, pas un lien. La carte garde
   le dessin des autres (marge, bordure, avatar, nom) mais ne se lève pas au
   survol : ce n'est pas une cible de clic, et une carte qui semble cliquable
   sans l'être est un piège. */
.ws-card--action { cursor: default; flex-wrap: wrap; row-gap: 10px; }
.ws-card--action:hover { border-color: var(--tc-border); box-shadow: none; transform: none; }
.ws-card__actions { flex: none; display: flex; flex-wrap: wrap; gap: 6px; margin-left: auto; }
/* Les lignes de duplication portent trois actions : en deux colonnes, le nom
   du collaborateur se retrouve squeezed à quelques dizaines de pixels et
   disparaît derrière une ellipse. Elles restent donc sur une ligne chacune,
   sur toute la largeur de la carte. */
.ws-cards--actions { grid-template-columns: 1fr; }
/* Sur téléphone, les actions passent à la ligne : elles restent alors
   alignées à gauche, sous le nom, plutôt qu'en bord de carte. */
@media (max-width: 575.98px) {
    .ws-card__actions { margin-left: 0; width: 100%; }
}

/* Variante compacte des boutons : les trois actions de duplication tiennent
   sur une ligne de carte sans peser sur le nom. */
.btn-tc-sm { padding: 6px 11px; font-size: 11.5px; border-radius: 7px; }

/* ---- Planning de travail : recherche par nom ---- */
/* Le dessin est celui de la recherche du planning des absences
   (`.planning-search`) : pastille arrondie, loupe, input sans bordure. Un
   même geste de filtrage ne doit pas avoir deux allure selon la page. */
.ws-search {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 230px;
    max-width: 100%;
    padding: 5px 14px;
    background: var(--tc-bg);
    border: 1px solid var(--tc-border);
    border-radius: 999px;
    transition: border-color .15s ease;
}
.ws-search__icon { flex: none; color: var(--tc-ink-4); transition: color .15s ease; }
/* Le focus est porté par la MARQUE (`:focus-within` : c'est le conteneur qui
   l'encadre, pas le champ seul), et la loupe se teinte du même ton. */
.ws-search:focus-within { border-color: var(--tc-accent-ink); }
.ws-search:focus-within .ws-search__icon { color: var(--tc-accent-ink); }
.ws-search__input {
    min-width: 0;
    width: 100%;
    border: none;
    background: none;
    outline: none;
    font-weight: 500;
    font-size: 13px;
    line-height: 1.4;
    color: var(--tc-ink);
}
.ws-search__input::placeholder { color: var(--tc-ink-4); }

/* Aucun nom ne correspond : le message est dans la carte, pas à côté. */
.ws-filter-empty {
    padding: 18px 0 6px;
    text-align: center;
    font-size: 13px;
    color: var(--tc-ink-4);
}

/* `[hidden]` doit l'emporter sur le `display` des classes : le navigateur
   masque un élément `[hidden]` par une règle de son propre style, que le
   `display: flex` de `.ws-card` — qui vient de l'auteur — écrase. Sans cette
   règle, la recherche ne masquait aucune carte. */
.ws-card[hidden], .ws-mini[hidden] { display: none; }

/* ---- Duplication d'un planning : en-tête et liste des semaines ---- */
.ws-dup-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.ws-dup-head__source {
    margin-left: auto;
    text-align: right;
    padding-left: 16px;
    border-left: 1px solid var(--tc-border);
}
@media (max-width: 575.98px) {
    .ws-dup-head__source { margin-left: 0; text-align: left; padding-left: 0; border-left: 0; }
}

/* Une semaine = une ligne cliquable, la case à cocher en tête. La ligne colorée
   dit d'un coup d'œil ce qui sera créé (libre) et ce qui serait écrasé
   (conflit), sans avoir à lire chaque pastille. */
.ws-dup-list { display: flex; flex-direction: column; gap: 8px; }
.ws-dup-week {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 11px 14px;
    border: 1px solid var(--tc-border);
    border-radius: 11px;
    cursor: pointer;
    margin: 0;
    transition: border-color .15s ease, background .15s ease;
}
.ws-dup-week:hover { border-color: var(--tc-red); }
.ws-dup-week.is-free { background: var(--tc-surface-soft); }
.ws-dup-week.is-conflict:has(.form-check-input:checked) { background: var(--tc-amber-bg); border-color: var(--tc-amber-border); }
.ws-dup-week:has(.form-check-input:checked) { border-color: var(--tc-red); }

.ws-dup-week__range { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.ws-dup-week__day { font-weight: 700; font-size: 13.5px; color: var(--tc-ink); white-space: nowrap; }
.ws-dup-week__sep { color: var(--tc-ink-4); }
.ws-dup-week__meta { display: flex; flex-wrap: wrap; gap: 6px; }
.ws-dup-week__hours { flex: none; text-align: right; font-weight: 700; font-size: 13px; color: var(--tc-ink); white-space: nowrap; }

@media (max-width: 575.98px) {
    .ws-dup-week { flex-wrap: wrap; }
    .ws-dup-week__range { flex-basis: 100%; }
    .ws-dup-week__hours { margin-left: auto; }
}
