:root {
  --oct-orange: #F28E13;
  --oct-orange-dark: #D97A05;
  --oct-orange-light: #FDB941;
  --oct-orange-soft: #FFF4E2;
  --oct-black: #1a1a1a;
  --oct-sidebar: #1f2430;
  --oct-sidebar-hover: #2a3040;
  --oct-text-muted: #7b8191;
  --oct-border: #e5e8ee;
  --oct-bg: #f5f6f8;
  --oct-green: #28a745;
  --oct-gray: #9ca3af;
}

/* ============================================================
   🎨 EVO-056 — Refonte UI ViaTEMPO · Bloc 1 Header
   ------------------------------------------------------------
   Section ajoutée pour la refonte topbar 2 étages + sidebar
   sections numérotées + repli rail/drawer. Tokens ONLY (aucun
   --oct-*, aucune valeur en dur). Anciennes définitions
   .sidebar*, .topbar*, .view-switcher, .user-menu, .topbar-icon
   sont commentées plus bas — à supprimer dans une future EVO
   de cleanup une fois la refonte stabilisée.
   ============================================================ */

/* ----- Topbar 2 étages -----
   Préfixe `body` pour battre la cascade legacy .topbar (lignes ~429+ neutralisées). */
body .topbar {
    position: sticky; top: 0; z-index: var(--z-sticky);
    height: var(--layout-topbar-h);
    display: flex; align-items: center; gap: var(--s-4);
    padding: 0 var(--s-6);
    background: color-mix(in srgb, var(--surface-card) 85%, transparent);
    border-bottom: 1px solid var(--border-subtle);
    backdrop-filter: saturate(1.2);
    transition: box-shadow var(--motion-base) var(--ease-standard),
                background  var(--motion-base) var(--ease-standard);
}
body .topbar.is-scrolled {
    background: color-mix(in srgb, var(--surface-card) 95%, transparent);
    box-shadow:
        0 6px 20px -8px rgba(15,14,12,.14),
        0 2px 4px  -2px rgba(15,14,12,.08);
}

/* fil d'ariane */
.topbar__crumb { display: flex; align-items: center; gap: var(--s-2); font-size: var(--t-13); }
.topbar__crumb a { color: var(--text-muted); text-decoration: none; }
.topbar__crumb a:hover { color: var(--text-strong); text-decoration: none; }
.topbar__crumb [aria-current] { color: var(--text-strong); font-weight: var(--fw-medium); }
.topbar__sep { color: var(--border-default); }

/* titre condensé : masqué au repos, révélé scrollé */
.topbar__condensed { display: none; font-weight: var(--fw-bold); font-size: var(--t-16); color: var(--text-strong); }
.topbar.is-scrolled .topbar__crumb { display: none; }
.topbar.is-scrolled .topbar__condensed { display: inline-flex; align-items: center; gap: var(--s-2); }

/* zone actions à droite */
.topbar__actions { margin-left: auto; display: flex; align-items: center; gap: var(--s-3); }

/* « Voir comme » — chip orange pâle avec select natif fondu (zéro Tom-Select).
   Le select natif est stylé en `appearance: none` + chevron CSS — aucun FOUC,
   couleurs 100% fixes, dropdown natif OS (cohérent + fiable). */
.impersonate {
    display: inline-flex; align-items: center; gap: var(--s-2);
    height: 38px; padding: 0 var(--s-3);
    border: 1px solid var(--orange-200); background: var(--orange-50); border-radius: var(--r-8);
    white-space: nowrap;
}
.impersonate__lbl {
    font: var(--fw-medium) var(--t-10)/1 var(--font-mono); letter-spacing: .08em;
    text-transform: uppercase; color: var(--brand-accent-text);
    display: inline-flex; align-items: center; gap: 5px;
    white-space: nowrap;
    cursor: default;
}
.impersonate__select {
    appearance: none; -webkit-appearance: none;
    background: transparent;
    border: none;
    color: var(--text-strong);
    font: var(--fw-medium) var(--t-13)/1 'Inter', sans-serif;
    padding: 0 var(--s-4) 0 0;
    cursor: pointer;
    /* chevron CSS — SVG inline orange foncé, aligné à droite */
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 16 16'><path fill='%23A05A07' d='M3.5 5.5L8 10l4.5-4.5z'/></svg>");
    background-repeat: no-repeat;
    background-position: right center;
    background-size: 10px;
}
.impersonate__select:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
    border-radius: var(--r-4);
}
.impersonate__select option { font-family: 'Inter', sans-serif; color: var(--text-strong); background: var(--surface-card); }

.topbar__divider { width: 1px; height: 24px; background: var(--border-subtle); }

/* compte */
.account { position: relative; }
.account__btn {
    display: inline-flex; align-items: center; gap: var(--s-2);
    height: 38px; padding: 0 var(--s-3);
    background: transparent; border: 1px solid transparent; border-radius: var(--r-8);
    cursor: pointer; color: var(--text-default);
}
.account__btn:hover { background: var(--ink-50); }
.account__id { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.15; }
.account__id b { font-size: var(--t-13); font-weight: var(--fw-medium); color: var(--text-strong); }
.account__id small { font-size: var(--t-11); color: var(--text-muted); }
.account__menu {
    position: absolute; top: calc(100% + 4px); right: 0; min-width: 240px;
    background: var(--surface-card); border: 1px solid var(--border-subtle); border-radius: var(--r-8);
    box-shadow: var(--elev-2); padding: var(--s-2); z-index: var(--z-dropdown);
    display: none; /* dropdown_controller toggle `.open` pour révéler */
}
.account__menu.open { display: block; }
.account__menu a {
    display: flex; align-items: center; gap: var(--s-2);
    padding: var(--s-2) var(--s-3); border-radius: var(--r-6);
    color: var(--text-default); text-decoration: none; font-size: var(--t-13);
}
.account__menu a:hover { background: var(--ink-50); color: var(--text-strong); text-decoration: none; }
.account__menu a.danger { color: var(--danger-base); }
.account__menu .divider { height: 1px; background: var(--border-subtle); margin: var(--s-2) 0; }
.account__menu .user-info { padding: var(--s-2) var(--s-3); }
.account__menu .user-info .name { font-weight: var(--fw-medium); color: var(--text-strong); font-size: var(--t-13); }
.account__menu .user-info .email { font-size: var(--t-12); color: var(--text-muted); }

/* avatar (utilisé dans topbar ET sidebar foot)
   Préfixe `body` pour battre la cascade legacy `.avatar { border-radius: 50% }`.
   Couleur par défaut = HEADER : fond sombre, initiales orange (cf. design Bloc 1). */
body .avatar--brand {
    width: 30px; height: 30px; border-radius: var(--r-6);
    display: grid; place-items: center;
    background: var(--ink-900); color: var(--orange-500);
    font-weight: var(--fw-bold); font-size: var(--t-12);
}

/* Avatar dans la sidebar-foot : couleur PAR RÔLE (cf. feedback_role_colors).
   Override scopé — n'affecte PAS l'avatar header. */
body .app-sidebar .sidebar-foot .avatar--brand { background: var(--orange-500); color: var(--ink-900); }
body .app-sidebar .sidebar-foot .avatar--brand.role-super-admin { background: #be185d; color: var(--ink-0); }
body .app-sidebar .sidebar-foot .avatar--brand.role-admin       { background: var(--orange-500); color: var(--ink-900); }
body .app-sidebar .sidebar-foot .avatar--brand.role-collab      { background: var(--orange-300); color: var(--ink-900); }
body .app-sidebar .sidebar-foot .avatar--brand.role-client      { background: #0284c7; color: var(--ink-0); }

/* bouton menu (rail / drawer mobile) */
.topbar__menu {
    display: none; /* visible uniquement en tablette/mobile (cf. responsive) */
    width: 34px; height: 34px; align-items: center; justify-content: center;
    background: transparent; border: 1px solid var(--border-subtle); border-radius: var(--r-8);
    color: var(--text-muted); cursor: pointer;
}
.topbar__menu:hover { color: var(--text-strong); background: var(--ink-25); }

/* Lockup ViaTEMPO topbar — visible UNIQUEMENT en état mobile C (cf. responsive) */
.topbar__lockup { display: none; }

/* Scrim — voile cliquable pour fermer le drawer mobile (§2.3 État D) */
.scrim {
    position: fixed; inset: 0;
    background: rgba(15, 14, 12, .5);
    z-index: calc(var(--z-overlay) - 1);
}
.scrim[hidden] { display: none; }

/* focus AA token, jamais outline (clippé par overflow:hidden) */
.topbar :is(a,button,select):focus-visible { outline: none; box-shadow: var(--focus-ring); border-radius: var(--r-6); }

/* ----- Sidebar espresso ----- */
.app-sidebar {
    width: var(--layout-sidebar-w);
    background: var(--ink-900); color: var(--ink-300);
    display: flex; flex-direction: column;
    position: fixed; inset: 0 auto 0 0;
    height: 100vh;
    overflow-y: auto;
    overflow-x: hidden; /* anti scroll horizontal en mode rail */
    z-index: var(--z-sidebar);
    transition: width var(--motion-base) var(--ease-standard);
}
/* Override : la marque par défaut du DS (.brand-mark) charge favicon-O.png
   (le « O » Octevia générique). Sur la sidebar ViaTEMPO on veut le sablier.
   Path direct relatif à app.css — la variable --brand-favicon-vt ne marche
   pas ici car url() dans une CSS var est résolu relative au CSS qui *utilise*
   la variable, pas à celui qui la définit (gotcha CSS connu). */
.app-sidebar .brand-mark { background-image: url("../design-system/brand/favicon-viatempo-8mMGkS6.svg"); }

.app-sidebar .sidebar-brand {
    padding: var(--s-4) var(--s-4) var(--s-3);
    background: transparent; border-bottom: 1px solid rgba(255,255,255,.06);
    position: relative;
}
.app-sidebar .sidebar-brand a { display: block; text-decoration: none; }

/* Bouton X close (drawer mobile uniquement, cf. media query <640px) */
.app-sidebar .sidebar-close {
    display: none;
    position: absolute; top: var(--s-3); right: var(--s-3);
    width: 36px; height: 36px;
    background: transparent;
    border: 1px solid rgba(255,255,255,.12);
    border-radius: var(--r-6);
    color: var(--text-on-dark);
    cursor: pointer;
    align-items: center; justify-content: center;
    font-size: 16px;
}
.app-sidebar .sidebar-close:hover { background: rgba(255,255,255,.08); border-color: rgba(255,255,255,.24); }
.app-sidebar .brand-lockup-vt-baseline,
.app-sidebar .brand-lockup-vt { display: block; width: 100%; }

/* Libellés de section — contraste AA sur fond espresso :
   --ink-500 (#4E4B46) sur --ink-900 = ~1.7:1 (fail) → --ink-300 (#A8A398) = ~7:1 (AA large OK).
   Numéros 01.→04. en orange : micro-marqueur de rythme, le label reste neutre. */
.app-sidebar .sidebar-section {
    padding: var(--s-3) var(--s-3) var(--s-2);
    font: var(--fw-medium) var(--t-11)/1 var(--font-mono);
    letter-spacing: .14em; text-transform: uppercase; color: var(--ink-300);
    text-align: left;
}
.app-sidebar .sidebar-section .num { color: var(--orange-500); margin-right: 4px; }

.app-sidebar .sidebar-nav { list-style: none; padding: 0 var(--s-2); margin: 0; }
.app-sidebar .sidebar-nav > li { margin-bottom: 2px; }
.app-sidebar .sidebar-item {
    display: flex; align-items: center; gap: var(--s-3);
    padding: var(--s-2) var(--s-3);
    border-radius: var(--r-6);
    color: var(--ink-300); text-decoration: none;
    font-size: var(--t-14);
    transition: background var(--motion-fast) var(--ease-standard), color var(--motion-fast) var(--ease-standard);
}
.app-sidebar .sidebar-item i { width: 18px; text-align: center; color: var(--ink-300); font-size: 15px; }
.app-sidebar .sidebar-item:hover { background: rgba(255,255,255,.05); color: var(--text-on-dark); text-decoration: none; }
.app-sidebar .sidebar-item:hover i { color: var(--orange-500); }
.app-sidebar .sidebar-item.is-active {
    background: var(--orange-500); color: var(--ink-900);
    font-weight: var(--fw-medium);
}
.app-sidebar .sidebar-item.is-active i { color: var(--ink-900); }

/* badge compteur (Mes CRA / Validation CRA) */
.count-badge {
    margin-left: auto;
    font: var(--fw-bold) var(--t-10)/1 var(--font-mono);
    background: rgba(255,255,255,.08); color: var(--ink-300);
    padding: 2px 7px; border-radius: var(--r-pill);
    flex-shrink: 0;
}
.count-badge--warning { background: var(--orange-500); color: var(--ink-900); }
.count-badge--danger  { background: var(--danger-base); color: var(--ink-0); }
.app-sidebar .sidebar-item.is-active .count-badge {
    background: rgba(0,0,0,.18); color: var(--ink-900);
}

/* sous-menus EVO-007 (Mes CRA → Nouveau CRA, Mes absences → Nouvelle absence) */
.app-sidebar .sidebar-subnav { list-style: none; padding: 0; margin: 0; }
.app-sidebar .sidebar-subnav li a {
    display: flex; align-items: center; gap: 10px;
    padding: 6px var(--s-3) 6px 44px;
    color: var(--ink-400); font-size: var(--t-12);
    text-decoration: none;
    position: relative; border-radius: var(--r-4);
}
.app-sidebar .sidebar-subnav li a::before {
    content: ""; position: absolute; left: 28px; top: 0; bottom: 50%;
    width: 1px; background: rgba(255,255,255,.14);
}
.app-sidebar .sidebar-subnav li a::after {
    content: ""; position: absolute; left: 28px; top: 50%;
    width: 9px; height: 1px; background: rgba(255,255,255,.14);
}
.app-sidebar .sidebar-subnav li:last-child a::before { bottom: 50%; }
.app-sidebar .sidebar-subnav li a:hover { background: rgba(255,255,255,.05); color: var(--text-on-dark); }
.app-sidebar .sidebar-subnav li a.is-active { color: var(--orange-500); font-weight: var(--fw-medium); }
.app-sidebar .sidebar-subnav li a i { width: 14px; text-align: center; font-size: 12px; }

/* pied de sidebar : avatar + nom + bouton collapse rail */
.app-sidebar .sidebar-foot {
    margin-top: auto;
    display: flex; align-items: center; gap: var(--s-2);
    padding: var(--s-3) var(--s-3) var(--s-4);
    border-top: 1px solid rgba(255,255,255,.06);
}
.app-sidebar .sidebar-foot__id { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.15; }
.app-sidebar .sidebar-foot__id b { color: var(--text-on-dark); font-size: var(--t-13); font-weight: var(--fw-medium); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.app-sidebar .sidebar-foot__id small { color: var(--ink-400); font-size: var(--t-11); }
.app-sidebar .sidebar-collapse {
    width: 28px; height: 28px; display: grid; place-items: center;
    background: transparent; border: 1px solid rgba(255,255,255,.08); border-radius: var(--r-4);
    color: var(--ink-400); cursor: pointer;
}
.app-sidebar .sidebar-collapse:hover { color: var(--orange-500); border-color: rgba(255,255,255,.18); }

/* main-content prend en compte la sidebar fixe */
.app-layout--v2 { display: flex; min-height: 100vh; }
.app-layout--v2 .main-content { flex: 1; margin-left: var(--layout-sidebar-w); display: flex; flex-direction: column; min-width: 0; min-height: 100vh; transition: margin-left var(--motion-base) var(--ease-standard); }

/* Bascule lockup full ↔ mark seul : en état normal on voit le baseline, en rail
   seul le sablier (la marque distillée du DS — éviter d'avoir le wordmark écrasé). */
.app-sidebar .lockup-rail { display: none; }

/* ----- Repli rail (sidebar 64px) — actif sur tablette ET desktop selon user toggle ----- */
@media (min-width: 768px) {
    html.sidebar-rail .app-sidebar { width: var(--layout-sidebar-collapsed-w); }
    html.sidebar-rail .app-sidebar .nav-label,
    html.sidebar-rail .app-sidebar .sidebar-section,
    html.sidebar-rail .app-sidebar .sidebar-subnav,
    html.sidebar-rail .app-sidebar .sidebar-foot__id { display: none; }
    /* count-badge en rail : devient une dot 6px collée en haut-droit de l'item
       (préserve la signalétique « action requise » sans déborder du rail 64px). */
    html.sidebar-rail .app-sidebar .sidebar-item { position: relative; }
    html.sidebar-rail .app-sidebar .count-badge {
        position: absolute; top: 6px; right: 10px;
        width: 6px; height: 6px;
        padding: 0; margin: 0;
        font-size: 0; line-height: 0;
        border-radius: 50%;
        overflow: hidden;
    }
    html.sidebar-rail .app-sidebar .sidebar-foot {
        flex-direction: column;
        align-items: center; justify-content: center;
        padding-inline: 0;
        gap: var(--s-2);
    }
    html.sidebar-rail .app-sidebar .sidebar-item { justify-content: center; padding-inline: 0; }
    html.sidebar-rail .app-sidebar .sidebar-brand { padding-inline: var(--s-2); display: flex; justify-content: center; }
    html.sidebar-rail .app-layout--v2 .main-content { margin-left: var(--layout-sidebar-collapsed-w); }
    /* Bascule lockup : full caché, mark (sablier seul) visible */
    html.sidebar-rail .app-sidebar .lockup-full { display: none; }
    html.sidebar-rail .app-sidebar .lockup-rail { display: inline-block; }
    /* Icônes nav remontées à --ink-300 (au lieu de --ink-400) pour la lisibilité rail */
    html.sidebar-rail .app-sidebar .sidebar-item i { color: var(--ink-300); }
    html.sidebar-rail .app-sidebar .sidebar-item:hover i { color: var(--orange-500); }
    /* L'item actif garde le pavé orange + icône --ink-900 (override pour ne pas être remonté à --ink-300) */
    html.sidebar-rail .app-sidebar .sidebar-item.is-active i { color: var(--ink-900); }
    /* Rotation du chevron de repli pour signaler l'état */
    html.sidebar-rail .app-sidebar .sidebar-collapse i { transform: rotate(180deg); }
    .app-sidebar .sidebar-collapse i { transition: transform var(--motion-base) var(--ease-standard); }
}

/* ----- Bouton menu topbar : visible <1024px (tablette + mobile) ----- */
@media (max-width: 1023px) {
    .topbar__menu { display: inline-flex; }
}
/* ----- État C/D mobile <=767px (§2.3 spec, breakpoint EVO-063 SL 1.1) ----- */
@media (max-width: 767px) {
    /* État C — topbar espresso compacte : sablier seul, fil d'ariane / impersonate / divider masqués.
       Safe-area-inset-top respectée (iPhone notch / Android status bar) via padding-top dynamique. */
    body .topbar {
        background: var(--ink-900);
        border-bottom: none;
        padding: env(safe-area-inset-top, 0px) var(--s-4) 0;
        color: var(--text-on-dark);
    }
    body .topbar.is-scrolled {
        background: var(--ink-900);
        box-shadow: 0 4px 12px -4px rgba(0,0,0,.4);
    }
    .topbar__crumb,
    .topbar__condensed,
    .topbar__search-lbl,
    .impersonate,
    .topbar__divider { display: none !important; }
    /* Lockup ViaTEMPO topbar — centré entre bouton menu (gauche) et actions (droite).
       margin: 0 auto absorbe l'espace des 2 côtés en flex → centrage visuel. */
    .topbar__lockup { display: inline-block; margin: 0 auto; height: 24px; width: auto; }
    /* Bouton menu : visible + version sombre cohérente avec topbar espresso */
    .topbar__menu {
        display: inline-flex;
        background: transparent;
        border-color: rgba(255,255,255,.12);
        color: var(--text-on-dark);
    }
    .topbar__menu:hover { background: rgba(255,255,255,.08); color: var(--text-on-dark); }
    /* Compte : sablier seul, dropdown reste blanc */
    .account__btn { background: transparent; color: var(--text-on-dark); }
    .account__btn:hover { background: rgba(255,255,255,.08); }
    .account__id { display: none; }
    /* Sidebar : masquée par défaut, devient drawer overlay au toggle.
       296px aligné sur le mockup EVO-063 (drawer.html) — espace pour badges count. */
    .app-sidebar {
        position: fixed; inset: 0 auto 0 0; width: 296px;
        transform: translateX(-100%);
        transition: transform var(--motion-slow) var(--ease-emphasized);
        z-index: var(--z-overlay);
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }
    html.sidebar-open .app-sidebar { transform: none; }
    /* En drawer ouvert, on garde l'état "déplié" (labels visibles, pas le rail) */
    html.sidebar-open .app-sidebar .nav-label,
    html.sidebar-open .app-sidebar .sidebar-section,
    html.sidebar-open .app-sidebar .sidebar-foot__id { display: revert; }
    html.sidebar-open .app-sidebar .lockup-full { display: block; }
    html.sidebar-open .app-sidebar .lockup-rail { display: none; }
    /* Bouton X visible quand drawer ouvert */
    html.sidebar-open .app-sidebar .sidebar-close { display: inline-flex; }
    /* Bouton repli rail (chevron) masqué en mobile drawer : pas de sens (soit ouvert, soit X-fermé) */
    .app-sidebar .sidebar-collapse { display: none; }
    /* Bouton déconnexion (SL 1.1) — visible uniquement en pied de drawer mobile */
    html.sidebar-open .app-sidebar .sidebar-foot-logout { display: inline-flex; }
    .app-layout--v2 .main-content { margin-left: 0; }
}

/* Body scroll-lock — appliqué par sidebar-toggle controller quand drawer mobile ouvert.
   Empêche le contenu derrière le scrim de scroller (gotcha tactile iOS). */
body.body-scroll-locked { overflow: hidden; touch-action: none; }

/* Bouton déconnexion mobile-only en pied de sidebar (EVO-063 SL 1.1).
   Caché par défaut (desktop = avatar dropdown topbar), révélé via la media query
   mobile quand html.sidebar-open. Style aligné sur .sidebar-collapse (cohérence). */
.app-sidebar .sidebar-foot-logout {
    display: none;
    width: 36px; height: 36px;
    background: transparent;
    border: 1px solid rgba(255,255,255,.12);
    border-radius: var(--r-6);
    color: var(--text-on-dark);
    cursor: pointer;
    align-items: center; justify-content: center;
    font-size: 16px;
    text-decoration: none;
    flex-shrink: 0;
}
.app-sidebar .sidebar-foot-logout:hover {
    background: rgba(255,255,255,.08);
    border-color: rgba(255,255,255,.24);
    color: var(--text-on-dark);
    text-decoration: none;
}

/* fin EVO-056 — Bloc 1 Header
   ============================================================ */

/* ============================================================
   🎨 EVO-057 — Refonte UI ViaTEMPO · Bloc 2 Échelle typographique
   ------------------------------------------------------------
   Classes utilitaires de hiérarchie typographique unifiée.
   Mapping sur tokens.css existants — Inter partout, Roboto Mono
   (--font-mono) uniquement pour eyebrow / données / en-têtes
   de tableaux. Le POIDS porte le sens, pas la couleur.
   ============================================================ */

.t-display {
    font: var(--fw-bold) var(--t-36)/var(--lh-tight) 'Inter', sans-serif;
    letter-spacing: var(--ls-tight);
    color: var(--text-strong);
}
.t-h1 {
    font: var(--fw-bold) var(--t-28)/var(--lh-tight) 'Inter', sans-serif;
    letter-spacing: var(--ls-tight);
    color: var(--text-strong);
}
.t-h2 {
    font: var(--fw-bold) var(--t-22)/var(--lh-snug) 'Inter', sans-serif;
    color: var(--text-strong);
}
.t-h3 {
    font: var(--fw-bold) 15px/var(--lh-snug) 'Inter', sans-serif;
    color: var(--text-strong);
}
.t-lead {
    font: var(--fw-regular) var(--t-16)/var(--lh-base) 'Inter', sans-serif;
    color: var(--text-muted);
}
.t-body {
    font: var(--fw-regular) var(--t-14)/var(--lh-base) 'Inter', sans-serif;
    color: var(--text-default);
}
/* Eyebrow — sur-titre CONTEXTUEL (période, volume), jamais la marque produit.
   La marque vit dans le lockup de la sidebar. */
.t-eyebrow {
    font: var(--fw-medium) var(--t-11)/1 var(--font-mono);
    letter-spacing: var(--ls-wide);
    text-transform: uppercase;
    color: var(--brand-accent-text);
    display: inline-flex; align-items: center; gap: var(--s-2);
}
/* En-tête de tableau — pour <th> mono compact */
.t-th {
    font: var(--fw-medium) var(--t-10)/1 var(--font-mono);
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--text-muted);
}
/* Donnée — réfs, montants, dates, jours travaillés (chiffres alignés tabular) */
.t-data {
    font-family: var(--font-mono);
    font-size: var(--t-13);
    font-variant-numeric: tabular-nums;
}

/* fin EVO-057 — Bloc 2 Échelle typographique
   ============================================================ */


* { box-sizing: border-box; }

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  background: var(--oct-bg);
  color: var(--oct-black);
  margin: 0;
  font-size: 14px;
}

a { color: var(--oct-orange); text-decoration: none; }
a:hover { color: var(--oct-orange-dark); text-decoration: underline; }

/* ========== LAYOUT ========== */
.app-layout { display: flex; min-height: 100vh; }

.sidebar {
  width: 240px;
  background: var(--oct-sidebar);
  color: #cfd3dc;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  position: fixed;
  height: 100vh;
  overflow-y: auto;
}

.sidebar-logo {
  padding: 18px 20px;
  background: #181c26;
  border-bottom: 1px solid rgba(255,255,255,0.05);
}
.sidebar-logo img, .sidebar-logo svg { max-width: 100%; height: auto; display: block; }
.sidebar-logo a { display: block; }

/* Marque ViaTEMPO — sidebar : lockup baseline du design-system */
.sidebar-brand { display: block; }
.sidebar-brand, .sidebar-brand:hover { text-decoration: none; }
.sidebar-brand .brand-lockup-vt-baseline { display: block; width: 100%; }

.sidebar-section {
  padding: 14px 20px 6px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 1.3px;
  color: #6b7280;
}

.sidebar-nav { list-style: none; padding: 0; margin: 0; }
.sidebar-nav li a {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 20px;
  color: #cfd3dc;
  font-size: 13.5px;
  border-left: 3px solid transparent;
  transition: all .15s;
}
.sidebar-nav li a:hover {
  background: var(--oct-sidebar-hover);
  color: #fff;
  text-decoration: none;
}
.sidebar-nav li a.active {
  background: var(--oct-sidebar-hover);
  color: var(--oct-orange);
  border-left-color: var(--oct-orange);
  font-weight: 600;
}
.sidebar-nav li a i { width: 18px; text-align: center; font-size: 15px; }

/* EVO-029 — Badges sidebar (« Validation CRA » admin / « Mes CRA » collab).
   La pastille colle à droite du lien (flex push avec margin-left:auto).
   Tones :
   - warning (orange) : action requise admin (CRA à valider)
   - danger (rouge) : alerte forte (CRA retournés à reprendre côté collab) */
.sidebar-badge {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  color: #fff;
  flex-shrink: 0;
}
.sidebar-badge-warning { background: var(--oct-orange); }
.sidebar-badge-danger { background: #dc3545; }
.sidebar-nav li a.active .sidebar-badge { /* badge un peu plus visible sur item actif */ }
.sidebar-nav li a:hover .sidebar-badge { filter: brightness(1.08); }

/* ============================================================
   Sous-niveaux de menu (EVO-007)
   Sous-menu toujours déplié sous un parent de `.sidebar-nav`.
   Indentation alignée sur le label du parent + connecteur
   arborescent discret (lignes verticales et horizontales).
   ============================================================ */
.sidebar-subnav {
  list-style: none;
  padding: 0;
  margin: 0;
}
.sidebar-subnav li a {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 20px 8px 50px;
  color: #a8acb6;
  font-size: 12.5px;
  border-left: 3px solid transparent;
  position: relative;
  transition: all .15s;
}
.sidebar-subnav li a::before {
  /* Trait vertical du connecteur — démarre du haut du <li> jusqu'au milieu */
  content: "";
  position: absolute;
  left: 32px;
  top: 0;
  bottom: 50%;
  width: 1px;
  background: rgba(255, 255, 255, 0.14);
}
.sidebar-subnav li a::after {
  /* Branche horizontale du connecteur jusqu'à l'icône */
  content: "";
  position: absolute;
  left: 32px;
  top: 50%;
  width: 9px;
  height: 1px;
  background: rgba(255, 255, 255, 0.14);
}
.sidebar-subnav li:last-child a::before {
  /* Dernier enfant : le trait vertical s'arrête à mi-hauteur, pas en bas */
  bottom: 50%;
}
.sidebar-subnav li a:hover {
  background: var(--oct-sidebar-hover);
  color: #fff;
  text-decoration: none;
}
.sidebar-subnav li a.active {
  background: var(--oct-sidebar-hover);
  color: var(--oct-orange);
  border-left-color: var(--oct-orange);
  font-weight: 600;
}
.sidebar-subnav li a i {
  width: 14px;
  text-align: center;
  font-size: 12px;
}

.main-content {
  flex: 1;
  margin-left: 240px;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 100vh;
}
.page { flex: 1; }

/* ========== TOPBAR ========== */
.topbar {
  background: #fff;
  height: 62px;
  border-bottom: 1px solid var(--oct-border);
  display: flex; align-items: center;
  padding: 0 24px;
  gap: 16px;
  position: sticky; top: 0; z-index: 10;
}
.topbar .search {
  flex: 1; max-width: 340px;
  position: relative;
}
.topbar .search input {
  width: 100%;
  border: 1px solid var(--oct-border);
  border-radius: 6px;
  padding: 8px 12px 8px 36px;
  font-size: 13px;
  background: var(--oct-bg);
}
.topbar .search i {
  position: absolute; left: 12px; top: 50%;
  transform: translateY(-50%);
  color: var(--oct-text-muted);
}
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 18px; }

/* EVO-030 — Sélecteur « Voir comme » (admin) dans le topbar.
   Inline avec le user-menu, label discret + Tom-select 220px. */
.view-switcher {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px;
}
.view-switcher-label {
  color: var(--oct-text-muted);
  white-space: nowrap;
  display: flex; align-items: center; gap: 5px;
}
.view-switcher .ts-control {
  min-width: 220px;
  padding: 5px 10px;
  border-radius: 6px;
  border-color: var(--oct-border);
  font-size: 13px;
}
.view-switcher .ts-dropdown { font-size: 13px; }
@media (max-width: 900px) {
  .view-switcher-label { display: none; }
  .view-switcher .ts-control { min-width: 160px; }
}

/* EVO-030 — Bandeau global d'impersonnation, en haut de chaque page. */
.view-switcher-banner {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px; margin-bottom: 14px;
  background: var(--oct-orange-soft);
  border: 1px solid var(--oct-orange-light);
  border-left: 4px solid var(--oct-orange);
  border-radius: 6px;
  color: var(--oct-orange-dark);
  font-size: 13px;
}
.view-switcher-banner i.bi-eye-fill { font-size: 18px; }
.view-switcher-banner span { flex: 1; }
.view-switcher-banner-form { margin: 0; }

.topbar-icon {
  position: relative;
  color: var(--oct-text-muted);
  cursor: pointer;
  font-size: 18px;
}
.topbar-icon .badge {
  position: absolute; top: -6px; right: -8px;
  background: var(--oct-orange);
  color: #fff; font-size: 9px; font-weight: 700;
  border-radius: 10px; padding: 2px 5px;
}
.user-menu {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 10px;
  border-radius: 6px;
  cursor: pointer;
}
.user-menu:hover { background: var(--oct-bg); }
.user-menu .avatar {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--oct-orange);
  color: #fff;
  font-weight: 600;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px;
}
.user-menu .name { font-size: 13px; font-weight: 500; }

/* ========== PAGE ========== */
.page {
  padding: 24px 28px;
  flex: 1;
}
.page-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 20px;
}
.page-title {
  font-size: 20px;
  font-weight: 700;
  margin: 0;
}
.page-subtitle {
  color: var(--oct-text-muted);
  font-size: 13px;
  margin-top: 2px;
}

/* ========== CARDS ========== */
.card {
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 8px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.03);
}
.card-body { padding: 18px 20px; }
.card-header {
  padding: 14px 20px;
  border-bottom: 1px solid var(--oct-border);
  font-weight: 600;
  display: flex; align-items: center; justify-content: space-between;
}

/* KPI cards */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 20px;
}
.kpi {
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 8px;
  padding: 18px;
  position: relative;
  overflow: hidden;
}
.kpi-label { color: var(--oct-text-muted); font-size: 12px; text-transform: uppercase; letter-spacing: .5px; }
.kpi-value { font-size: 26px; font-weight: 700; margin: 6px 0 4px; }
.kpi-delta { font-size: 12px; color: var(--oct-green); }
.kpi-delta.neg { color: #dc3545; }
.kpi .kpi-icon {
  position: absolute; right: 14px; top: 18px;
  width: 40px; height: 40px; border-radius: 10px;
  background: var(--oct-orange-soft);
  color: var(--oct-orange);
  display: flex; align-items: center; justify-content: center;
  font-size: 20px;
}
.kpi .progress {
  height: 6px; background: var(--oct-bg); border-radius: 3px; margin-top: 10px; overflow: hidden;
}
.kpi .progress-bar { height: 100%; background: var(--oct-orange); }

/* ========== BUTTONS ========== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 36px;
  padding: 0 14px;
  border-radius: 7px;
  font-size: 13px;
  font-weight: 500;
  border: 1px solid transparent;
  cursor: pointer;
  transition: all .15s;
  text-decoration: none;
  white-space: nowrap;
  line-height: 1;
}
.btn:hover { text-decoration: none; }
.btn i { font-size: 14px; line-height: 1; }
.btn:focus-visible { outline: 2px solid var(--oct-orange); outline-offset: 2px; }

/* Primary (orange) — action principale */
.btn-primary { background: var(--oct-orange); color: #fff; box-shadow: 0 1px 2px rgba(242,142,19,0.25); }
.btn-primary:hover { background: var(--oct-orange-dark); color: #fff; box-shadow: 0 3px 8px rgba(242,142,19,0.35); }

/* Success (vert plein) — validation */
.btn-success { background: var(--oct-green); color: #fff; box-shadow: 0 1px 2px rgba(40,167,69,0.25); }
.btn-success:hover { background: #1d7f3d; color: #fff; box-shadow: 0 3px 8px rgba(40,167,69,0.35); }

/* Danger plein — destructif */
.btn-danger { background: #dc3545; color: #fff; }
.btn-danger:hover { background: #b8213a; color: #fff; }

/* Danger outline — action négative douce (retourner au collaborateur) */
.btn-danger-outline { background: #fff; color: #b8213a; border-color: #f5c2c7; }
.btn-danger-outline:hover { background: #fde8e8; color: #9c2030; border-color: #f1a4ac; }

/* Warning outline — rétracter (auteur) */
.btn-warning { background: #fff; color: var(--oct-orange-dark); border-color: var(--oct-orange-light); }
.btn-warning:hover { background: var(--oct-orange-soft); color: var(--oct-orange-dark); border-color: var(--oct-orange); }

/* Outline neutre (conservé pour rétrocompat) */
.btn-outline { background: #fff; color: var(--oct-black); border-color: var(--oct-border); }
.btn-outline:hover { background: var(--oct-bg); color: var(--oct-black); }

/* Ghost — utilitaires peu saillants (Retour, PDF) */
.btn-ghost { background: transparent; color: var(--oct-text-muted); border-color: transparent; }
.btn-ghost:hover { background: var(--oct-bg); color: var(--oct-black); border-color: var(--oct-border); }

.btn-sm { height: 30px; padding: 0 10px; font-size: 12px; border-radius: 6px; }
.btn-icon { padding: 6px 8px; color: var(--oct-text-muted); background: transparent; border: none; height: auto; cursor: pointer; text-decoration: none; }
.btn-icon:hover { color: var(--oct-orange); background: var(--oct-orange-soft); text-decoration: none; }

/* ========== TABS ========== */
.tabs {
  display: flex;
  gap: 2px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--oct-border);
  padding-bottom: 0;
}
.tab {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 18px;
  font-size: 13px;
  font-weight: 500;
  color: var(--oct-text-muted);
  text-decoration: none;
  border-bottom: 3px solid transparent;
  margin-bottom: -1px;
  transition: all .15s;
}
.tab:hover { color: var(--oct-black); background: var(--oct-bg); text-decoration: none; }
.tab-active {
  color: var(--oct-orange-dark);
  border-bottom-color: var(--oct-orange);
  font-weight: 600;
}
.tab-active:hover { color: var(--oct-orange-dark); background: transparent; }
.tab-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 22px;
  padding: 0 7px;
  border-radius: 11px;
  background: var(--oct-border);
  color: var(--oct-text-muted);
  font-size: 11px;
  font-weight: 700;
}
.tab-active .tab-count { background: var(--oct-orange); color: #fff; }
.tab-count-alert { background: var(--oct-orange); color: #fff; animation: pulse 1.6s infinite; }
@keyframes pulse {
  0%,100% { box-shadow: 0 0 0 0 rgba(242,142,19,0.4); }
  50%     { box-shadow: 0 0 0 4px rgba(242,142,19,0); }
}

/* ========== BTN PDF ========== */
.btn-pdf {
  background: #fff;
  color: #c62828;
  border: 1px solid #ffcdd2;
}
.btn-pdf:hover { background: #fde8e8; color: #b71c1c; border-color: #ef9a9a; }
.btn-pdf i { color: #d32f2f; font-size: 16px; }

/* ========== BTN LG ========== */
.btn-lg { height: 42px; padding: 0 20px; font-size: 14px; font-weight: 600; }

/* ========== AVATAR ========== */
/* Base : cercle orange avec initiales blanches, centré. */
.avatar {
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--oct-orange);
  color: #fff;
  font-weight: 600;
  font-size: 12px;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  letter-spacing: 0;
}
.avatar-sm { width: 28px; height: 28px; font-size: 10px; }
.avatar-md { width: 40px; height: 40px; font-size: 14px; }
.avatar-lg { width: 56px; height: 56px; font-size: 18px; }

/* Variante neutre sur fond sombre (ex. si besoin en overlay) */
.avatar-dark { background: var(--oct-sidebar); color: var(--oct-orange); }

/* ========== CRA META (en-tête enrichi) ========== */
.cra-meta {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 10px;
  padding: 12px 16px;
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 8px;
  max-width: fit-content;
}
.cra-meta-user {
  display: flex; align-items: center; gap: 10px;
}
.cra-meta-user-name { font-weight: 700; font-size: 14px; color: var(--oct-black); }
.cra-meta-user-role { font-size: 11px; color: var(--oct-text-muted); text-transform: uppercase; letter-spacing: 0.5px; }
.cra-meta-divider { width: 1px; height: 32px; background: var(--oct-border); }
.cra-meta-mission { font-size: 13px; }
.cra-meta-mission-client { font-weight: 600; color: var(--oct-orange-dark); display: flex; align-items: center; gap: 6px; }
.cra-meta-mission-client i { color: var(--oct-orange); }
.cra-meta-mission-title { font-size: 12px; color: var(--oct-text-muted); margin-top: 1px; }

/* ========== CTA BANNERS ========== */
.cta-banner {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 18px 22px;
  border-radius: 10px;
  margin-bottom: 18px;
  border-left: 5px solid;
  box-shadow: 0 2px 8px rgba(0,0,0,0.04);
}
.cta-banner-icon {
  flex-shrink: 0;
  width: 48px; height: 48px;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px;
}
.cta-banner-content { flex: 1; }
.cta-banner-title { font-size: 16px; font-weight: 700; margin-bottom: 4px; }
.cta-banner-desc { font-size: 13px; line-height: 1.5; }
.cta-banner-actions {
  display: flex; gap: 8px; flex-shrink: 0;
  align-items: center;
}
.cta-banner-actions form { margin: 0; }

/* Variante "action requise" — validateur : orange fort */
.cta-banner-validate {
  background: linear-gradient(to right, #fff8e7, #fffaf0);
  border-left-color: var(--oct-orange);
}
.cta-banner-validate .cta-banner-icon {
  background: var(--oct-orange);
  color: #fff;
}
.cta-banner-validate .cta-banner-title { color: var(--oct-orange-dark); }
.cta-banner-validate .cta-banner-desc { color: #6b4700; }

/* Variante "info" — attente neutre */
.cta-banner-info {
  background: linear-gradient(to right, #e7f3fe, #f5faff);
  border-left-color: #1976d2;
}
.cta-banner-info .cta-banner-icon { background: #1976d2; color: #fff; }
.cta-banner-info .cta-banner-title { color: #0d47a1; }
.cta-banner-info .cta-banner-desc { color: #1e5a9c; }

/* Variante "succès" — CRA validé */
.cta-banner-success {
  background: linear-gradient(to right, #e6f7ec, #f0fbf3);
  border-left-color: var(--oct-green);
}
.cta-banner-success .cta-banner-icon { background: var(--oct-green); color: #fff; }
.cta-banner-success .cta-banner-title { color: #1d7f3d; }
.cta-banner-success .cta-banner-desc { color: #0d5c2a; }

/* Responsive : empile sur petit écran */
@media (max-width: 900px) {
  .cta-banner { flex-direction: column; align-items: flex-start; }
  .cta-banner-actions { width: 100%; margin-top: 10px; flex-wrap: wrap; }
  .cta-banner-actions form { width: 100%; }
  .cta-banner-actions button { width: 100%; }
}

/* ========== ACTION BAR ========== */
.action-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
.action-group {
  display: flex;
  align-items: center;
  gap: 6px;
}
/* Groupe primary : pas de séparateur visuel, le gap suffit
   (cohérence entre action-bar du haut et action-bar-footer du bas) */
.action-group-primary { position: relative; }
.action-group form { display: inline-flex; margin: 0; }

/* Action bar en pied de page : destructif à gauche, actions principales à droite */
.action-bar-footer {
  justify-content: space-between;
  padding: 14px 16px;
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 8px;
}

/* ========== TABLES ========== */
.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.table thead th {
  text-align: left;
  padding: 12px 16px;
  background: var(--oct-bg);
  color: var(--oct-text-muted);
  font-weight: 600;
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: .5px;
  border-bottom: 1px solid var(--oct-border);
}
.table tbody td {
  padding: 14px 16px;
  border-bottom: 1px solid var(--oct-border);
}
.table tbody tr:hover { background: var(--oct-orange-soft); }
.table tbody tr:last-child td { border-bottom: none; }

/* ========== BADGES ========== */
.badge-status {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
}
.badge-status::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%;
}
.badge-draft { background: #eef0f4; color: #6b7280; }
.badge-draft::before { background: var(--oct-gray); }
.badge-submitted { background: var(--oct-orange-soft); color: var(--oct-orange-dark); }
.badge-submitted::before { background: var(--oct-orange); }
.badge-validated { background: #e6f7ec; color: #1d7f3d; }
.badge-validated::before { background: var(--oct-green); }
.badge-client-validated { background: #d1fae5; color: #065f46; font-weight: 700; }
.badge-client-validated::before { background: #065f46; }
.badge-role-super-admin { background: #fde7ef; color: #9d174d; }
.badge-role-super-admin::before { background: #be185d; }
.badge-role-admin { background: var(--oct-orange-soft); color: var(--oct-orange-dark); }
.badge-role-admin::before { background: var(--oct-orange); }
.badge-role-collab { background: var(--oct-orange-soft); color: var(--oct-orange-dark); }
.badge-role-collab::before { background: var(--oct-orange-light); }
.badge-role-client { background: #e0f2fe; color: #075985; }
.badge-role-client::before { background: #0284c7; }

/* ----- Rôles de société (F21) ----- */
/* OWNER : orange Octevia (la société propriétaire EST Octevia, palette charte). */
.badge-owner { background: var(--oct-orange-soft); color: var(--oct-orange-dark); }
.badge-owner::before { background: var(--oct-orange); }
.badge-client { background: #e0f2fe; color: #075985; }
.badge-client::before { background: #0284c7; }
.badge-client-final { background: #ccfbf1; color: #115e59; }
.badge-client-final::before { background: #14b8a6; }
.badge-portage { background: #ede9fe; color: #5b21b6; }
.badge-portage::before { background: #7c3aed; }
.badge-partner { background: #eef0f4; color: #6b7280; }
.badge-partner::before { background: #9ca3af; }

/* Avatars par rôle — accordés aux badges */
.avatar.role-super-admin { background: #be185d; }
.avatar.role-admin       { background: var(--oct-orange); }
.avatar.role-collab      { background: var(--oct-orange-light); }
.avatar.role-client      { background: #0284c7; }

/* ========== FORMS ========== */
.form-group { margin-bottom: 16px; }
.form-label { display: block; font-size: 12px; font-weight: 600; margin-bottom: 6px; color: #2a2f3a; }
.form-control, .form-select {
  width: 100%;
  border: 1px solid var(--oct-border);
  border-radius: 6px;
  padding: 8px 12px;
  font-size: 13px;
  background: #fff;
  transition: border-color .15s;
}
.form-control:focus, .form-select:focus {
  outline: none;
  border-color: var(--oct-orange);
  box-shadow: 0 0 0 3px rgba(242, 142, 19, 0.15);
}

/* Champ en erreur : bordure rouge marquée (parent .form-group avec ul.form-errors).
   On retire le `>` direct child pour matcher quel que soit le wrapping Symfony. */
.form-group:has(.form-errors) .form-control,
.form-group:has(.form-errors) .form-select,
.form-group:has(.form-errors) input[type="text"],
.form-group:has(.form-errors) input[type="email"],
.form-group:has(.form-errors) input[type="tel"],
.form-group:has(.form-errors) input[type="url"],
.form-group:has(.form-errors) input[type="password"],
.form-group:has(.form-errors) input[type="number"],
.form-group:has(.form-errors) input[type="search"],
.form-group:has(.form-errors) textarea,
.form-group:has(.form-errors) select {
  border: 2px solid #c0392b !important;
  background: #fef7f7;
  padding-right: 36px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='%23c0392b'><path d='M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16zm.93-9.412l-1 4.705c-.07.34.029.533.304.533.194 0 .487-.07.686-.246l-.088.416c-.287.346-.92.598-1.465.598-.703 0-1.002-.422-.808-1.319l.738-3.468c.064-.293.006-.399-.287-.47l-.451-.081.082-.381 2.29-.287zM8 5.5a1 1 0 1 1 0-2 1 1 0 0 1 0 2z'/></svg>");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 16px;
}
.form-group:has(.form-errors) .form-control:focus,
.form-group:has(.form-errors) .form-select:focus,
.form-group:has(.form-errors) input:focus,
.form-group:has(.form-errors) textarea:focus,
.form-group:has(.form-errors) select:focus {
  outline: none;
  box-shadow: 0 0 0 3px rgba(192, 57, 43, 0.18);
}
/* Le label aussi en rouge — repère visuel renforcé */
.form-group:has(.form-errors) .form-label {
  color: #c0392b;
}

/* Spécial groupe de pavés (.choice-grid) : encadre la grille en rouge */
.form-group:has(.form-errors) .choice-grid {
  outline: 2px dashed #c0392b;
  outline-offset: 6px;
  border-radius: 8px;
}

/* ========== SEARCHABLE SELECT (combobox) ========== */
.searchable-select {
  position: relative;
}
.searchable-select-input {
  cursor: pointer;
}
.searchable-select-dropdown {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.08);
  max-height: 260px;
  overflow-y: auto;
  z-index: 25;
}
.searchable-select-item {
  display: block;
  width: 100%;
  text-align: left;
  padding: 8px 12px;
  border: none;
  background: transparent;
  border-bottom: 1px solid var(--oct-border);
  cursor: pointer;
  font-size: 13px;
  transition: background .1s;
}
.searchable-select-item:last-child { border-bottom: none; }
.searchable-select-item:hover,
.searchable-select-item.is-active { background: var(--oct-orange-soft); }
.searchable-select-empty {
  padding: 12px;
  font-size: 12px;
  color: var(--oct-text-muted);
  text-align: center;
  font-style: italic;
}

/* ========== LOGIN ========== */
.login-wrap {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  background: #fff;
}

/* --- Brand panel (left) --- */
.login-brand {
  position: relative;
  overflow: hidden;
  padding: 56px 64px;
  color: #fff;
  background:
    url("../images/textures/noise-nZ3v5TG.svg"),
    linear-gradient(135deg, #14181f 0%, #1f2430 55%, #2a3140 100%);
  background-size: 200px 200px, 100% 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.login-brand::before {
  content: "";
  position: absolute;
  top: -60px; left: -40px;
  width: 340px; height: 460px;
  background: url("../images/textures/chap_01-overlay-mmR7B0E.png") no-repeat top left;
  background-size: contain;
  opacity: 0.85;
  pointer-events: none;
}
.login-brand::after {
  content: "";
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 90px;
  background: url("../images/textures/motif-octevia-contenu-ozsrZTP.png") repeat-y top right;
  background-size: 90px auto;
  opacity: 0.22;
  pointer-events: none;
}
.login-brand-content {
  position: relative;
  z-index: 2;
  margin: auto 0;
  max-width: 460px;
}
.login-brand-eyebrow {
  font-size: 12px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--oct-orange-light);
  margin-bottom: 18px;
}
.login-brand-eyebrow strong { color: var(--oct-orange); font-weight: 800; }
.login-brand-title {
  font-size: 42px;
  font-weight: 900;
  line-height: 1.08;
  margin: 0 0 18px;
  letter-spacing: -0.5px;
}
.login-brand-title .hl { color: var(--oct-orange); }
.login-brand-tagline {
  font-size: 16px;
  line-height: 1.6;
  color: #c9cfdb;
  margin: 0 0 34px;
  max-width: 420px;
}
.login-brand-points {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.login-brand-points li {
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 14px;
  color: #dbdfe8;
}
.login-brand-points li i {
  width: 36px; height: 36px;
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: rgba(242, 142, 19, 0.15);
  border: 1px solid rgba(242, 142, 19, 0.35);
  color: var(--oct-orange);
  border-radius: 8px;
  font-size: 16px;
}
.login-brand-footer {
  position: relative;
  z-index: 2;
  font-size: 12px;
  color: #6b7389;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  padding-top: 18px;
}

/* --- Card panel (right) --- */
.login-card-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 24px;
}
.login-card {
  width: 100%;
  max-width: 400px;
}
.login-logo { text-align: center; margin-bottom: 26px; }
.login-title { font-size: 20px; font-weight: 700; margin-bottom: 6px; }
.login-subtitle { color: var(--oct-text-muted); font-size: 13px; margin-bottom: 24px; }
.login-card-legal {
  text-align: center;
  margin-top: 24px;
  font-size: 12px;
  color: var(--oct-text-muted);
}

/* --- Responsive: hide brand panel on narrow screens --- */
@media (max-width: 900px) {
  .login-wrap {
    grid-template-columns: 1fr;
    background: linear-gradient(135deg, #fff 0%, var(--oct-orange-soft) 100%);
  }
  .login-brand { display: none; }
  .login-card-wrap { padding: 24px; }
  .login-card {
    background: #fff;
    border-radius: 12px;
    padding: 36px;
    box-shadow: 0 10px 40px rgba(0,0,0,0.08);
  }
}

/* ========== CRA GRID ========== */
.cra-grid-wrap {
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 8px;
  overflow: auto;
  max-width: 100%;
}
.cra-grid {
  border-collapse: collapse;
  font-size: 12px;
  min-width: 100%;
}
.cra-grid th, .cra-grid td {
  border: 1px solid var(--oct-border);
  padding: 0;
  text-align: center;
  vertical-align: middle;
  height: 36px;
  min-width: 36px;
  position: relative;
}
.cra-grid thead th {
  background: var(--oct-sidebar);
  color: #fff;
  font-weight: 600;
  font-size: 11px;
  padding: 6px 4px;
}
.cra-grid thead th.day-num { background: #2a3040; }
.cra-grid thead th.weekend { background: #454a57; color: #9ca3af; }
.cra-grid .label-col {
  text-align: left;
  padding: 0 36px 0 12px; /* place réservée à droite pour la croix de suppression */
  min-width: 220px;
  font-weight: 500;
  background: var(--oct-bg);
  position: sticky; left: 0;
  z-index: 2;
}
.cra-grid tbody .label-col { position: relative; } /* containing block pour .row-actions absolute */
.cra-grid thead .label-col { padding-right: 12px; }
.cra-grid thead .label-col {
  z-index: 3;
  background: var(--oct-sidebar);
  color: #fff;
}
.cra-grid .total-col {
  background: var(--oct-orange-soft);
  font-weight: 700;
  color: var(--oct-orange-dark);
  min-width: 60px;
}
.cra-grid td.weekend { background: #eef0f4; }
.cra-grid td.holiday { background: #fde8e8; }
.cra-grid td.holiday::after {
  content: '🎉';
  position: absolute;
  top: 2px; right: 3px;
  font-size: 9px;
}
/* Férié non chômé (RG-Hol-2) : jaune doux, saisie autorisée. */
.cra-grid td.holiday-open { background: #fdf3d3; }
.cra-grid td.holiday-open::after {
  content: '🎉';
  position: absolute;
  top: 2px; right: 3px;
  font-size: 9px;
  opacity: 0.4;
}
.cra-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%; height: 36px;
  border: none; background: transparent;
  text-align: center;
  font-weight: 600;
  color: var(--oct-orange-dark);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
}
.cra-cell:focus {
  outline: 2px solid var(--oct-orange);
  outline-offset: -2px;
  background: var(--oct-orange-soft);
}
/* ========== OPTIONS — TOGGLE SWITCHES (sexy UI) ========== */
.options-card .card-body { padding: 0; }

.opt-section {
  padding: 18px 20px;
  border-bottom: 1px solid var(--oct-border);
}
.opt-section.opt-section-last { border-bottom: none; background: var(--oct-bg); }
.opt-section-title {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1.2px;
  color: var(--oct-text-muted);
  margin-bottom: 14px;
  display: flex; align-items: center; gap: 7px;
}
.opt-section-title i { font-size: 13px; color: var(--oct-orange); }

.opt-switch, .opt-field {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 10px 0;
  cursor: pointer;
  position: relative;
  user-select: none;
}
.opt-switch + .opt-switch,
.opt-field + .opt-switch,
.opt-switch + .opt-field,
.opt-field + .opt-field { border-top: 1px solid var(--oct-border); }
.opt-field { cursor: default; }

.opt-icon {
  flex-shrink: 0;
  width: 36px; height: 36px;
  border-radius: 9px;
  background: var(--oct-bg);
  display: flex; align-items: center; justify-content: center;
  color: var(--oct-orange);
  font-size: 16px;
  transition: background .15s, color .15s;
}
.opt-switch:hover .opt-icon { background: var(--oct-orange-soft); }

.opt-text {
  flex: 1;
  display: flex; flex-direction: column; gap: 2px;
  padding-top: 6px;
}
.opt-title { font-size: 13px; font-weight: 600; color: var(--oct-black); }
.opt-desc { font-size: 11.5px; color: var(--oct-text-muted); line-height: 1.4; }

/* Switch visuel : cache la checkbox native, dessine une piste */
.opt-input {
  position: absolute;
  opacity: 0;
  width: 0; height: 0;
  pointer-events: none;
}
.opt-track {
  position: relative;
  width: 44px; height: 24px;
  flex-shrink: 0;
  background: #d1d5db;
  border-radius: 999px;
  transition: background .2s;
  margin-top: 7px;
}
.opt-track::before {
  content: '';
  position: absolute;
  top: 2px; left: 2px;
  width: 20px; height: 20px;
  background: #fff;
  border-radius: 50%;
  transition: transform .2s;
  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
.opt-input:checked ~ .opt-track { background: var(--oct-orange); }
.opt-input:checked ~ .opt-track::before { transform: translateX(20px); }
.opt-input:focus-visible ~ .opt-track { outline: 3px solid var(--oct-orange-light); outline-offset: 2px; }
.opt-switch:active .opt-track::before { width: 24px; }

.opt-switch-lg .opt-track { width: 52px; height: 28px; }
.opt-switch-lg .opt-track::before { width: 24px; height: 24px; }
.opt-switch-lg .opt-input:checked ~ .opt-track::before { transform: translateX(24px); }

/* Conditional disabled (si requireClientValidation = false) */
.is-disabled {
  opacity: 0.45;
  pointer-events: none;
  transition: opacity .2s;
}
.is-disabled select,
.is-disabled input,
.is-disabled textarea { background: #f5f6f8; cursor: not-allowed; }

/* ========== CHOICE CARDS (pavés sélectionnables, single ou multi) ==========
   Usage :
     <div class="choice-grid">
       <label class="choice-card">
         <input type="checkbox" class="choice-input">
         <span class="choice-icon"><i class="bi bi-..."></i></span>
         <span class="choice-title">Salariés</span>
         <span class="choice-desc">Société OWNER</span>
         <span class="choice-check"><i class="bi bi-check-lg"></i></span>
       </label>
       ...
     </div>
*/
.choice-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px;
}
.choice-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: 14px 14px 14px 16px;
  border: 2px solid var(--oct-border);
  border-radius: 8px;
  background: #fff;
  cursor: pointer;
  transition: border-color .15s, background .15s;
  margin: 0;
}
.choice-card:hover { border-color: var(--oct-orange-light); background: #fffbf5; }
.choice-input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  width: 0;
  height: 0;
}
.choice-icon {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  background: var(--oct-orange-soft);
  color: var(--oct-orange-dark);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  margin-bottom: 2px;
}
.choice-title { font-weight: 600; font-size: 13px; color: var(--oct-text); }
.choice-desc { font-size: 11px; color: var(--oct-text-muted); line-height: 1.35; }
.choice-check {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--oct-orange);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  opacity: 0;
  transform: scale(.8);
  transition: opacity .15s, transform .15s;
}
.choice-card:has(.choice-input:checked) {
  border-color: var(--oct-orange);
  background: var(--oct-orange-soft);
}
.choice-card:has(.choice-input:checked) .choice-check {
  opacity: 1;
  transform: scale(1);
}
.choice-card:has(.choice-input:focus-visible) {
  outline: 3px solid var(--oct-orange-light);
  outline-offset: 2px;
}

/* Role cards : surcharge des couleurs choice-card par rôle */
.role-card.role-card-role-super-admin .choice-icon { background: #fde7ef; color: #9d174d; }
.role-card.role-card-role-super-admin:has(.choice-input:checked) {
  border-color: #be185d; background: #fdf2f8;
}
.role-card.role-card-role-super-admin:has(.choice-input:checked) .choice-check { background: #be185d; }

.role-card.role-card-role-admin .choice-icon { background: var(--oct-orange-soft); color: var(--oct-orange-dark); }
.role-card.role-card-role-admin:has(.choice-input:checked) {
  border-color: var(--oct-orange); background: var(--oct-orange-soft);
}

.role-card.role-card-role-collab .choice-icon { background: var(--oct-orange-soft); color: var(--oct-orange); }
.role-card.role-card-role-collab:has(.choice-input:checked) {
  border-color: var(--oct-orange-light); background: var(--oct-orange-soft);
}

.role-card.role-card-role-client .choice-icon { background: #e0f2fe; color: #075985; }
.role-card.role-card-role-client:has(.choice-input:checked) {
  border-color: #0284c7; background: #f0f9ff;
}
.role-card.role-card-role-client:has(.choice-input:checked) .choice-check { background: #0284c7; }

/* ========== SIRENE SEARCH WIDGET ========== */
.sirene-search {
  position: relative;
}
.sirene-results {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.08);
  max-height: 320px;
  overflow-y: auto;
  z-index: 20;
}
.sirene-result {
  display: block;
  width: 100%;
  text-align: left;
  padding: 10px 14px;
  border: none;
  background: transparent;
  border-bottom: 1px solid var(--oct-border);
  cursor: pointer;
  transition: background .1s;
}
.sirene-result:last-child { border-bottom: none; }
.sirene-result:hover,
.sirene-result.is-active { background: var(--oct-orange-soft); }
.sirene-result-name {
  font-weight: 600;
  font-size: 13px;
  color: var(--oct-text);
  margin-bottom: 2px;
}
.sirene-result-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  font-size: 11px;
  color: var(--oct-text-muted);
}
.sirene-result-meta span i { margin-right: 3px; }
.sirene-result-closed {
  color: #dc3545;
  font-weight: 600;
}
.sirene-result-empty,
.sirene-result-error {
  padding: 14px;
  font-size: 12px;
  color: var(--oct-text-muted);
  text-align: center;
}
.sirene-result-error { color: #dc3545; }

/* ========== APP FOOTER — EVO-067 (B1 desktop riche + D1 mobile compact) ==========
   Hand-off : ViaTEMPO Refonte - Footer.dc.html (frames B1 + D1 + C env).
   Lockup partial : templates/_partials/brand_lockup.html.twig
   Template : templates/_partials/app_footer.html.twig
   ----------------------------------------------------------------------------- */
.app-footer {
  margin-top: auto;
  background: var(--surface-app);
  border-top: 1px solid var(--border-subtle);
}
.app-footer__top {
  display: flex;
  align-items: flex-start;
  gap: var(--s-10);                    /* 40px */
  padding: var(--s-8) var(--s-10) var(--s-5);  /* 32 40 20 — aligné avec le bar bas */
}
.app-footer__brand {
  flex: none;
  width: auto;                  /* lockup prend sa taille naturelle */
  order: 2;                     /* poussé à droite (après les colonnes) */
  margin-left: auto;            /* absorbe tout l'espace dispo entre cols et brand
                                   → lockup aligné sur la fin du badge env du bar */
}
.app-footer__col {
  flex: none;                   /* pas d'étirement : colonnes resserrées à gauche,
                                   alignées sur le début du copyright du bar */
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.app-footer__head {
  font-family: var(--font-mono);
  font-size: var(--t-12);              /* +2 px : titres plus marqués (10 → 12) */
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin: 0 0 2px;                     /* liens collés sous le titre (~12 → 2 px) */
}
.ft-link {
  color: var(--text-default);
  text-decoration: none;
  font-size: var(--t-13);
  transition: color var(--motion-base) var(--ease-standard);
  padding: 4px 0;            /* cible touch ~28px en hauteur (renforcé en mobile) */
}
/* Override explicite de la règle globale `a:hover { text-decoration: underline }`
   posée ligne 479 — le footer reste sobre, seul le changement de couleur signale
   le hover. */
.ft-link:hover {
  color: var(--orange-500);
  text-decoration: none;
}

.app-footer__bar {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4) var(--s-10);
  position: relative;
  /* Ligne de séparation NON pleine largeur : du début du logo (left: --s-10)
     à la fin du badge env (right: --s-10), alignée sur les paddings du top. */
}
.app-footer__bar::before {
  content: '';
  position: absolute;
  top: 0;
  left: var(--s-10);
  right: var(--s-10);
  height: 1px;
  background: var(--border-subtle);
}
.app-footer__copy {
  font-size: var(--t-12);
  color: var(--text-muted);          /* aligné sur .ft-status (= « Environnement local ») */
}
/* Séparateurs orange et mention « OCTEVIA » stylisée comme dans le lockup */
.ft-copy__dot { color: var(--orange-500); font-weight: 700; }
.ft-copy__brand {
  font-family: 'Roboto', system-ui, sans-serif;
  font-weight: 300;
  letter-spacing: 0.1em;
  color: inherit;                    /* hérite --text-muted du copy → ligne homogène */
  text-decoration: none;
  transition: color var(--motion-base) var(--ease-standard);
}
.ft-copy__brand:hover {
  color: var(--ink-700);
  text-decoration: none;
}
.ft-copy__hl { color: var(--orange-500); }

/* Lockup du footer cliquable — aucun soulignement, le lockup conserve son aspect */
.app-footer__brand-link {
  display: inline-block;
  line-height: 0;
  text-decoration: none;
}
.app-footer__brand-link:hover { text-decoration: none; }
.app-footer__spacer { flex: 1; }

/* ----- statut services ----- */
.ft-status {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--t-12);
  color: var(--text-muted);
  text-decoration: none;
}
.ft-status .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--success-base);
  animation: ft-pulse 2.4s ease-in-out infinite;
}
.ft-status--off .dot {
  background: var(--text-faint);
  animation: none;
}
@keyframes ft-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}
@media (prefers-reduced-motion: reduce) {
  .ft-status .dot { animation: none; }
}

/* ----- divider + version ----- */
.ft-div {
  width: 1px;
  height: 14px;
  background: var(--border-subtle);
}
.ft-version {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--font-mono);
  font-size: var(--t-11);
}
/* Numéro de version dans une petite pill orange (cf. footer pre-EVO-067) */
.ft-version__num {
  color: var(--brand-accent-text);
  background: var(--orange-50);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  padding: 3px 9px;
  border-radius: 10px;
  letter-spacing: 0.3px;
}

/* ----- badge environnement — plaquette plus marquée (cf. hand-off) ----- */
.ft-env {
  font-family: var(--font-mono);
  font-size: var(--t-12);              /* +1 px (11 → 12) */
  font-weight: 700;                    /* +200 (medium → bold) */
  letter-spacing: 0.08em;
  padding: 3px 9px;                    /* +1 px V / +2 px H */
  border-radius: var(--r-4);
}
.ft-env--prod    { background: var(--success-soft); color: var(--success-base); }
.ft-env--recette { background: var(--orange-50);    color: var(--brand-accent-text); }
.ft-env--local   { background: var(--ink-50);       color: var(--text-muted); }

/* Labels longs / courts des liens footer — desktop affiche le long, mobile le court. */
.ft-link-short { display: none; }
.ft-link-long  { display: inline; }

/* Zone status mobile (entre __top et __bar) — masquée par défaut, affichée
   uniquement en mobile via media query plus bas. */
.app-footer__status-mobile { display: none; }

/* ----- Mobile compact <= 767px (refonte EVO-063 SL 1.10) :
   - Lockup centré ligne 1
   - Colonnes Ressources / Légal côte-à-côte avec mini-titres conservés
   - Copyright sur sa ligne
   - Status « Services opérationnels » sur sa propre ligne (line break forcé)
   - Version + env chip alignés au-dessous
   ----- */
@media (max-width: 767px) {
  .app-footer { padding: 0; }
  /* Section top : lockup centré (full width), puis 2 colonnes mini côte-à-côte.
     Padding + gap généreux pour aérer (le footer mobile est lu à froid en
     fin de page, pas besoin de compresser). Bug avant : utilisait `--s-7` qui
     n'existe pas dans tokens.css (s-1..s-6 puis s-8, s-10…) → règle gap
     silencieusement ignorée → aucun espacement visible. */
  .app-footer__top {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: center;
    text-align: center;
    gap: var(--s-5) var(--s-10);   /* 20px row, 40px col */
    padding: var(--s-5) var(--s-4) 0;   /* bottom = 0 : status-mobile gère
                                            seul l'écart symétrique avant le trait. */
  }
  .app-footer__brand {
    width: 100%;
    display: flex;
    justify-content: center;
    margin-bottom: 0;
  }
  /* Mini-titres « RESSOURCES » / « LÉGAL » : taille très réduite, lettrage espacé */
  .app-footer__head {
    font-size: var(--t-10, 10px);
    letter-spacing: 0.08em;
    margin: 0 0 4px;
    opacity: 0.7;
  }
  .app-footer__col {
    align-items: center;
    gap: 4px;
    width: auto;
  }
  .ft-link {
    padding: 4px 0;
    min-height: auto;
    font-size: var(--t-13);
  }
  /* Swap des labels en mobile : libellés courts (Aide / Support / Mentions / Confidentialité). */
  .ft-link-long  { display: none; }
  .ft-link-short { display: inline; }
  /* Bar bas : flex-wrap row mais on FORCE le retour à la ligne avant la
     version en mettant .ft-status sur sa propre ligne (flex-basis: 100%).
     Gap row généreux (var(--s-3) = 12px) entre © / services / version pour
     que ça respire. */
  .app-footer__bar {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--s-3) var(--s-2);
    padding: var(--s-5) var(--s-4) calc(var(--s-5) + env(safe-area-inset-bottom, 0px));
  }
  .app-footer__spacer { display: none; }
  .app-footer__copy {
    font-size: var(--t-11);
    flex-basis: 100%;
    text-align: center;
  }
  /* Status dans le bar : masqué en mobile (le duplicate dans
     .app-footer__status-mobile entre __top et __bar prend le relais). */
  .app-footer__bar .ft-status { display: none; }

  /* Zone status mobile activée : centrée, entre les colonnes et le bar bas.
     Padding symétrique haut/bas pour équilibrer les écarts (12px de chaque
     côté du status, sans padding sur __top qui se charge de zero). */
  .app-footer__status-mobile {
    display: flex;
    justify-content: center;
    padding: var(--s-3) var(--s-4);
  }
  /* Trait séparateur du bar : élargi en mobile (les --s-10 desktop laissent
     un trait trop court ; on retombe sur --s-4 = 16px pour qu'il atteigne
     quasiment la largeur du contenu interne des colonnes Aide/Support…). */
  .app-footer__bar::before {
    left: var(--s-4);
    right: var(--s-4);
  }
  .app-footer__status-mobile .ft-status {
    font-size: var(--t-12, 12px);
  }

  .ft-div { display: none; }
  .ft-version { font-size: var(--t-11); }
}

/* ========== USER DROPDOWN ========== */
.user-menu-wrap { position: relative; }
.user-menu { background: none; border: none; cursor: pointer; }
.user-menu:hover { background: var(--oct-bg); }
.user-dropdown {
  position: absolute;
  top: calc(100% + 6px); right: 0;
  min-width: 220px;
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 8px;
  box-shadow: 0 6px 24px rgba(0,0,0,0.10);
  padding: 6px;
  z-index: 50;
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  transition: opacity .12s, transform .12s;
}
.user-dropdown.open {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.user-dropdown a, .user-dropdown button {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px;
  color: var(--oct-black);
  font-size: 13px;
  border-radius: 5px;
  text-decoration: none;
  width: 100%;
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
}
.user-dropdown a:hover, .user-dropdown button:hover {
  background: var(--oct-orange-soft);
  color: var(--oct-orange-dark);
  text-decoration: none;
}
.user-dropdown a i, .user-dropdown button i { width: 16px; color: var(--oct-text-muted); }
.user-dropdown a:hover i, .user-dropdown button:hover i { color: var(--oct-orange); }
.user-dropdown .divider { height: 1px; background: var(--oct-border); margin: 5px 2px; }
.user-dropdown .danger { color: #b8213a; }
.user-dropdown .danger:hover { background: #fde8e8; color: #9c2030; }
.user-dropdown .danger i { color: #b8213a; }
.user-dropdown .user-info {
  padding: 10px 12px 8px;
  border-bottom: 1px solid var(--oct-border);
  margin-bottom: 4px;
}
.user-dropdown .user-info .name { font-weight: 600; font-size: 13px; }
.user-dropdown .user-info .email { font-size: 11px; color: var(--oct-text-muted); margin-top: 2px; word-break: break-all; }

/* ========== PASSWORD TOGGLE ========== */
.pwd-wrap { position: relative; }
.pwd-wrap input { padding-right: 40px; }
.pwd-eye {
  position: absolute;
  right: 8px; top: 50%;
  transform: translateY(-50%);
  background: transparent;
  border: none;
  color: var(--oct-text-muted);
  cursor: pointer;
  padding: 4px 8px;
  font-size: 16px;
  border-radius: 4px;
}
.pwd-eye:hover { color: var(--oct-orange); background: var(--oct-orange-soft); }
.pwd-eye:focus { outline: 2px solid var(--oct-orange); outline-offset: 1px; }

/* ========== SORTABLE ========== */
.drag-handle { user-select: none; }
.drag-handle:hover { color: var(--oct-orange) !important; }
.drag-handle:active { cursor: grabbing !important; }
.sortable-ghost {
  opacity: 0.4;
  background: var(--oct-orange-soft);
  border: 2px dashed var(--oct-orange);
  border-radius: 6px;
}
.sortable-chosen {
  background: #fff;
  box-shadow: 0 4px 16px rgba(0,0,0,0.12);
  border-radius: 6px;
}

.cra-cell.filled { background: var(--oct-orange-soft); }
.cra-cell.invalid { background: #fde8e8 !important; color: #9c2030 !important; box-shadow: inset 0 0 0 2px #dc3545; animation: cra-shake .4s; }
@keyframes cra-shake {
  0%,100% { transform: translateX(0); }
  25% { transform: translateX(-2px); }
  75% { transform: translateX(2px); }
}
.cra-grid tfoot td {
  background: var(--oct-sidebar);
  color: #fff;
  font-weight: 700;
}
.cra-grid tfoot td.total-col {
  background: var(--oct-orange);
  color: #fff;
}

.label-edit {
  background: transparent;
  border: none;
  font: inherit;
  color: inherit;
  padding: 0;
  width: 100%;
  text-align: left;
}
.label-edit:focus { outline: 1px dashed var(--oct-orange); }

.row-actions {
  display: flex;
  position: absolute; right: 6px; top: 50%;
  transform: translateY(-50%);
  gap: 2px;
  opacity: 0;
  transition: opacity .15s ease;
  pointer-events: none;
}
.cra-grid tr:hover .row-actions,
.cra-grid tr:focus-within .row-actions { opacity: 1; pointer-events: auto; }
.row-actions button {
  background: #fff;
  border: 1px solid var(--oct-border);
  width: 24px; height: 24px;
  border-radius: 6px;
  font-size: 12px;
  cursor: pointer;
  color: var(--oct-text-muted);
  display: flex; align-items: center; justify-content: center;
  padding: 0;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.row-actions button:hover { background: #fde8e8; border-color: #f5c2c7; color: #dc3545; }

.cra-toolbar {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 16px;
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 8px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}
.cra-toolbar .divider { width: 1px; height: 20px; background: var(--oct-border); }
.save-indicator {
  margin-left: auto;
  font-size: 12px;
  color: var(--oct-green);
  display: flex; align-items: center; gap: 5px;
}

.cra-summary {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 12px;
  margin-top: 16px;
}
@media (max-width: 1100px) {
  .cra-summary { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 720px) {
  .cra-summary { grid-template-columns: repeat(2, 1fr); }
}
.cra-summary .box {
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 8px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.cra-summary .box .lbl {
  font-size: 11px;
  color: var(--oct-text-muted);
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: 6px;
}
.cra-summary .box .lbl i { font-size: 13px; }
.cra-summary .box .val { font-size: 22px; font-weight: 700; color: var(--oct-orange-dark); }
.cra-summary .box-worked { background: linear-gradient(135deg, #fff 0%, var(--oct-orange-soft) 100%); border-color: var(--oct-orange-light); }
.cra-summary .box-worked .lbl { color: var(--oct-orange-dark); }
.cra-summary .box-non-worked { background: linear-gradient(135deg, #fff 0%, #eef2f7 100%); border-color: #d6dde6; }
.cra-summary .box-non-worked .lbl { color: #4b5563; }
.cra-summary .box-non-worked .val { color: #4b5563; }

.keyboard-hint {
  background: var(--oct-orange-soft);
  border: 1px dashed var(--oct-orange);
  color: var(--oct-orange-dark);
  padding: 8px 14px;
  border-radius: 6px;
  font-size: 12px;
  margin-top: 12px;
}
.keyboard-hint kbd {
  background: #fff;
  border: 1px solid var(--oct-orange);
  border-radius: 3px;
  padding: 1px 5px;
  font-family: monospace;
  font-size: 11px;
  color: var(--oct-orange-dark);
}

/* ========== PDF PREVIEW ========== */
.pdf-preview-wrap {
  background: #525659;
  min-height: calc(100vh - 62px);
  padding: 30px;
  display: flex; justify-content: center;
}
.pdf-page {
  background: #fff;
  width: 1056px;
  min-height: 600px;
  padding: 40px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.3);
}
.pdf-header { margin-bottom: 24px; }
.pdf-table {
  border-collapse: collapse;
  font-size: 11px;
  width: 100%;
}
.pdf-table th, .pdf-table td {
  border: 1px solid #333;
  padding: 3px 5px;
  text-align: center;
  min-width: 22px;
  height: 22px;
}
.pdf-table .meta-col { text-align: left; min-width: 160px; }
.pdf-table .meta-label { background: #f5f5f5; font-weight: 600; }
.pdf-table .orange { color: var(--oct-orange); font-weight: 700; }
.pdf-table .weekend { background: #e0e0e0; }
.pdf-toolbar {
  position: sticky; top: 62px;
  background: #3a3d42; color: #fff;
  padding: 10px 20px;
  display: flex; align-items: center; gap: 14px;
  border-bottom: 1px solid #000;
}

/* ========== LAYOUT HELPERS ========== */
.row-g { display: grid; gap: 16px; }
.row-g-2-1 { grid-template-columns: 2fr 1fr; }
.row-g-1-1 { grid-template-columns: 1fr 1fr; }
.d-flex { display: flex; }
.gap-2 { gap: 8px; }
.gap-3 { gap: 12px; }
.ml-auto { margin-left: auto; }
.mt-3 { margin-top: 12px; }
.mb-3 { margin-bottom: 12px; }
.text-muted { color: var(--oct-text-muted); }
.text-center { text-align: center; }

/* ========== MOCK BAR CHART ========== */
.bar-chart {
  display: flex; align-items: flex-end; gap: 6px;
  height: 180px; padding: 10px 0;
}
.bar-chart .bar {
  flex: 1;
  background: linear-gradient(180deg, var(--oct-orange-light) 0%, var(--oct-orange) 100%);
  border-radius: 4px 4px 0 0;
  position: relative;
  min-height: 4px;
}
.bar-chart .bar::after {
  content: attr(data-label);
  position: absolute;
  bottom: -22px;
  left: 50%; transform: translateX(-50%);
  font-size: 11px;
  color: var(--oct-text-muted);
}
.bar-chart .bar:hover { background: var(--oct-orange-dark); }

/* ========== NAV CRUMB ========== */
.breadcrumb {
  font-size: 12px;
  color: var(--oct-text-muted);
  margin-bottom: 4px;
}
.breadcrumb a { color: var(--oct-text-muted); }
.breadcrumb .sep { margin: 0 6px; }

/* ========== INDEX MOCKUPS ========== */
.mock-index {
  max-width: 980px;
  margin: 40px auto;
  padding: 30px;
}
.mock-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 16px;
  margin-top: 24px;
}
.mock-tile {
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 10px;
  padding: 20px;
  display: block;
  color: var(--oct-black);
  transition: all .2s;
}
.mock-tile:hover {
  border-color: var(--oct-orange);
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(242,142,19,0.15);
  text-decoration: none;
  color: var(--oct-black);
}
.mock-tile .num {
  font-size: 11px; color: var(--oct-orange);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
}
.mock-tile h3 { font-size: 16px; margin: 6px 0; }
.mock-tile p { font-size: 12px; color: var(--oct-text-muted); margin: 0; }

/* responsive mini */
@media (max-width: 900px) {
  .sidebar { width: 70px; }
  .sidebar-logo, .sidebar-nav span, .sidebar-section { display: none; }
  .main-content { margin-left: 70px; }
  .kpi-grid { grid-template-columns: repeat(2, 1fr); }
  .row-g-2-1, .row-g-1-1 { grid-template-columns: 1fr; }
}

/* ========== F9 — TIMELINE HISTORIQUE CRA ========== */
.timeline-card { background: #fff; border: 1px solid var(--oct-border); border-radius: 8px; overflow: hidden; }
.timeline-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px; border-bottom: 1px solid var(--oct-border);
  background: #fafbfc;
}
.timeline-header h2 {
  margin: 0; font-size: 14px; font-weight: 600;
  display: flex; align-items: center; gap: 10px;
}
.timeline-header h2 i { color: var(--oct-orange); font-size: 16px; }
.timeline-header .meta { font-size: 12px; color: var(--oct-text-muted); }
.timeline-header .meta strong { color: var(--oct-black); font-weight: 600; }

/* Rail horizontal — max 5 éléments, pas de scroll horizontal */
.rail-wrapper { padding: 24px 28px 16px; border-bottom: 1px dashed var(--oct-border); }
.rail { position: relative; display: flex; justify-content: space-between; align-items: flex-start; gap: 6px; }
.rail::before {
  content: ""; position: absolute; top: 22px; left: 22px; right: 22px; height: 2px;
  background: var(--oct-border); z-index: 0;
}
.rail-step { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; flex: 1 1 0; min-width: 0; padding: 0 2px; }
.rail-step .rail-label, .rail-step .rail-date, .rail-step .rail-actor {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.rail-dot {
  width: 44px; height: 44px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: #fff; border: 2px solid var(--oct-border); color: var(--oct-text-muted);
  font-size: 18px; margin-bottom: 10px; transition: all 0.2s;
}
.rail-step.cat-create .rail-dot { border-color: var(--oct-gray); color: var(--oct-gray); }
.rail-step.cat-submit .rail-dot { border-color: var(--oct-orange); color: var(--oct-orange); background: var(--oct-orange-soft); }
.rail-step.cat-validate .rail-dot { border-color: var(--oct-green); color: var(--oct-green); background: #e6f7ec; }
.rail-step.cat-reject .rail-dot { border-color: #9c2030; color: #9c2030; background: #fde8e8; }
.rail-step.cat-retract .rail-dot { border-color: var(--oct-orange-light); color: var(--oct-orange-dark); background: var(--oct-orange-soft); }
.rail-step.current .rail-dot { box-shadow: 0 0 0 4px var(--oct-orange-soft); transform: scale(1.05); }
.rail-step.current .rail-dot::after {
  content: ""; position: absolute; top: -2px; right: calc(50% - 24px);
  width: 12px; height: 12px; background: var(--oct-orange); border: 2px solid #fff; border-radius: 50%;
  animation: rail-pulse 1.8s infinite;
}
@keyframes rail-pulse {
  0%,100% { box-shadow: 0 0 0 0 rgba(242,142,19,0.6); }
  50%     { box-shadow: 0 0 0 6px rgba(242,142,19,0); }
}
.rail-label { font-size: 12px; font-weight: 600; color: var(--oct-black); text-align: center; line-height: 1.3; }
.rail-date  { font-size: 10px; color: var(--oct-text-muted); margin-top: 3px; text-align: center; }
.rail-actor { font-size: 10px; color: var(--oct-text-muted); margin-top: 1px; text-align: center; font-style: italic; }

.rail-step.collapsed .rail-dot {
  background: #fff; border-color: var(--oct-border); color: var(--oct-text-muted);
  font-size: 13px; font-weight: 700; width: 40px; height: 40px; cursor: default;
}
.rail-step.collapsed .rail-label { color: var(--oct-text-muted); font-weight: 500; font-size: 11px; }

/* Feed vertical */
.feed-wrapper { padding: 20px 28px 24px; }
.feed-toolbar {
  display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px;
  flex-wrap: wrap; gap: 10px;
}
.feed-toolbar .title {
  font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--oct-text-muted); font-weight: 600;
}
.feed-filters { display: flex; gap: 6px; flex-wrap: wrap; }
.feed-filter {
  padding: 4px 10px; border: 1px solid var(--oct-border); border-radius: 14px;
  font-size: 11px; cursor: pointer; background: #fff; color: var(--oct-text-muted);
  transition: all 0.15s;
}
.feed-filter:hover { color: var(--oct-black); border-color: var(--oct-text-muted); }
.feed-filter.active { background: var(--oct-sidebar); color: #fff; border-color: var(--oct-sidebar); }

.feed { position: relative; padding-left: 24px; }
.feed::before { content: ""; position: absolute; left: 9px; top: 8px; bottom: 8px; width: 2px; background: var(--oct-border); }
.feed-item { position: relative; margin-bottom: 16px; }
.feed-item:last-child { margin-bottom: 0; }
.feed-item::before {
  content: ""; position: absolute; left: -19px; top: 14px;
  width: 12px; height: 12px; border-radius: 50%; background: #fff; border: 2px solid var(--oct-border);
}
.feed-item.cat-create::before   { border-color: var(--oct-gray); }
.feed-item.cat-submit::before   { border-color: var(--oct-orange);   background: var(--oct-orange); }
.feed-item.cat-validate::before { border-color: var(--oct-green);    background: var(--oct-green); }
.feed-item.cat-reject::before   { border-color: #9c2030;             background: #9c2030; }
.feed-item.cat-retract::before  { border-color: var(--oct-orange-light); background: var(--oct-orange-light); }

.feed-card {
  background: #fff; border: 1px solid var(--oct-border); border-radius: 6px;
  padding: 12px 14px; transition: all 0.15s;
}
.feed-card:hover { border-color: var(--oct-orange-light); box-shadow: 0 2px 6px rgba(242,142,19,0.08); }
.feed-item.current .feed-card { border-color: var(--oct-orange); box-shadow: 0 0 0 3px var(--oct-orange-soft); }

.feed-card-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.feed-card-left { display: flex; gap: 10px; align-items: flex-start; flex: 1; min-width: 200px; }
.feed-icon {
  width: 32px; height: 32px; border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; flex-shrink: 0;
}
.cat-create .feed-icon   { background: #f1f3f5; color: var(--oct-gray); }
.cat-submit .feed-icon   { background: var(--oct-orange-soft); color: var(--oct-orange-dark); }
.cat-validate .feed-icon { background: #e6f7ec; color: #1d7f3d; }
.cat-reject .feed-icon   { background: #fde8e8; color: #9c2030; }
.cat-retract .feed-icon  { background: var(--oct-orange-soft); color: var(--oct-orange-dark); }

.feed-title { font-size: 13px; font-weight: 600; color: var(--oct-black); line-height: 1.3; margin-bottom: 3px; }
.feed-title .transition-arrow { color: var(--oct-text-muted); font-weight: 400; margin: 0 4px; }
.feed-state {
  display: inline-block; padding: 1px 7px; font-size: 10px; font-weight: 600;
  border-radius: 3px; letter-spacing: 0.3px; text-transform: uppercase;
}
.feed-state.draft            { background: #e5e7eb; color: #374151; }
.feed-state.submitted        { background: var(--oct-orange-soft); color: var(--oct-orange-dark); }
.feed-state.validated        { background: #e6f7ec; color: #1d7f3d; }
.feed-state.client_validated { background: #d1fae5; color: #065f46; }

.feed-meta { font-size: 11px; color: var(--oct-text-muted); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.feed-meta .actor-chip { display: inline-flex; align-items: center; gap: 5px; }
.feed-meta .actor-name { color: var(--oct-black); font-weight: 500; }
.feed-date { font-size: 11px; color: var(--oct-text-muted); white-space: nowrap; }
.feed-date i { margin-right: 3px; opacity: 0.6; }

.feed-comment {
  margin-top: 8px; padding: 8px 12px; background: var(--oct-bg);
  border-left: 3px solid var(--oct-border); border-radius: 0 4px 4px 0;
  font-size: 13px; color: #4a4f5a; line-height: 1.5; font-style: italic;
}
.cat-validate .feed-comment { border-left-color: var(--oct-green); background: #e6f7ec; }
.cat-reject .feed-comment   { border-left-color: #9c2030;         background: #fde8e8; }
.cat-retract .feed-comment  { border-left-color: var(--oct-orange); background: var(--oct-orange-soft); }

.feed-actions { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
.btn-snapshot {
  display: inline-flex; align-items: center; gap: 5px; padding: 4px 9px;
  font-size: 11px; font-weight: 500; background: #fff;
  border: 1px solid var(--oct-border); border-radius: 4px; color: var(--oct-black);
  cursor: pointer; text-decoration: none;
}
.btn-snapshot:hover { border-color: var(--oct-orange); color: var(--oct-orange-dark); text-decoration: none; }
.btn-snapshot i { font-size: 12px; }

.current-badge {
  display: inline-block; padding: 2px 8px; background: var(--oct-orange); color: #fff;
  font-size: 10px; font-weight: 700; border-radius: 10px; letter-spacing: 0.3px;
  text-transform: uppercase; margin-left: 6px;
}
.timeline-footer {
  padding: 12px 20px; background: #fafbfc; border-top: 1px solid var(--oct-border);
  display: flex; justify-content: space-between; align-items: center;
  font-size: 12px; color: var(--oct-text-muted); flex-wrap: wrap; gap: 8px;
}
.timeline-footer a { color: var(--oct-orange); text-decoration: none; }
.timeline-footer a:hover { text-decoration: underline; }

/* ========================================================================
   FORMS — renforcement validation (P2)
   - label required : astérisque
   - form-errors-banner : bandeau haut de form (erreurs class-level)
   - .form-group .invalid-feedback / form_errors : texte rouge sous le champ
   - chip-group : pastilles radio 1..5 pour daysPerWeek
   - form-help : helper text sous le champ
======================================================================== */
.form-label.required::after {
  content: " *";
  color: #c0392b;
  font-weight: 700;
}
.form-help {
  font-size: 11px;
  color: var(--oct-text-muted);
  margin-top: 6px;
  line-height: 1.4;
}
.form-help .bi { margin-right: 4px; }

/* Erreurs au niveau champ (rendu par form_errors()) */
.form-group .form-errors,
.form-group ul.form-errors,
ul.form-errors {
  list-style: none;
  padding: 0;
  margin: 6px 0 0 0;
  font-size: 12px;
  color: #c0392b;
  font-weight: 500;
}
.form-group .form-errors li,
ul.form-errors li {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  background: #fef2f2;
  border-left: 3px solid #c0392b;
  border-radius: 0 4px 4px 0;
  margin-top: 4px;
  line-height: 1.4;
}
.form-group .form-errors li::before,
ul.form-errors li::before {
  content: "\f33a"; /* bi-exclamation-circle-fill */
  font-family: "bootstrap-icons";
  font-size: 13px;
  flex-shrink: 0;
  color: #c0392b;
}

/* Bandeau erreurs global (class-level errors) */
.form-errors-banner {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: #fde8e8;
  border: 1px solid #f5c2c7;
  color: #9c2030;
  padding: 12px 16px;
  border-radius: 6px;
  margin-bottom: 16px;
  font-size: 13px;
  line-height: 1.5;
}
.form-errors-banner .bi {
  font-size: 18px;
  flex-shrink: 0;
  margin-top: 1px;
}
.form-errors-banner div > div { padding: 1px 0; }

/* Chips radio — daysPerWeek */
.chip-group {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 4px;
}
.chip-group input[type="radio"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.chip-group label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 48px;
  height: 40px;
  padding: 0 14px;
  border: 1.5px solid var(--oct-border);
  border-radius: 999px;
  background: #fff;
  color: var(--oct-text);
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
  transition: all 0.15s ease;
  user-select: none;
  margin: 0;
}
.chip-group label:hover {
  border-color: var(--oct-orange-light);
  background: var(--oct-orange-soft);
}
.chip-group input[type="radio"]:checked + label,
.chip-group label.active {
  background: var(--oct-orange);
  color: #fff;
  border-color: var(--oct-orange);
  box-shadow: 0 1px 3px rgba(242,142,19,0.3);
}
.chip-group input[type="radio"]:focus-visible + label {
  outline: 2px solid var(--oct-orange-light);
  outline-offset: 2px;
}
.chip-group-days label { min-width: 56px; font-size: 15px; }

/* Alertes quota dans CRA (P3) */
/* EVO-037 V2 — refonte du bandeau quota en compact pleine largeur 1 ligne
   (au lieu de 3 lignes empilées). Garde toutes les infos (titre, chiffres,
   barre, message contextuel) mais les compose en flex-row avec wrap
   responsive. Hauteur passe de ~80px à ~36px. */
.cra-quota-banner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  padding: 8px 14px;
  border-radius: 6px;
  margin-bottom: 12px;
  font-size: 13px;
  line-height: 1.35;
  border: 1px solid;
}
.cra-quota-banner-info {
  background: #e7f3fe;
  border-color: #b8d9f5;
  color: #1e5a9c;
}
.cra-quota-banner-warning {
  background: var(--oct-orange-soft);
  border-color: var(--oct-orange-light);
  color: var(--oct-orange-dark);
}
.cra-quota-banner-danger {
  background: #fde8e8;
  border-color: #f5c2c7;
  color: #9c2030;
}
/* EVO-044 — niveau « autorisé » : bleu neutre, distinct du nominal vert (`safe`)
   et du dépassement rouge (`danger`). Activé quand un override d'autorisation
   est positionné sur la variation de période courante (cf. _quota_banner.html.twig).
   Reprend la palette `info` (bleu clair + bordure + texte foncé) — cohérent
   avec `cta-banner-info`. */
.cra-quota-banner-authorized {
  background: #e7f3fe;
  border-color: #b8d9f5;
  color: #1e5a9c;
}

/* ============================================================
   EVO-049/044 — Refonte UX carte « Quota cumulatif »
   Une carte mère, 4 sous-blocs hiérarchisés :
   1. Synthèse (en tête, bleu clair)
   2. Paramétrage (neutre)
   3. Message dépassement (orange clair = couleur du bandeau warning quota)
   4. Variations par période (gris clair, contient les sous-blocs override)
   ============================================================ */

.quota-synthesis {
  background: #e7f3fe;
  border: 1px solid #b8d9f5;
  border-left: 4px solid #1e5a9c;
  border-radius: 6px;
  padding: 12px 16px;
  margin-bottom: 18px;
  font-size: 13px;
  color: #1e5a9c;
}
.quota-synthesis-title {
  font-weight: 600;
  margin-bottom: 6px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.quota-synthesis-list {
  margin: 0;
  padding-left: 18px;
  line-height: 1.7;
  color: var(--oct-text);
}
.quota-synthesis-muted { color: var(--oct-text-muted); }
.quota-synthesis-override {
  color: #1e5a9c;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.quota-section-title {
  font-weight: 600;
  font-size: 13px;
  color: var(--oct-text);
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 6px;
}

.quota-guard-warning {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: var(--oct-orange-soft);
  border: 1px solid var(--oct-orange-light);
  border-left: 4px solid var(--oct-orange);
  border-radius: 6px;
  padding: 10px 14px;
  margin-top: 10px;
  font-size: 13px;
  color: var(--oct-orange-dark);
}
.quota-guard-warning i.bi-exclamation-triangle-fill { font-size: 16px; flex-shrink: 0; }

.quota-overflow-block {
  background: var(--oct-orange-soft);
  border: 1px solid var(--oct-orange-light);
  border-radius: 6px;
  padding: 14px;
  margin: 18px 0;
}
.quota-overflow-title {
  font-weight: 600;
  font-size: 13px;
  color: var(--oct-orange-dark);
  margin-bottom: 6px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.quota-overflow-optional {
  font-weight: 400;
  color: var(--oct-text-muted);
  font-size: 12px;
}
.quota-overflow-desc {
  font-size: 12px;
  color: var(--oct-orange-dark);
  margin: 0 0 8px 0;
  line-height: 1.5;
}

.quota-variations-block {
  background: #fafbfc;
  border: 1px solid var(--oct-border);
  border-radius: 6px;
  padding: 14px;
  margin-top: 8px;
}
.quota-variations-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}
.quota-variations-title {
  font-weight: 600;
  font-size: 13px;
  color: var(--oct-text);
  display: flex;
  align-items: center;
  gap: 6px;
}
.quota-variations-desc {
  font-size: 12px;
  color: var(--oct-text-muted);
  margin: 4px 0 0 0;
  line-height: 1.5;
}

/* Ligne de variation : fond blanc pour contraste avec le bloc parent gris */
.quota-period-row {
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 6px;
  padding: 14px;
  margin-bottom: 10px;
}
.quota-period-row:last-child { margin-bottom: 0; }

.quota-override-fieldset {
  border: 1px dashed var(--oct-border);
  border-radius: 6px;
  padding: 10px 12px;
  margin-top: 10px;
  background: #fafbfc;
}
.quota-override-fieldset legend {
  font-size: 12px;
  color: var(--oct-text-muted);
  padding: 0 6px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

/* ===== Vue user engagement — blocs multi-règles / multi-portages (EVO-054) ===== */
.engagement-multi-block {
  background: #fafbfc;
  border: 1px solid var(--oct-border);
  border-radius: 6px;
  padding: 12px;
  margin: 10px 0;
}
.engagement-multi-title {
  font-weight: 600;
  font-size: 13px;
  color: var(--oct-text);
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.engagement-multi-synth {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 4px;
  margin-bottom: 10px;
}
.engagement-multi-synth th,
.engagement-multi-synth td {
  padding: 6px 10px;
  text-align: left;
  border-bottom: 1px solid var(--oct-border);
}
.engagement-multi-synth th {
  font-weight: 600;
  color: var(--oct-text-muted);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  background: #f6f7fa;
}
.engagement-multi-synth tr:last-child td { border-bottom: none; }
/* Ligne « active » du tableau synthèse (EVO-054) : fond bleu plus marqué,
   typographie accentuée et bord-gauche orange large pour que l'œil identifie
   la période active au premier coup d'œil sans avoir à lire la colonne État. */
.engagement-multi-synth tr.is-current td {
  background: rgba(30, 90, 156, 0.10);
  font-weight: 600;
  color: var(--oct-text);
}
.engagement-multi-synth tr.is-current td:first-child {
  border-left: 3px solid var(--oct-orange);
}
.engagement-multi-synth tr:not(.is-current) td:first-child {
  border-left: 3px solid transparent;
}
.engagement-multi-synth .num { text-align: right; font-variant-numeric: tabular-nums; }
.engagement-multi-synth .acc-indicator-col {
  width: 24px;
  padding-left: 8px;
  padding-right: 4px;
  text-align: center;
}
.engagement-multi-synth .acc-indicator {
  color: var(--oct-orange);
  font-size: 13px;
}

/* ===== Sous-périodes de portage — synthèse + accordéon (EVO-051) ===== */

.portage-synthesis {
  background: #fafbfc;
  border: 1px solid var(--oct-border);
  border-radius: 6px;
  margin-bottom: 14px;
  overflow: hidden;
}
.portage-synthesis-title {
  font-weight: 600;
  font-size: 13px;
  color: var(--oct-text);
  padding: 10px 14px;
  border-bottom: 1px solid var(--oct-border);
  background: #fff;
  display: flex;
  align-items: center;
  gap: 6px;
}
.portage-synthesis-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
}
.portage-synthesis-table th,
.portage-synthesis-table td {
  padding: 8px 14px;
  text-align: left;
  border-bottom: 1px solid var(--oct-border);
}
.portage-synthesis-table th {
  font-weight: 600;
  color: var(--oct-text-muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  background: #f6f7fa;
}
.portage-synthesis-table tr:last-child td { border-bottom: none; }
.portage-synthesis-table tr.is-current td {
  background: rgba(30, 90, 156, 0.04);
  font-weight: 500;
}
.portage-synthesis-table .portage-rate { text-align: right; font-variant-numeric: tabular-nums; }
.portage-synthesis-table .acc-muted { color: var(--oct-text-muted); font-style: italic; }
.portage-synthesis-empty {
  padding: 14px;
  text-align: center;
  color: var(--oct-text-muted);
  font-size: 13px;
}

/* Classes génériques — utilisées par les sous-périodes de portage (EVO-051)
   et les règles de quota par période (EVO-052). Tout nouvel usage doit
   réutiliser ces classes (cf. docs/components.md → accordion-section). */
.acc-section {
  border: 1px solid var(--oct-border);
  border-radius: 6px;
  margin-bottom: 10px;
  background: #fafbfc;
  overflow: hidden;
}
.acc-section.is-current { border-left: 3px solid var(--oct-orange); }
.acc-header {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 14px;
  background: transparent;
  border: 0;
  text-align: left;
  cursor: pointer;
  font-size: 13px;
  color: var(--oct-text);
  font-family: inherit;
}
.acc-header:hover { background: rgba(0,0,0,0.02); }
.acc-header:focus-visible {
  outline: 2px solid var(--oct-orange);
  outline-offset: -2px;
}
.acc-caret {
  display: inline-block;
  transition: transform 180ms ease;
  color: var(--oct-text-muted);
  flex-shrink: 0;
}
.acc-section.is-open .acc-caret { transform: rotate(90deg); }
.acc-summary {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.acc-summary strong { font-weight: 600; }
.acc-summary .sep { color: var(--oct-text-muted); }
.acc-summary .acc-muted { color: var(--oct-text-muted); font-style: italic; }
.acc-badge {
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  padding: 2px 8px;
  border-radius: 4px;
  background: var(--oct-orange-soft);
  color: var(--oct-orange-dark);
  flex-shrink: 0;
}
.acc-body {
  display: none;
  padding: 0 14px 14px 14px;
  border-top: 1px solid var(--oct-border);
  background: #fff;
}
.acc-section.is-open .acc-body { display: block; padding-top: 14px; }

/* Auto-libellé période à côté du DateType (« 01/07/2026 → S2 2026 ») */
.quota-period-label {
  display: inline-block;
  margin-top: 4px;
  font-size: 12px;
  color: var(--oct-orange-dark);
  font-weight: 500;
  background: var(--oct-orange-soft);
  padding: 2px 8px;
  border-radius: 4px;
}

.cra-quota-banner-title {
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  flex-shrink: 0;
}
.cra-quota-row {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-size: 12.5px;
  flex: 1 1 240px;
  min-width: 180px;
}
/* EVO-037 V2.3 — option D améliorée : donut radial SVG 44px avec
   pourcentage à l'intérieur. Lisible jusqu'à 3 chiffres (« 106% »). */
.cra-quota-donut {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  margin-right: 2px;
}
.cra-quota-donut svg {
  /* Démarre le tracé à 12h plutôt qu'à 3h (rotation -90°). Cohérent avec
     les jauges familières (cadran horloge / vitesse). */
  transform: rotate(-90deg);
}
.cra-quota-donut-bg {
  stroke: rgba(0, 0, 0, 0.10);
}
.cra-quota-donut-bar {
  stroke: currentColor;
  stroke-linecap: butt;
  transition: stroke-dashoffset 0.4s ease;
}
/* Pourcentage centré dans le donut. Hérite de currentColor (donc même
   couleur que le bandeau). Tracking légèrement serré pour « 106% ». */
.cra-quota-donut-pct {
  position: absolute;
  font-size: 11px;
  font-weight: 700;
  color: currentColor;
  letter-spacing: -0.01em;
  line-height: 1;
}

/* La barre linéaire historique reste définie pour rétrocompat si réutilisée
   ailleurs (page CRA list par exemple). Ce qui n'est plus rendu sur le
   bandeau quota lui-même mais le CSS reste valide. */
.cra-quota-progress {
  flex: 1 1 80px;
  height: 3px;
  background: rgba(0,0,0,0.08);
  border-radius: 2px;
  overflow: hidden;
  min-width: 80px;
}
.cra-quota-progress-bar {
  height: 100%;
  transition: width 0.3s ease;
}
.cra-quota-progress-bar-info { background: #1e5a9c; }
.cra-quota-progress-bar-warning { background: var(--oct-orange); }
.cra-quota-progress-bar-danger { background: #c0392b; }
/* EVO-037 V2.1/V2.2 — chip pourcentage (utilisé par les options A et D).
   Hérite de la couleur du bandeau (currentColor) pour cohérence visuelle. */
.cra-quota-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  background: rgba(255, 255, 255, 0.5);
  border: 1px solid currentColor;
  border-radius: 999px;
  font-weight: 700;
  font-size: 11.5px;
  letter-spacing: 0.02em;
  flex-shrink: 0;
  white-space: nowrap;
}
/* Message contextuel (danger/warning) : inline avec le reste sur grand
   écran, passe en dessous sur écran étroit grâce au flex-wrap parent. */
.cra-quota-message {
  font-size: 12px;
  opacity: 0.9;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: 0 1 auto;
}

/* ========================================================================
   FRISE 12 MOIS — page Nouveau CRA
   ======================================================================== */
.frise-card { padding: 18px 20px; }

.frise-header { display: flex; align-items: baseline; justify-content: space-between; }
.frise-title { font-size: 14px; font-weight: 600; color: var(--oct-black); }
.frise-engagement-hint { font-size: 12px; color: var(--oct-text-muted); margin-top: 2px; }

.frise-legend {
  display: flex; flex-wrap: wrap; gap: 14px;
  font-size: 11px; color: var(--oct-text-muted);
  margin: 10px 0 16px;
}
.frise-legend-item { display: inline-flex; align-items: center; gap: 5px; }
.frise-legend-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.frise-legend-dot.st-validated { background: var(--oct-green); }
.frise-legend-dot.st-submitted { background: var(--oct-orange-dark); }
.frise-legend-dot.st-draft { background: var(--oct-orange); }
.frise-legend-dot.st-empty { background: var(--oct-gray); }

.frise {
  display: grid;
  grid-template-columns: repeat(13, minmax(0, 1fr));
  gap: 6px;
}
/* Le `display: grid` ci-dessus a la même spécificité que la règle UA `[hidden]`
   (et passe après), donc l'attribut hidden seul ne masquerait rien. On force
   ici une spécificité supérieure. */
.frise[hidden] { display: none; }

.frise-month {
  border: 1px solid var(--oct-border);
  border-radius: 8px;
  padding: 10px 4px 9px;
  text-align: center;
  background: #fff;
  cursor: pointer;
  transition: transform .12s, box-shadow .12s, border-color .12s, background .12s;
  position: relative;
  min-height: 86px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  text-decoration: none;
  color: inherit;
  font-family: inherit;
  font-size: inherit;
}
.frise-month:hover {
  border-color: var(--oct-orange);
  transform: translateY(-1px);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05);
  text-decoration: none;
}
.frise-month:focus-visible {
  outline: 2px solid var(--oct-orange);
  outline-offset: 2px;
}

.frise-month-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--oct-black);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  line-height: 1.2;
}
.frise-month-year {
  font-size: 10px;
  color: var(--oct-text-muted);
  font-weight: 400;
  line-height: 1.2;
}
.frise-month-icon { font-size: 18px; margin: 4px 0 2px; }
.frise-month-status { font-size: 10px; color: var(--oct-text-muted); font-weight: 500; }

.frise-month.is-validated { background: #f0faf3; border-color: #cce9d5; }
.frise-month.is-validated .frise-month-icon,
.frise-month.is-validated .frise-month-status { color: var(--oct-green); }

.frise-month.is-submitted { background: #fff8ec; border-color: #ffe0b3; }
.frise-month.is-submitted .frise-month-icon,
.frise-month.is-submitted .frise-month-status { color: var(--oct-orange-dark); }

.frise-month.is-draft { background: #fffaf3; border-color: #fde2bf; border-style: dashed; }
.frise-month.is-draft .frise-month-icon,
.frise-month.is-draft .frise-month-status { color: var(--oct-orange); }

.frise-month.is-empty { background: var(--oct-bg); border-style: dashed; border-color: #d6d9e0; }
.frise-month.is-empty .frise-month-icon { color: var(--oct-gray); }
.frise-month.is-empty:hover { background: var(--oct-orange-soft); border-style: solid; border-color: var(--oct-orange); }
.frise-month.is-empty:hover .frise-month-icon,
.frise-month.is-empty:hover .frise-month-status { color: var(--oct-orange-dark); }

.frise-month.is-out {
  opacity: 0.45;
  cursor: not-allowed;
  background: #fafbfc;
  border-style: dotted;
}
.frise-month.is-out:hover { transform: none; box-shadow: none; border-color: var(--oct-border); background: #fafbfc; }

.frise-month.is-current {
  /* EVO-054 — mois pivot mis en évidence sur la frise des CRA :
     bord orange épais + halo (box-shadow) orange-soft pour créer un effet
     « spotlight » qui se distingue sans écraser la couleur du state
     (validated/draft/submitted/missing) qui pilote le background. */
  border: 2px solid var(--oct-orange);
  box-shadow: 0 0 0 3px var(--oct-orange-soft);
  z-index: 1;
}
.frise-month.is-current::after {
  content: "";
  position: absolute;
  top: -3px; right: -3px;
  width: 10px; height: 10px;
  background: var(--oct-orange);
  border-radius: 50%;
  border: 2px solid #fff;
}

/* Tablette : grille 7 colonnes (2 lignes : 7 + 6) */
@media (max-width: 1100px) {
  .frise { grid-template-columns: repeat(7, minmax(0, 1fr)); }
}
/* Mobile : grille 5 colonnes (3 lignes : 5 + 5 + 3) */
@media (max-width: 560px) {
  .frise { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .frise-month { min-height: 80px; }
}

/* ----- Strip groupé par engagement (page Mes CRA, option A) ----- */
.frise-strip-block + .frise-strip-block,
.frise-strip-block-sep { /* alias visuel */ }
.frise-strip-block { padding-top: 4px; }
.frise-strip-block + .frise-strip-block { margin-top: 14px; padding-top: 14px; border-top: 1px dashed var(--oct-border); }

.frise-strip-title {
  font-size: 12px;
  margin-bottom: 8px;
  color: var(--oct-text-muted);
  display: flex; gap: 6px; flex-wrap: wrap; align-items: baseline;
}
.frise-strip-code { font-weight: 600; color: var(--oct-black); }
.frise-strip-name { color: var(--oct-black); }
.frise-strip-client { color: var(--oct-text-muted); }

/* ----- Heatmap engagement × mois (page Mes CRA, option B) ----- */
.frise-heatmap-wrap { overflow-x: auto; }
.frise-heatmap {
  border-collapse: separate;
  border-spacing: 4px;
  width: 100%;
}
.frise-heatmap th,
.frise-heatmap td { padding: 0; }

.hm-corner { width: 220px; }

.hm-col-header {
  width: 56px;
  min-width: 56px;
  text-align: center;
  font-size: 10px;
  font-weight: 500;
  color: var(--oct-text-muted);
  padding: 2px 0;
}
.hm-col-header .hm-col-month {
  font-weight: 600;
  color: var(--oct-black);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  font-size: 10px;
}
.hm-col-header .hm-col-year { font-size: 9px; }
.hm-col-header.is-current { color: var(--oct-orange-dark); }
.hm-col-header.is-current .hm-col-month { color: var(--oct-orange-dark); }

.hm-row-label {
  width: 220px; max-width: 220px;
  text-align: left;
  padding: 4px 12px 4px 4px;
  font-weight: 500;
  font-size: 12px;
  vertical-align: middle;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.hm-row-label .hm-row-code { font-weight: 600; color: var(--oct-black); }
.hm-row-label .hm-row-client { font-size: 11px; color: var(--oct-text-muted); margin-top: 1px; }

.hm-cell-wrap { text-align: center; vertical-align: middle; }
.hm-cell {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  border-radius: 8px;
  border: 1px solid var(--oct-border);
  background: #fff;
  color: var(--oct-gray);
  font-size: 14px;
  text-decoration: none;
  transition: transform .12s, box-shadow .12s, border-color .12s, background .12s;
  position: relative;
}
.hm-cell:hover {
  border-color: var(--oct-orange);
  transform: translateY(-1px);
  box-shadow: 0 3px 8px rgba(0,0,0,0.06);
  text-decoration: none;
}

.hm-cell.is-validated { background: #f0faf3; border-color: #cce9d5; color: var(--oct-green); }
.hm-cell.is-submitted { background: #fff8ec; border-color: #ffe0b3; color: var(--oct-orange-dark); }
.hm-cell.is-draft     { background: #fffaf3; border-color: #fde2bf; border-style: dashed; color: var(--oct-orange); }
.hm-cell.is-empty     { background: var(--oct-bg); border-style: dashed; border-color: #d6d9e0; color: var(--oct-gray); }
.hm-cell.is-empty:hover { background: var(--oct-orange-soft); border-style: solid; border-color: var(--oct-orange); color: var(--oct-orange-dark); }
.hm-cell.is-out       { background: #fafbfc; border-style: dotted; opacity: 0.45; cursor: not-allowed; }
.hm-cell.is-out:hover { transform: none; box-shadow: none; border-color: var(--oct-border); background: #fafbfc; }

.hm-cell.is-current {
  outline: 2px solid var(--oct-orange);
  outline-offset: 1px;
}

/* ========================================================================
   PAGE « MES ENGAGEMENTS »
   ======================================================================== */
.engagement-card .card-body { padding: 18px 20px; }

.engagement-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
}
.engagement-header-text { flex: 1; min-width: 0; }
.engagement-code {
  font-size: 12px;
  font-weight: 600;
  color: var(--oct-orange-dark);
  text-transform: uppercase;
  letter-spacing: 0.6px;
}
.engagement-title { font-size: 16px; font-weight: 600; color: var(--oct-black); margin-top: 2px; }
.engagement-client { font-size: 12px; color: var(--oct-text-muted); margin-top: 2px; }
.engagement-ref { font-family: ui-monospace, Menlo, monospace; font-size: 11px; }

.btn.btn-sm { padding: 6px 12px; font-size: 12.5px; }

.engagement-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 14px;
}
.engagement-chips-compact { gap: 4px; margin-bottom: 0; }

.engagement-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 500;
  background: var(--oct-bg);
  color: var(--oct-black);
  border: 1px solid var(--oct-border);
  white-space: nowrap;
}
.engagement-chip i { font-size: 12px; line-height: 1; }
.engagement-chip-default { /* default tones already set */ }
.engagement-chip-info { background: #eaf3fb; color: #1e5a9c; border-color: #c5dcef; }
.engagement-chip-warning { background: var(--oct-orange-soft); color: var(--oct-orange-dark); border-color: #fde2bf; }
.engagement-chip-danger { background: #fef3f2; color: #c0392b; border-color: #fbcdc6; }
.engagement-chip-success { background: #f0faf3; color: var(--oct-green); border-color: #cce9d5; }
.engagement-chip-muted { background: transparent; color: var(--oct-text-muted); border-style: dashed; }

.engagement-alerts {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 14px;
}
.engagement-alert {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 9px 12px;
  border-radius: 8px;
  font-size: 12.5px;
  border: 1px solid transparent;
  line-height: 1.4;
}
.engagement-alert i { font-size: 14px; margin-top: 1px; flex-shrink: 0; }
.eng-alert-info    { background: #eaf3fb; color: #1e5a9c; border-color: #c5dcef; }
.eng-alert-warning { background: var(--oct-orange-soft); color: var(--oct-orange-dark); border-color: #fde2bf; }
.eng-alert-danger  { background: #fef3f2; color: #c0392b; border-color: #fbcdc6; }

.engagement-quota {
  margin-bottom: 14px;
  padding: 10px 12px;
  background: var(--oct-bg);
  border-radius: 8px;
  border: 1px solid var(--oct-border);
}
.engagement-quota-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 12px;
  margin-bottom: 6px;
  gap: 12px;
  flex-wrap: wrap;
}
.engagement-quota-label { color: var(--oct-text-muted); display: inline-flex; align-items: center; gap: 6px; }
.engagement-quota-value { font-weight: 600; color: var(--oct-black); }

.engagement-frise-wrap { margin-top: 6px; }

.badge-alert {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
}
.badge-alert-info    { background: #eaf3fb; color: #1e5a9c; }
.badge-alert-warning { background: var(--oct-orange-soft); color: var(--oct-orange-dark); }
.badge-alert-danger  { background: #fef3f2; color: #c0392b; }

.eng-table td { vertical-align: middle; }

.engagement-archive {
  margin-top: 18px;
}
.engagement-archive > summary {
  cursor: pointer;
  padding: 10px 14px;
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  color: var(--oct-text-muted);
  user-select: none;
  display: flex;
  align-items: center;
  gap: 8px;
  list-style: none;
}
.engagement-archive > summary::-webkit-details-marker { display: none; }
.engagement-archive > summary::before {
  content: "▸";
  font-size: 10px;
  transition: transform .15s;
  display: inline-block;
}
.engagement-archive[open] > summary::before { transform: rotate(90deg); }
.engagement-archive > summary:hover { color: var(--oct-black); border-color: var(--oct-orange); }

/* ----- Pavé Dashboard : engagements actifs (lignes compactes) ----- */
.dashboard-engagements {
  list-style: none;
  padding: 0;
  margin: 0;
}
.dashboard-engagement {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 18px 12px 14px;
  border-bottom: 1px solid var(--oct-border);
  border-left: 4px solid transparent;
  transition: background .12s;
}
.dashboard-engagement:last-child { border-bottom: none; }
.dashboard-engagement:hover { background: #fafbfc; }

.dashboard-engagement.state-missing  { border-left-color: #c0392b; }
.dashboard-engagement.state-draft    { border-left-color: var(--oct-orange); }
.dashboard-engagement.state-submitted { border-left-color: var(--oct-orange-dark); }
.dashboard-engagement.state-validated { border-left-color: var(--oct-green); }

.dashboard-engagement .de-icon {
  width: 32px; height: 32px;
  border-radius: 8px;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  font-size: 15px;
  background: var(--oct-bg);
  color: var(--oct-text-muted);
}
.dashboard-engagement.state-missing  .de-icon,
.de-icon.state-missing                          { background: #fef3f2; color: #c0392b; }
.dashboard-engagement.state-draft    .de-icon,
.de-icon.state-draft                            { background: #fffaf3; color: var(--oct-orange); }
.dashboard-engagement.state-submitted .de-icon,
.de-icon.state-submitted                        { background: var(--oct-orange-soft); color: var(--oct-orange-dark); }
.dashboard-engagement.state-validated .de-icon,
.de-icon.state-validated                        { background: #f0faf3; color: var(--oct-green); }

/* Libellé contextuel du mois courant à droite du badge statut, sur dashboard
   ET /cra — désambigüise « Soumis » en « Soumis · mai 2026 » (EVO-021 v3). */
.de-month-label {
  color: var(--oct-text-muted);
  font-size: 12px;
  font-weight: 400;
}

/* Bloc head d'engagement sur /cra : icône statut à gauche + body à droite,
   layout flex aligné comme le dashboard. La frise des 13 mois reste dessous. */
.frise-strip-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 10px;
}
.frise-strip-head .de-body { flex: 1; min-width: 0; }

.dashboard-engagement .de-body { flex: 1; min-width: 0; }
.dashboard-engagement .de-line1 {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-bottom: 3px;
}
.dashboard-engagement .de-code { font-weight: 600; color: var(--oct-black); font-size: 13px; }
.dashboard-engagement .de-client { color: var(--oct-text-muted); font-size: 12px; }

.dashboard-engagement .de-line2,
.frise-strip-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
  font-size: 12px;
  color: var(--oct-text-muted);
}
.dashboard-engagement .de-line2 strong,
.frise-strip-meta strong               { color: var(--oct-black); font-weight: 600; }
.dashboard-engagement .de-sep,
.frise-strip-meta .de-sep              { color: #d6d9e0; }
.dashboard-engagement .de-cta,
.frise-strip-meta .de-cta              { color: #c0392b; font-weight: 500; }
/* Sous-ligne meta de la frise /cra (EVO-021) — léger espace vertical avec le
   titre de l'engagement au-dessus + retrait à gauche pour aligner sous le code. */
.frise-strip-meta { margin: 6px 0 4px; }

.dashboard-engagement .de-alert,
.frise-strip-meta .de-alert {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 7px;
  border-radius: 999px;
  font-weight: 500;
  font-size: 11px;
}
.dashboard-engagement .de-alert.tone-info,
.frise-strip-meta .de-alert.tone-info       { background: #eaf3fb; color: #1e5a9c; }
.dashboard-engagement .de-alert.tone-warning,
.frise-strip-meta .de-alert.tone-warning    { background: var(--oct-orange-soft); color: var(--oct-orange-dark); }
.dashboard-engagement .de-alert.tone-danger,
.frise-strip-meta .de-alert.tone-danger     { background: #fef3f2; color: #c0392b; }

/* EVO-054 — chip muted « +N portages / +N règles » : secondaire visuel,
   pour ne pas concurrencer la chip Quota Y% (alert tonée) qui reste l'élément
   d'attention principal. Tooltip natif au hover via attribut title=. */
.dashboard-engagement .de-meta-muted,
.frise-strip-meta .de-meta-muted {
  font-size: 11px;
  color: var(--oct-text-muted);
  font-weight: 500;
  cursor: help;
  border-bottom: 1px dotted var(--oct-text-muted);
}

.dashboard-engagement .de-action {
  flex-shrink: 0;
  font-size: 12px;
  font-weight: 500;
  color: var(--oct-orange);
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.dashboard-engagement .de-action:hover { color: var(--oct-orange-dark); text-decoration: none; }

.dashboard-engagement-more {
  padding: 10px 18px;
  text-align: center;
  font-size: 12px;
  color: var(--oct-text-muted);
}
.dashboard-engagement-more a { color: var(--oct-orange); }

/* ============================================================
   Catalogue de libellés CRA (form Engagement)
   - Une ligne = drag-handle + icône + label + switch worked + switch enabled + delete
   - Le switch isWorked est central : il bascule entre "travaillé" (briefcase orange)
     et "non travaillé" (cup-hot gris)
   ============================================================ */
.labels-card .card-body { padding: 16px 18px; }

.lbl-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  font-size: 11px;
  color: var(--oct-text-muted);
  margin-bottom: 14px;
  padding-bottom: 12px;
  border-bottom: 1px dashed var(--oct-border);
}
.lbl-legend-item { display: inline-flex; align-items: center; gap: 6px; }

.lbl-row {
  display: grid;
  grid-template-columns: 24px 36px 1fr auto auto auto auto 32px;
  gap: 10px;
  align-items: center;
  padding: 8px 10px;
  margin-bottom: 8px;
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 8px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.lbl-row:hover { border-color: var(--oct-orange-light); box-shadow: 0 2px 6px rgba(242, 142, 19, 0.06); }
.lbl-row .drag-handle {
  cursor: grab;
  color: #c9ced9;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
}
.lbl-row .drag-handle:hover { color: var(--oct-orange); }
.lbl-row .drag-handle:active { cursor: grabbing; }

.lbl-icon {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  transition: background .2s ease, color .2s ease;
}
.lbl-icon-worked { background: var(--oct-orange-soft); color: var(--oct-orange-dark); }
.lbl-icon-off { background: #eef2f7; color: #6b7280; }

.lbl-input { font-size: 14px; }
.lbl-input:focus { border-color: var(--oct-orange); }

/* Switch dédié travaillé / non travaillé : pastille avec icône qui glisse. */
.lbl-switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  user-select: none;
  margin: 0;
}
.lbl-worked-input { position: absolute; opacity: 0; pointer-events: none; }
.lbl-track {
  position: relative;
  width: 64px;
  height: 28px;
  background: #d4d8e0;
  border-radius: 999px;
  transition: background .2s ease;
  display: flex;
  align-items: center;
  padding: 0 6px;
  justify-content: space-between;
  font-size: 12px;
}
.lbl-track::after {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(0,0,0,0.18);
  transition: left .2s ease, background .2s ease;
}
.lbl-track-on, .lbl-track-off {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  transition: opacity .2s ease;
}
.lbl-track-on { color: #fff; opacity: 0; }
.lbl-track-off { color: #6b7280; opacity: 1; }

.lbl-worked-input:checked + .lbl-track {
  background: var(--oct-orange);
}
.lbl-worked-input:checked + .lbl-track::after { left: 39px; }
.lbl-worked-input:checked + .lbl-track .lbl-track-on { opacity: 1; }
.lbl-worked-input:checked + .lbl-track .lbl-track-off { opacity: 0; }

/* Petit switch enabled/disabled (réutilise opt-input + opt-track existants) */
.lbl-enabled-switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  margin: 0;
  width: 44px;
  height: 24px;
}
.lbl-enabled-switch .opt-input { position: absolute; opacity: 0; pointer-events: none; width: 0; height: 0; }
.lbl-enabled-switch .opt-track {
  position: relative;
  width: 44px;
  height: 24px;
  background: #d4d8e0;
  border-radius: 999px;
  transition: background .2s ease;
  margin: 0; /* surcharge la règle générique .opt-track { margin-top: 7px } qui casse l'alignement en grid */
  flex-shrink: 0;
}
.lbl-enabled-switch .opt-track::before {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(0,0,0,0.18);
  transition: left .2s ease;
}
.lbl-enabled-switch .opt-input:checked ~ .opt-track { background: var(--oct-green); }
.lbl-enabled-switch .opt-input:checked ~ .opt-track::before {
  left: 23px;
  transform: none; /* neutralise le translateX(20px) de la règle générique .opt-track::before qui faisait sortir le thumb du pill */
}

.lbl-row .lbl-remove {
  color: #c9ced9;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  transition: background .15s ease, color .15s ease;
}
.lbl-row .lbl-remove:hover { background: #fde8e8; color: #dc3545; }

/* Sélecteur de couleur d'accent (F17) — input natif type=color recadré. */
.lbl-color-input {
  width: 38px;
  height: 30px;
  padding: 2px;
  border: 1px solid var(--oct-border);
  border-radius: 7px;
  background: #fff;
  cursor: pointer;
  flex-shrink: 0;
}
.lbl-color-input::-webkit-color-swatch-wrapper { padding: 0; }
.lbl-color-input::-webkit-color-swatch { border: none; border-radius: 4px; }
.lbl-color-input::-moz-color-swatch { border: none; border-radius: 4px; }

/* Bouton-icône « déclarable comme absence » (F17) : carré bleu allumé / gris éteint. */
.lbl-abs-switch {
  position: relative;
  display: inline-flex;
  width: 32px;
  height: 32px;
  cursor: pointer;
  margin: 0;
}
.lbl-abs-switch .opt-input { position: absolute; opacity: 0; pointer-events: none; width: 0; height: 0; }
.lbl-abs-switch .opt-track {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: #eef2f7;
  color: #9aa3b2;
  font-size: 15px;
  margin: 0;
  transition: background .15s ease, color .15s ease;
}
.lbl-abs-switch .opt-track::before { content: none; display: none; }
.lbl-abs-switch .opt-input:checked ~ .opt-track { background: #e0f2fe; color: #0284c7; }
.lbl-abs-switch .opt-input:focus-visible ~ .opt-track { outline: 3px solid #bae6fd; outline-offset: 1px; }
/* Désactivée : libellé travaillé → la déclaration en absence n'a pas de sens. */
.lbl-abs-switch.is-disabled { opacity: .3; cursor: not-allowed; pointer-events: none; }

/* ============================================================
   F17 — Planning des absences (liste « Mes absences » + formulaire)
   ============================================================ */

/* ---- Liste : carte d'une déclaration d'absences ---- */
.abs-card { margin-bottom: 16px; padding: 0; overflow: hidden; }
.abs-card-head {
  display: flex; align-items: center; gap: 16px;
  padding: 14px 18px; border-bottom: 1px solid var(--oct-border);
}
.abs-card-icon {
  width: 42px; height: 42px; border-radius: 10px; flex-shrink: 0;
  background: var(--oct-orange-soft); color: var(--oct-orange-dark);
  display: flex; align-items: center; justify-content: center; font-size: 20px;
}
.abs-card-head-main { flex: 1; min-width: 0; }
.abs-card-period { font-size: 15px; font-weight: 700; color: var(--oct-black); }
.abs-card-meta { font-size: 12px; color: var(--oct-text-muted); margin-top: 2px; }
.abs-card-total { text-align: right; flex-shrink: 0; padding-right: 6px; }
.abs-card-total .v { font-size: 20px; font-weight: 700; color: var(--oct-orange-dark); line-height: 1; }
.abs-card-total .l { font-size: 10px; color: var(--oct-text-muted); text-transform: uppercase; letter-spacing: .5px; }
.abs-card-actions { display: flex; gap: 2px; flex-shrink: 0; }

.abs-detail-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.abs-detail-table thead th {
  text-align: left; padding: 8px 18px;
  font-size: 10px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--oct-text-muted); font-weight: 600; background: var(--oct-bg);
}
.abs-detail-table tbody td { padding: 10px 18px; border-bottom: 1px solid var(--oct-border); }
.abs-detail-table tbody tr:last-child td { border-bottom: none; }
.abs-detail-table .col-days { text-align: right; white-space: nowrap; width: 120px; }
.abs-detail-table .col-period { white-space: nowrap; width: 210px; }
.abs-detail-table .days-value { font-weight: 700; color: var(--oct-orange-dark); }
.abs-detail-table .note { color: var(--oct-text-muted); }

.abs-type { display: inline-flex; align-items: center; gap: 7px; font-weight: 600; }
.abs-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; display: inline-block; }
.abs-frac {
  display: inline-block; margin-left: 5px;
  font-size: 10px; font-weight: 700; color: var(--oct-orange-dark);
  background: var(--oct-orange-soft); border-radius: 4px; padding: 1px 5px;
}

.abs-card-comment {
  display: flex; gap: 8px; align-items: flex-start;
  padding: 11px 18px; background: #fff8eb;
  border-top: 1px solid var(--oct-border);
  font-size: 12.5px; color: #6b4700;
}
.abs-card-comment i { color: var(--oct-orange); margin-top: 1px; }

.abs-empty { text-align: center; padding: 50px 24px; }
/* Cible uniquement le grand picto (enfant direct) — pas l'icône du bouton. */
.abs-empty > i { font-size: 44px; color: var(--oct-orange-light); }
.abs-empty h3 { margin: 14px 0 6px; font-size: 17px; }
.abs-empty p { color: var(--oct-text-muted); font-size: 13px; margin: 0 auto 18px; max-width: 440px; }

/* ---- Formulaire de déclaration ---- */
.abs-form-wrap { max-width: 1080px; }

.abs-intro {
  display: flex; gap: 11px; align-items: flex-start;
  background: #fff8eb; border: 1px solid var(--oct-orange-light);
  border-left: 4px solid var(--oct-orange);
  border-radius: 8px; padding: 12px 15px; margin-bottom: 16px;
  font-size: 12.5px; color: #6b4700; line-height: 1.55;
}
.abs-intro i { color: var(--oct-orange); font-size: 16px; margin-top: 1px; }

.abs-section-title { font-size: 13px; font-weight: 700; color: var(--oct-black); display: inline-flex; align-items: center; gap: 8px; }
.abs-section-title i { color: var(--oct-orange); }
.abs-section-sub { font-size: 11.5px; color: var(--oct-text-muted); font-weight: 400; margin-top: 3px; }

.abs-detail-head,
.abs-detail-row {
  display: grid;
  grid-template-columns: 1.3fr 1fr 1fr 1fr 1.7fr 36px;
  gap: 10px;
  align-items: center;
}
.abs-detail-head {
  padding: 0 10px 6px;
  font-size: 10px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--oct-text-muted); font-weight: 600;
}
.abs-detail-row {
  padding: 9px 10px; margin-bottom: 8px;
  background: #fff; border: 1px solid var(--oct-border); border-radius: 8px;
  transition: border-color .15s, box-shadow .15s;
}
.abs-detail-row:hover { border-color: var(--oct-orange-light); box-shadow: 0 2px 6px rgba(242,142,19,0.06); }
.abs-detail-row .form-control,
.abs-detail-row .form-select { padding: 7px 10px; font-size: 13px; }
.abs-detail-remove {
  width: 32px; height: 32px; border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  color: #c9ced9; background: transparent; border: none; cursor: pointer;
  transition: background .15s, color .15s;
}
.abs-detail-remove:hover { background: #fde8e8; color: #dc3545; }
/* EVO-043 Phase B — ligne verrouillée par un CRA Soumis/Validé.
   Reste lisible mais signalée par un fond grisé, un cadenas et une
   atténuation. Les inputs sont rendus `disabled` côté Twig. */
.abs-detail-row.is-locked {
  background: #f7f7f8;
  border-color: #d8d8de;
  opacity: .85;
}
.abs-detail-row.is-locked:hover { border-color: #d8d8de; box-shadow: none; }
.abs-detail-row.is-locked .form-control,
.abs-detail-row.is-locked .form-select { background-color: #fafafa; cursor: not-allowed; }
.abs-detail-locked {
  width: 32px; height: 32px; border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  color: #8a8a93;
  cursor: help;
}
.abs-detail-errors { grid-column: 1 / -1; }
.abs-detail-errors:empty { display: none; }
.abs-detail-errors ul { margin: 4px 0 0; padding-left: 18px; color: #dc3545; font-size: 12px; }

.abs-add-row {
  display: flex; align-items: center; gap: 7px;
  margin-top: 4px; padding: 9px 12px;
  border: 1px dashed var(--oct-border); border-radius: 8px;
  background: var(--oct-bg); color: var(--oct-text-muted);
  font-size: 12px; cursor: pointer; width: 100%;
  transition: all .15s;
}
.abs-add-row:hover { border-color: var(--oct-orange); color: var(--oct-orange-dark); background: var(--oct-orange-soft); }

.abs-detail-total {
  display: flex; align-items: center; justify-content: flex-end; gap: 8px;
  margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--oct-border);
  font-size: 13px;
}
.abs-detail-total .v { font-size: 17px; font-weight: 700; color: var(--oct-orange-dark); }

@media (max-width: 860px) {
  .abs-detail-head { display: none; }
  .abs-detail-row { grid-template-columns: 1fr 1fr; }
}

/* Sélecteur de libellé dans la grille CRA (remplace l'input texte libre). */
.label-cell {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}
.line-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 6px;
  flex-shrink: 0;
  font-size: 13px;
  transition: background .15s ease, color .15s ease;
}
.line-icon-worked { background: var(--oct-orange-soft); color: var(--oct-orange-dark); }
.line-icon-off { background: #eef2f7; color: #6b7280; }

.label-select {
  flex: 1;
  min-width: 0;
  border: 1px solid transparent;
  background: transparent;
  padding: 6px 8px;
  font-size: 13px;
  border-radius: 4px;
  cursor: pointer;
  font-family: inherit;
  color: var(--oct-black);
}
.label-select:hover { border-color: var(--oct-border); background: #fff; }
.label-select:focus { border-color: var(--oct-orange); background: #fff; outline: none; }
.label-select.is-non-worked { color: #6b7280; font-style: italic; }
.label-select option.is-non-worked { color: #6b7280; }

/* Affichage readonly (CRA non éditable) — alignement de l'icône avec le libellé */
.label-edit-readonly {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* Drag-handle du CRA edit (réordonnancement des lignes via SortableJS) */
.cra-drag-handle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  cursor: grab;
  color: #c9ced9;
  font-size: 14px;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity .15s ease, color .15s ease;
}
.cra-grid tr:hover .cra-drag-handle,
.cra-grid tr:focus-within .cra-drag-handle { opacity: 1; }
.cra-drag-handle:hover { color: var(--oct-orange); }
.cra-drag-handle:active { cursor: grabbing; }

/* Effets visuels SortableJS pendant le drag */
.cra-row-ghost { opacity: 0.4; background: var(--oct-orange-soft); }
.cra-row-chosen { background: #fff; box-shadow: 0 4px 12px rgba(0,0,0,0.08); }
.label-col .lbl-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 4px;
  margin-left: 6px;
  font-weight: 600;
  vertical-align: middle;
}
.lbl-pill-worked { background: var(--oct-orange-soft); color: var(--oct-orange-dark); }
.lbl-pill-off { background: #eef2f7; color: #6b7280; }

/* ============================================================
   Dialog de confirmation réutilisable (assets/utils/confirm.js)
   - 3 variantes : default / warning / danger
   - icône en pastille ronde + titre + message + 2 boutons
   - <form method="dialog"> en interne (fermeture native fiable)
   ============================================================ */
.app-confirm {
  border: none;
  border-radius: 14px;
  padding: 0;
  max-width: 480px;
  width: 92%;
  box-shadow: 0 24px 60px rgba(0,0,0,0.22), 0 0 0 1px rgba(0,0,0,0.04);
  background: #fff;
  color: var(--oct-black);
  overflow: hidden;
  animation: appConfirmIn .18s ease-out;
}
@keyframes appConfirmIn {
  from { transform: translateY(8px) scale(.98); opacity: 0; }
  to   { transform: translateY(0) scale(1); opacity: 1; }
}
.app-confirm::backdrop {
  background: rgba(15, 23, 42, 0.45);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
}

.app-confirm .app-confirm-form {
  margin: 0;
  display: flex;
  flex-direction: column;
}

.app-confirm .app-confirm-head {
  display: flex;
  gap: 14px;
  padding: 22px 22px 18px;
  align-items: flex-start;
}

.app-confirm .app-confirm-icon {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.app-confirm .app-confirm-icon i {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  background: var(--oct-orange-soft);
  color: var(--oct-orange-dark);
}
.app-confirm-info    .app-confirm-icon i { background: #dbeafe; color: #2563eb; }
.app-confirm-warning .app-confirm-icon i { background: #fef3c7; color: #d97706; }
.app-confirm-danger  .app-confirm-icon i { background: #fde8e8; color: #dc3545; }

.app-confirm .app-confirm-body {
  flex: 1;
  min-width: 0;
}
.app-confirm .app-confirm-title {
  font-size: 16px;
  font-weight: 700;
  margin-bottom: 6px;
  color: var(--oct-black);
}
.app-confirm .app-confirm-message {
  font-size: 13px;
  line-height: 1.55;
  color: #4b5563;
}
.app-confirm .app-confirm-message strong { color: var(--oct-black); }

.app-confirm .app-confirm-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  padding: 12px 22px;
  border-top: 1px solid var(--oct-border);
  background: #fafbfc;
}
.app-confirm .app-confirm-actions .btn { min-width: 96px; }

/* Bouton danger générique (peut servir ailleurs) */
.btn-danger {
  background: #dc3545;
  color: #fff;
  border: 1px solid #dc3545;
}
.btn-danger:hover { background: #c12b3a; border-color: #c12b3a; color: #fff; }
.btn-warning {
  background: #d97706;
  color: #fff;
  border: 1px solid #d97706;
}
.btn-warning:hover { background: #b45309; border-color: #b45309; color: #fff; }

/* ============================================================
   Feedback de soumission — bouton + overlay (EVO-004)
   Piloté par les contrôleurs Stimulus `ajax-modal-form` (modales)
   et `form-submit` (forms page-pleine), via le module utilitaire
   `assets/utils/form_feedback.js`. Le module pose la classe
   `.is-submitting` sur le bouton et le host (dialog ou form), et
   injecte un `<div class="form-overlay">` dans le host.
   ============================================================ */
@keyframes oct-spin {
  to { transform: rotate(360deg); }
}
@keyframes oct-overlay-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Spinner inline (dans le bouton submit) */
.spinner-inline {
  display: inline-block;
  width: 0.9em;
  height: 0.9em;
  vertical-align: -2px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: oct-spin 0.7s linear infinite;
}
.btn.is-submitting {
  cursor: progress;
  opacity: 0.85;
}

/* Overlay injecté dans le host (modale ou form standalone).
   Le voile couvre le host (le <dialog> pour une modale, ou tout le viewport
   pour un form standalone — variante ci-dessous). La carte est en
   `position: fixed` et toujours centrée dans le viewport : sur un form long
   qui dépasse la fenêtre, l'utilisateur voit la confirmation même quand il
   a cliqué sur un bouton en bas de page. */
.form-overlay {
  position: absolute;
  inset: 0;
  z-index: 10;
  background: rgba(255, 255, 255, 0.72);
  pointer-events: auto;
  border-radius: inherit;
  animation: oct-overlay-fade-in 0.18s ease-out;
  backdrop-filter: blur(1px);
  -webkit-backdrop-filter: blur(1px);
}
/* Forms page-pleine : voile full-viewport pour couvrir aussi header/sidebar
   et signaler que toute la page est gelée pendant la soumission. */
form[data-controller~="form-submit"].is-submitting > .form-overlay,
form[data-controller~="confirm-submit"].is-submitting > .form-overlay {
  position: fixed;
  z-index: 1000;
  border-radius: 0;
}
.form-overlay-card {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 1001;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 20px 28px;
  background: #fff;
  border: 1px solid var(--oct-border, #e5e7eb);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.form-overlay-spinner {
  display: block;
  width: 36px;
  height: 36px;
  border: 3px solid var(--oct-orange, #d97706);
  border-right-color: transparent;
  border-radius: 50%;
  animation: oct-spin 0.7s linear infinite;
}
.form-overlay-label {
  font-size: 13px;
  font-weight: 500;
  color: var(--oct-text, #1f2937);
  letter-spacing: 0.2px;
}

/* Cibles de l'overlay : doivent pouvoir contenir un `position: absolute` */
dialog.modal-dialog.is-submitting {
  cursor: wait;
}
form[data-controller~="form-submit"] {
  position: relative;
}
form[data-controller~="form-submit"].is-submitting,
form[data-controller~="confirm-submit"].is-submitting {
  cursor: wait;
}
/* EVO-023 — `confirm-submit` couvre des forms souvent inline (corbeille de
   ligne, barre bulk, transitions CRA). On ne force PAS `position: relative`
   sur le form pour éviter de casser des layouts (sticky bar, table cell) ;
   le voile passe en `position: fixed` (cf. règle au-dessus) et la carte
   centrale est déjà fixed centrée viewport. */

/* ============================================================
   Feedback visuel recherche SIRENE (EVO-003)
   Spinner intégré à droite du champ, actif pendant le debounce
   et la requête. Classe `.is-loading` posée par sirene-search.
   ============================================================ */
.sirene-input-wrap {
  position: relative;
}
.sirene-input-wrap > input.form-control {
  padding-right: 36px;
}
.sirene-input-wrap.is-loading::after {
  content: "";
  position: absolute;
  top: 50%;
  right: 12px;
  width: 14px;
  height: 14px;
  margin-top: -7px;
  border: 2px solid var(--oct-orange, #d97706);
  border-right-color: transparent;
  border-radius: 50%;
  animation: oct-spin 0.7s linear infinite;
  pointer-events: none;
}

/* ============================================================
   Pages d'erreur 403 / 404 / 500 / fallback (EVO-001)
   Layout centré sur fond clair, indépendant de la sidebar — les
   templates étendent directement base.html.twig pour rester
   utilisables aussi par les utilisateurs non authentifiés.
   ============================================================ */
.error-page-wrap {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(180deg, #fafafa 0%, #f3f4f6 100%);
  padding: 40px 20px;
}
/* Quand la carte est embed dans le layout (utilisateur authentifié, sidebar
   conservée), on n'a pas besoin du min-height: 100vh ni du fond gradient —
   le `<div class="page">` du layout fournit déjà l'enveloppe. Padding plus
   compact pour laisser respirer sans gaspiller d'espace. */
.app-layout .error-page-wrap {
  min-height: auto;
  background: transparent;
  padding: 40px 0 20px;
}
.error-page-card {
  max-width: 560px;
  width: 100%;
  background: #fff;
  border: 1px solid var(--oct-border, #e5e7eb);
  border-radius: 14px;
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.06);
  padding: 44px 40px 36px;
  text-align: center;
}
.error-page-illustration {
  font-size: 56px;
  color: var(--oct-orange, #d97706);
  margin-bottom: 8px;
  line-height: 1;
}
.error-page-code {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 1.3px;
  text-transform: uppercase;
  color: var(--oct-text-muted, #6b7280);
  margin-bottom: 6px;
}
.error-page-title {
  font-size: 22px;
  font-weight: 700;
  color: var(--oct-text, #1f2937);
  margin: 0 0 14px;
}
.error-page-message {
  font-size: 15px;
  color: var(--oct-text, #1f2937);
  margin: 0 0 10px;
  line-height: 1.5;
}
.error-page-explainer {
  font-size: 13px;
  color: var(--oct-text-muted, #6b7280);
  margin: 0 0 28px;
  line-height: 1.5;
}
.error-page-actions {
  display: flex;
  gap: 10px;
  justify-content: center;
  flex-wrap: wrap;
}

/* Bloc « Détails techniques » sous la carte 500 — réservé ROLE_ADMIN/SUPER_ADMIN.
   Discret par défaut (replié), monospace pour le contenu, déployable via le
   <details>/<summary> natif HTML5 (pas de JS requis). */
.error-page-tech-wrap {
  max-width: 760px;
  margin: -10px auto 40px;
  padding: 0 20px;
}
.error-page-tech {
  background: #fff;
  border: 1px solid var(--oct-border, #e5e7eb);
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
}
.error-page-tech > summary {
  list-style: none;
  cursor: pointer;
  padding: 14px 18px;
  font-size: 13px;
  font-weight: 600;
  color: var(--oct-text-muted, #6b7280);
  display: flex;
  align-items: center;
  gap: 10px;
  user-select: none;
}
.error-page-tech > summary::-webkit-details-marker { display: none; }
.error-page-tech > summary::after {
  content: "▾";
  margin-left: auto;
  font-size: 12px;
  transition: transform 0.18s ease;
}
.error-page-tech[open] > summary::after { transform: rotate(180deg); }
.error-page-tech > summary i {
  color: var(--oct-orange, #d97706);
  font-size: 14px;
}
.error-page-tech-hint {
  font-weight: 400;
  font-size: 11.5px;
  color: var(--oct-text-muted, #6b7280);
  margin-left: 4px;
  font-style: italic;
}
.error-page-tech-body {
  padding: 14px 18px 18px;
  border-top: 1px solid var(--oct-border, #e5e7eb);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.error-page-tech-row {
  display: flex;
  gap: 12px;
  font-size: 12.5px;
  line-height: 1.5;
}
.error-page-tech-key {
  flex: 0 0 70px;
  font-weight: 600;
  color: var(--oct-text-muted, #6b7280);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 11px;
  padding-top: 2px;
}
.error-page-tech-val {
  flex: 1;
  background: #f8f9fb;
  padding: 4px 8px;
  border-radius: 4px;
  font-family: ui-monospace, SF Mono, Menlo, monospace;
  font-size: 12px;
  color: var(--oct-text, #1f2937);
  word-break: break-all;
  white-space: pre-wrap;
}
/* Type d'erreur — orange Octevia + gras pour le mettre en évidence (c'est
   l'info la plus utile à transmettre au support pour identifier la cause). */
.error-page-tech-val.error-page-tech-class {
  color: var(--oct-orange, #d97706);
  font-weight: 700;
}
.error-page-tech-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  margin-top: 8px;
  padding-top: 14px;
  border-top: 1px dashed var(--oct-border, #e5e7eb);
}
.error-page-tech-actions-hint {
  font-size: 11.5px;
  color: var(--oct-text-muted, #6b7280);
  font-style: italic;
}

/* ============================================================
   Barre d'actions groupées sur listes admin (EVO-015)
   Position : sticky-TOP au-dessus du tableau (sous les filtres),
   apparaît dès au moins 1 ligne cochée via le contrôleur Stimulus
   bulk-select. Slide-down à l'apparition. Choix sticky-top plutôt
   que sticky-bottom : éviter le conflit avec la profiler toolbar
   Symfony en dev + visibilité immédiate sans scroller.
   ============================================================ */
@keyframes bulk-bar-slide-down {
  from { transform: translateY(-100%); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}
.bulk-action-bar {
  position: sticky;
  top: 0;
  background: var(--oct-orange-soft, #fff4e2);
  border: 1px solid var(--oct-orange-light, #fbd38d);
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(217, 119, 6, 0.08);
  padding: 10px 16px;
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  z-index: 30;
  animation: bulk-bar-slide-down 0.16s ease-out;
}
.bulk-action-bar[hidden] { display: none; }
.bulk-action-bar-count {
  font-weight: 500;
  color: var(--oct-orange-dark, #d97a05);
  font-size: 13.5px;
}
.bulk-action-bar-count strong {
  color: var(--oct-orange-dark, #d97a05);
  font-size: 15px;
  font-weight: 700;
}
.bulk-action-bar-actions {
  display: flex;
  gap: 8px;
  align-items: center;
}
.bulk-action-bar-actions form { display: inline; margin: 0; }
.bulk-action-bar .btn-clear {
  background: transparent;
  border: none;
  color: var(--oct-text-muted, #6b7280);
  font-size: 12px;
  cursor: pointer;
  padding: 4px 8px;
  margin-right: 4px;
}
.bulk-action-bar .btn-clear:hover {
  color: var(--oct-text, #1f2937);
  text-decoration: underline;
}

/* Colonne checkbox compacte dans les listes admin équipées du bulk-select */
.table .bulk-col {
  width: 36px;
  text-align: center;
  padding-left: 8px;
  padding-right: 8px;
}
.table .bulk-col input[type="checkbox"] {
  cursor: pointer;
  vertical-align: middle;
}

/* Bulk-select pour les cartes Absence (template en cartes, pas en table) :
   la checkbox est placée à gauche de l'icône calendrier dans abs-card-head. */
.abs-card-bulk {
  display: flex;
  align-items: center;
  padding-right: 4px;
}
.abs-card-bulk input[type="checkbox"] {
  cursor: pointer;
  width: 16px;
  height: 16px;
}

/* ============================================================
   EVO-010 V1 — Barre d'actions CRA sticky (top-on-scroll)
   Reprend le design de mockups/cra-floating-bar.html (variante 1).
   3 zones : stats / save / actions.
   Position dans le flux naturel (au-dessus de la grille) avec
   `position: sticky; top: 62px` (= sous la topbar fixe) — quand
   l'utilisateur scrolle dans la grille, la barre se colle sous la
   topbar ; quand il remonte, elle reprend sa place. Comportement
   CSS pur, aucun JS pour la position.

   Approche préférée à un fixed-bottom : reste dans le champ de
   vision principal, pas de conflit profiler Symfony en dev, pas
   de chevauchement avec la sidebar fixe.
   ============================================================ */
.cra-float-bar {
  position: sticky;
  /* EVO-037 V2.5 — sticky bar empilée COLLÉE juste sous `.cra-header-row`.
     `--cra-header-h` est exposée par le ctrl `cra-header-sticky` au connect
     et au resize. Fallback 96px = hauteur typique du bloc engagement+frise.
     Pas de gap entre les 2 sticky : sinon on voit passer le contenu de la
     grille au scroll, ce qui est perturbant visuellement. */
  top: calc(62px + var(--cra-header-h, 96px));
  z-index: 9; /* sous la topbar (z-index: 10) et sous .cra-header-row (z:11) */
  margin: 0 0 16px;
  /* Suppression du margin-top : la cra-header-row a déjà géré son padding
     pour qu'on se colle parfaitement. */
  margin-top: 0;
  background: rgba(255, 255, 255, 0.96);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--oct-border);
  border-radius: 12px;
  box-shadow: 0 4px 16px rgba(15, 23, 42, 0.05);
  padding: 10px 16px;
  display: grid;
  grid-template-columns: minmax(280px, 1fr) minmax(0, 1fr) auto;
  gap: 16px;
  align-items: center;
  font-size: 13px;
}

/* ====== Zone 1 : stats ====== */
.cfb-stats {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}
.cfb-status {
  font-size: 12px;
  white-space: nowrap;
}
.cfb-stat-group {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
}
.cfb-stat-num {
  font-weight: 700;
  font-size: 15px;
  color: var(--oct-black);
  min-width: 18px;
  text-align: right;
}
.cfb-stat-num-worked { color: var(--oct-orange-dark); }
.cfb-stat-num-off { color: #6b7280; }
.cfb-stat-divider {
  width: 1px;
  height: 18px;
  background: var(--oct-border);
}
.cfb-stat-label {
  color: var(--oct-text-muted);
  font-size: 11px;
}
.cfb-icon-worked { color: var(--oct-orange-dark); }
.cfb-icon-off { color: #6b7280; }

/* ====== Zone 2 : indicateur de sauvegarde ====== */
.cfb-status-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  min-width: 0;
}
.cfb-save {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  white-space: nowrap;
}
.cfb-save-idle    { color: var(--oct-text-muted); }
.cfb-save-saving  { color: var(--oct-text-muted); }
.cfb-save-saved   { color: var(--oct-green, #28a745); }
.cfb-save-invalid { color: #dc3545; }
.cfb-save-error   { color: #dc3545; }
.cfb-save-locked  {
  color: var(--oct-text-muted);
  /* Verrouillage : libellé en gris discret, mais le cadenas orange
     pour signaler clairement le statut bloquant (cf. EVO-010 V1 — reprise
     du visuel du bandeau historique de la toolbar de grille). */
}
.cfb-save-locked strong { color: var(--oct-black); }
.cfb-icon-locked { color: var(--oct-orange); }

/* ====== Zone 3 : actions ====== */
.cfb-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}
.cfb-actions form {
  display: inline-flex;
  margin: 0;
}

/* ====== Responsive ====== */
@media (max-width: 900px) {
  .cra-float-bar {
    grid-template-columns: 1fr;
    gap: 10px;
    /* EVO-037 V2.6 — Sur mobile/tablette, on désactive l'empilement sticky
       dynamique : la zone engagement+frise prend trop de place quand elle
       est wrap (engagement + frise empilés sous 900px), et la sticky bar
       se retrouverait à mi-écran. La sticky bar revient à top:62 classique,
       sticky pure sous topbar — cf. override de .cra-header-row plus bas. */
    top: 62px;
  }
  .cfb-actions {
    justify-content: flex-end;
  }
  /* La cra-header-row redevient statique en mobile : pas d'empilement
     sticky avec la sticky bar EVO-010 (volume trop important quand wrap). */
  .cra-header-row {
    position: static;
    /* margin-bottom à remettre car on retire le sticky (qui collait au suivant) */
    margin-bottom: 12px;
  }
  /* EVO-037 V2.6 — Carte engagement en mobile : prend toute la largeur dispo
     et laisse son contenu wrap proprement. Sinon le `max-width: fit-content`
     du .cra-meta force la carte à sa taille naturelle (~600px), ce qui
     déborde un viewport mobile (~450px) et tronque le texte. */
  .cra-header-engagement {
    flex: 1 1 100%;
    min-width: 0;
  }
  .cra-header-engagement .cra-meta {
    max-width: 100%;
    width: 100%;
    flex-wrap: wrap;
  }
  .cra-meta-mission-title,
  .cra-meta-mission-client {
    /* Permet aux longs codes mission (« ASSISTANCE TECHNIQUE - MATMUT ROUEN »)
       de wrapper sur 2 lignes au lieu de déborder. */
    word-break: break-word;
  }
  .cra-header-nav {
    flex: 1 1 100%;
  }
}

/* ============================================================
   EVO-011 V1 — Vue calendrier d'absences (collab `/absences?view=calendar`)
   Réutilise les composants .tabs / .card / .btn-icon / .abs-dot /
   .abs-type / .kpi-grid du design-system ; ajoute la grille mensuelle
   et la navigation mois.
   Lecture seule en V1 — cf. EVO-025 pour la création par glisser-déplacer.
   ============================================================ */

/* Toolbar : navigation mois */
.cal-monthnav {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 8px;
  padding: 4px;
  margin: 0 0 16px;
}
.cal-monthnav .month-label {
  font-weight: 600;
  font-size: 14px;
  padding: 0 14px;
  min-width: 120px;
  text-align: center;
  color: var(--oct-black);
}
.cal-monthnav .btn-icon {
  background: transparent;
  border: 0;
  color: var(--oct-text-muted);
  padding: 6px 10px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
}
.cal-monthnav .btn-icon:hover {
  background: var(--oct-bg);
  color: var(--oct-orange);
}

/* Grille mensuelle : 7 colonnes Lun → Dim */
.cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
}
.cal-head {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--oct-text-muted);
  padding: 4px 6px 8px;
}
.cal-cell {
  position: relative;
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 8px;
  min-height: 104px;
  padding: 8px 9px;
  transition: transform 0.12s, box-shadow 0.12s;
  overflow: visible;
  display: block;
}
a.cal-cell { cursor: pointer; }
a.cal-cell:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.08);
  z-index: 2;
}
.cal-cell .day-num {
  font-weight: 700;
  font-size: 14px;
  color: var(--oct-black);
}
.cal-cell.is-weekend { background: #fafbfc; }
.cal-cell.is-other-month {
  opacity: 0.45;
  background: #fafbfc;
}
.cal-cell.is-other-month .day-num { color: var(--oct-text-muted); }
.cal-cell.is-today {
  border-color: var(--oct-orange);
  border-width: 2px;
  padding: 7px 8px;
}
.cal-cell.is-today .day-num { color: var(--oct-orange); }
/* EVO-025 V3 — État « en cours de sélection » pendant un drag-to-select
   (ou pendant que la modale rapide est ouverte avec une plage figée).
   Fond orange-soft + bordure orange épaisse pour rendre la sélection très
   visible sur la palette des autres slots. */
.cal-cell.is-selecting {
  background: var(--oct-orange-soft) !important;
  border-color: var(--oct-orange);
  border-width: 2px;
  padding: 7px 8px; /* compensation -1px de bordure pour garder l'alignement */
  box-shadow: 0 0 0 1px var(--oct-orange-light) inset;
}
/* EVO-025 — Curseur explicite « grab » sur les cellules éligibles côté
   collab (drag-to-select activé). Les cellules `data-blocked` gardent
   leur curseur par défaut (ou not-allowed visuellement par leur couleur). */
[data-controller~="absence-calendar-select"] .cal-cell:not([data-blocked="true"]) {
  cursor: cell;
  user-select: none;
}
[data-controller~="absence-calendar-select"] .cal-cell:not([data-blocked="true"]):active {
  cursor: grabbing;
}
.cal-cell.is-ferie {
  background-color: #fffdf0;
  background-image: repeating-linear-gradient(45deg, #fffbe5, #fffbe5 6px, #fffdf0 6px, #fffdf0 12px);
  border-color: #f0e0a8;
}
.cal-ferie-tag {
  display: inline-block;
  font-size: 9.5px;
  font-weight: 600;
  color: #8a6a00;
  background: #fff8d0;
  padding: 1px 5px;
  border-radius: 4px;
  margin-top: 6px;
  letter-spacing: 0.02em;
}

/* Pastille d'absence dans une cellule — couleur via CSS var --c
   alimentée inline par CraDefaultLabel.color (cf. EVO-009). */
.cal-abs {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  padding: 4px 7px;
  border-radius: 5px;
  font-size: 11px;
  font-weight: 600;
  color: var(--oct-black);
  background: color-mix(in srgb, var(--c, var(--oct-orange)) 14%, white);
  border-left: 3px solid var(--c, var(--oct-orange));
}
.cal-abs .abs-dot { background: var(--c, var(--oct-orange)); }

/* Tooltip CSS-only au survol d'une cellule (data-tip). */
.cal-cell[data-tip]:hover::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--oct-sidebar);
  color: #fff;
  padding: 7px 10px;
  border-radius: 7px;
  font-size: 11.5px;
  white-space: nowrap;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
  z-index: 10;
  font-weight: 500;
  pointer-events: none;
}
.cal-cell[data-tip]:hover::before {
  content: "";
  position: absolute;
  bottom: calc(100% + 2px);
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: var(--oct-sidebar);
  z-index: 10;
  pointer-events: none;
}

/* Légende du calendrier */
.cal-legend {
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
  font-size: 12px;
  color: #4b5260;
  padding: 12px 16px;
  align-items: center;
}
.cal-legend .abs-type { font-weight: 500; color: #4b5260; }
.cal-legend-sep {
  color: var(--oct-border);
  font-size: 14px;
}
.lgd-ferie {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  background-color: #fffdf0;
  background-image: repeating-linear-gradient(45deg, #fffbe5, #fffbe5 3px, #fffdf0 3px, #fffdf0 6px);
  border: 1px solid #f0e0a8;
  display: inline-block;
}
.lgd-weekend {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  background: #fafbfc;
  border: 1px solid var(--oct-border);
  display: inline-block;
}

/* Responsive : grille adaptative jusqu'à ~600px puis liste verticale. */
@media (max-width: 768px) {
  .cal-cell { min-height: 84px; padding: 6px 7px; }
  .cal-cell .day-num { font-size: 13px; }
  .cal-abs { font-size: 10px; padding: 3px 5px; }
  .cal-ferie-tag { font-size: 9px; }
  .cal-monthnav .month-label { min-width: 90px; padding: 0 8px; font-size: 13px; }
}

/* ============================================================
   EVO-011 Phase B — Vue ruban admin (`/admin/absences?view=ribbon`)
   Reprise fidèle de mockups/admin-absences-calendar.html.
   Grille `200px (nom collab) + N×28px (jours)` ; scroll horizontal si
   nécessaire ; cellules d'absence colorisées par `CraDefaultLabel.color`.
   ============================================================ */

/* Toolbar : ligne portant la nav mois */
.cal-toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0;
  margin-bottom: 10px;
}

/* Carte ruban : scrollable horizontalement */
.rb-card {
  padding: 18px;
  overflow-x: auto;
}
.rb-grid {
  display: grid;
  min-width: min-content;
  border: 1px solid var(--oct-border);
  border-radius: 8px;
  overflow: hidden;
  /* grid-template-columns posé inline par le template (dépend de daysInMonth) */
}
.rb-grid > div,
.rb-grid > a {
  border-right: 1px solid var(--oct-border);
  border-bottom: 1px solid var(--oct-border);
}

/* Header row */
.rb-h {
  background: var(--oct-bg);
  padding: 6px 4px 7px;
  text-align: center;
  font-size: 11px;
  color: var(--oct-text-muted);
  font-weight: 600;
  line-height: 1.1;
}
.rb-h.wk { background: #eef0f4; }
.rb-h.fr {
  background: #fff8d0;
  color: #8a6a00;
}
.rb-h.today {
  /* Aujourd'hui — souligne discrètement dans le header */
  box-shadow: inset 0 -3px 0 var(--oct-orange);
}
.rb-h .num {
  font-size: 13px;
  color: var(--oct-black);
  font-weight: 700;
  display: block;
}
.rb-h.fr .num { color: #8a6a00; }
.rb-h .dow {
  font-size: 9px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  opacity: 0.85;
  margin-top: 1px;
}
.rb-h-name {
  background: var(--oct-bg);
  padding: 6px 12px;
  font-size: 11px;
  color: var(--oct-text-muted);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  display: flex;
  align-items: center;
  border-right: 2px solid var(--oct-border) !important;
}

/* Colonne nom collaborateur */
.rb-name {
  padding: 8px 12px;
  display: flex;
  align-items: center;
  gap: 9px;
  background: #fcfcfd;
  border-right: 2px solid var(--oct-border) !important;
  min-height: 44px;
}
.rb-name .avatar {
  width: 26px;
  height: 26px;
  font-size: 10.5px;
  flex-shrink: 0;
}
.rb-name .meta {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
  min-width: 0;
}
.rb-name .meta .full-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--oct-black);
}
.rb-name .meta .role {
  font-size: 10px;
  color: var(--oct-text-muted);
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Cellules jour : background = couleur d'absence si présente */
.rb-c {
  position: relative;
  min-height: 44px;
  display: block;
}
.rb-c.wk { background: #fafbfc; }
.rb-c.fr {
  background-color: #fffdf0;
  background-image: repeating-linear-gradient(45deg, #fffbe5, #fffbe5 4px, #fffdf0 4px, #fffdf0 8px);
}
.rb-c.has-abs { background: var(--c, var(--oct-orange)); }
a.rb-c {
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}
a.rb-c:hover { filter: brightness(0.94); }
.rb-c.today {
  box-shadow: inset 0 -3px 0 var(--oct-orange);
}

/* Totaux consolidés sous le ruban */
.rb-totals {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 16px;
  font-size: 12px;
  color: var(--oct-text-muted);
}
.rb-totals strong { color: var(--oct-black); }

/* ============================================================
   EVO-034 — Toast (notifications transitoires JS)
   Stack bottom-right, max 5 simultanés (FIFO), animation slide+fade.
   Container `<div id="toast-stack">` créé en lazy par assets/utils/toast.js
   au premier appel `showToast(...)`.
   ============================================================ */
.toast-stack {
  position: fixed;
  bottom: 20px;
  right: 20px;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  gap: 10px;
  pointer-events: none;
  max-width: min(380px, calc(100vw - 40px));
}
.toast {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  background: #fff;
  border: 1px solid var(--oct-border);
  border-left: 4px solid var(--oct-orange);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
  font-size: 13px;
  line-height: 1.4;
  color: var(--oct-black);
  animation: oct-toast-in 0.22s ease-out;
}
.toast.toast-leaving {
  animation: oct-toast-out 0.2s ease-in forwards;
}
@keyframes oct-toast-in {
  from { transform: translateX(110%); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}
@keyframes oct-toast-out {
  from { transform: translateX(0);    opacity: 1; }
  to   { transform: translateX(110%); opacity: 0; }
}
.toast-icon {
  flex-shrink: 0;
  font-size: 18px;
  line-height: 1.4;
  margin-top: 1px;
}
.toast-message {
  flex: 1;
  word-break: break-word;
}
.toast-close {
  flex-shrink: 0;
  background: transparent;
  border: 0;
  color: var(--oct-text-muted);
  cursor: pointer;
  padding: 2px 4px;
  font-size: 13px;
  line-height: 1;
  border-radius: 4px;
}
.toast-close:hover {
  color: var(--oct-black);
  background: var(--oct-bg);
}

/* Variants — couleur de bordure gauche + couleur de l'icône.
   Le fond reste blanc pour la lisibilité et la cohérence avec les
   modales de confirm (confirm.js). */
.toast-success {
  border-left-color: var(--oct-green, #28a745);
}
.toast-success .toast-icon { color: var(--oct-green, #28a745); }
.toast-info {
  border-left-color: #3b82f6;
}
.toast-info .toast-icon { color: #3b82f6; }
.toast-warning {
  border-left-color: var(--oct-orange);
}
.toast-warning .toast-icon { color: var(--oct-orange-dark); }
.toast-danger {
  border-left-color: #dc3545;
}
.toast-danger .toast-icon { color: #dc3545; }

/* Responsive — sur très petit écran, le stack prend toute la largeur
   en bas (cohérent avec les patterns Snackbar mobile). */
@media (max-width: 540px) {
  .toast-stack {
    bottom: 12px;
    right: 12px;
    left: 12px;
    max-width: none;
  }
}

/* ============================================================
   EVO-037 V2 — Zone du haut /cra/{id}/edit en 2 colonnes
   - .cra-header-engagement : carte engagement (gauche, taille naturelle —
     fit-content du contenu pour éviter le wrapping du texte « mission +
     référence + TJM » qui ne tient pas sous 480px)
   - .cra-header-nav : mini-frise (droite, prend le reste flex:1)
   Empilement vertical automatique via flex-wrap si la frise ne peut pas
   afficher au moins ~320px de slots (cohérent avec son min de 5 slots).
   ============================================================ */
.cra-header-row {
  display: flex;
  align-items: stretch;
  gap: 16px;
  flex-wrap: wrap;
  /* EVO-037 V2.5 — sticky sous la topbar (62px) pour rester visible quand
     l'utilisateur scrolle dans la grille. Le ctrl Stimulus `cra-header-sticky`
     mesure la hauteur réelle de ce bloc (qui varie selon engagement court/long
     + wrap responsive) et expose `--cra-header-h` ; la sticky bar EVO-010
     consomme cette var pour s'empiler EXACTEMENT en dessous (collée, sans gap)
     pour ne laisser passer aucun pixel de contenu de la grille entre les 2
     zones — sinon perturbation visuelle au scroll. */
  position: sticky;
  top: 62px;
  z-index: 11; /* au-dessus de .cra-float-bar (z:9) et du contenu */
  background: var(--oct-bg, #f5f6f8);
  /* Pas de margin-bottom : la sticky bar EVO-010 vient se coller directement
     en dessous. Padding 8px haut/bas pour respiration interne (cet espace
     est inclus dans offsetHeight, donc le calc(62 + var) tombe pile au bord
     du fond sticky — pas de pixel de contenu qui passe). */
  padding: 8px 0;
}
.cra-header-engagement {
  /* Taille naturelle (fit-content) du contenu — pas de basis fixe pour
     ne pas tasser la mission/référence sur plusieurs lignes inutilement. */
  flex: 0 0 auto;
}
.cra-header-engagement .cra-meta {
  /* Neutralise margin-top historique — le gap du .cra-header-row gère. */
  margin: 0;
  height: 100%;
}
.cra-header-nav {
  /* `min-width: 320px` (~ 5 slots à 78px + flèches + padding) : si la
     place restante est < 320, le bloc wrap en dessous de l'engagement
     pour préserver la lisibilité plutôt que de tasser la frise. */
  flex: 1 1 320px;
  min-width: 0;
  display: flex;
}
.cra-header-nav > .cra-nav {
  flex: 1;
  margin: 0;  /* neutralise margin-bottom historique */
}

/* ============================================================
   EVO-037 — Mini-frise inter-CRA (`/cra/{id}/edit`)
   Frise compacte + flèches latérales pour naviguer entre les CRA
   d'un même engagement. Réutilise la palette d'état de la frise
   principale (.frise-*) en variante condensée.
   V1 : windowSize fixe à 5. V2 : windowSize dynamique selon largeur
   disponible (ResizeObserver côté Stimulus, bornes 5-15).
   ============================================================ */
.cra-nav {
  margin: 0 0 16px;
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 10px;
  padding: 10px 14px;
  position: relative;
}
.cra-nav-loading {
  opacity: 0.6;
  pointer-events: none;
  transition: opacity 0.15s;
}
.cra-nav-title {
  font-size: 11px;
  color: var(--oct-text-muted);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-bottom: 8px;
  display: flex;
  align-items: center;
  gap: 6px;
}
.cra-nav-title i {
  color: var(--oct-orange);
}
.cra-nav-rail {
  display: flex;
  align-items: center;
  gap: 8px;
}
.cra-nav-slots {
  display: flex;
  align-items: stretch;
  gap: 6px;
  flex-wrap: nowrap;
  /* Alignement à gauche (Q3 fiche F20) — pas d'étirement si peu de slots. */
  flex: 1;
  min-width: 0;
}
.cra-nav-arrow {
  flex-shrink: 0;
  background: #fff;
  border: 1px solid var(--oct-border);
  border-radius: 6px;
  padding: 6px 10px;
  cursor: pointer;
  color: var(--oct-text-muted);
  font-size: 14px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  transition: filter 0.15s, color 0.15s;
}
.cra-nav-arrow:hover:not(.is-disabled) {
  color: var(--oct-orange);
  filter: brightness(0.98);
}
.cra-nav-arrow.is-disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

/* Slot (case) — bouton/lien/span selon le contexte (cf. partial Twig).
   Reset des styles natifs button/form. */
.cra-nav-slot,
.cra-nav-slot-form button.cra-nav-slot {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: 72px;
  padding: 8px 10px;
  border-radius: 7px;
  border: 1px solid var(--oct-border);
  background: #fff;
  color: inherit;
  text-decoration: none;
  font-family: inherit;
  cursor: pointer;
  transition: transform 0.12s, box-shadow 0.12s, border-color 0.12s;
}
.cra-nav-slot:hover:not(.is-current):not(.state-out) {
  transform: translateY(-1px);
  box-shadow: 0 3px 10px rgba(15, 23, 42, 0.08);
}
/* Override de la règle globale `a:hover { text-decoration: underline }`
   pour les slots qui sont des <a>. L'effet de survol est sur la carte
   (translate + ombre), pas sur le libellé. */
a.cra-nav-slot,
a.cra-nav-slot:hover,
a.cra-nav-slot:focus,
a.cra-nav-slot:active {
  text-decoration: none;
}
.cra-nav-slot-label {
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
.cra-nav-slot-year {
  font-size: 10px;
  color: var(--oct-text-muted);
  margin-top: 2px;
}
.cra-nav-slot-form {
  display: inline-flex;
  margin: 0;
  padding: 0;
}

/* États (reprend la palette de la frise principale, en variante compacte) */
.cra-nav-slot.state-validated {
  background: #e6f7ec;
  border-color: #b8e0c4;
  color: #1d7f3d;
}
.cra-nav-slot.state-validated .cra-nav-slot-year { color: #1d7f3d; opacity: 0.7; }
.cra-nav-slot.state-submitted {
  background: var(--oct-orange-soft);
  border-color: var(--oct-orange-light);
  color: var(--oct-orange-dark);
}
.cra-nav-slot.state-submitted .cra-nav-slot-year { color: var(--oct-orange-dark); opacity: 0.7; }
.cra-nav-slot.state-draft {
  background: #fff;
  border-color: var(--oct-orange-light);
  color: var(--oct-black);
}
.cra-nav-slot.state-empty {
  background: var(--oct-bg);
  border-color: var(--oct-border);
  border-style: dashed;
  color: var(--oct-text-muted);
}
.cra-nav-slot.state-out {
  background: var(--oct-bg);
  border-color: var(--oct-border);
  color: var(--oct-text-muted);
  opacity: 0.5;
  cursor: not-allowed;
}

/* EVO-037 V2.5 — Mois courant : 3 signaux visuels distincts pour signaler
   clairement « tu consultes ce CRA » SANS écraser la couleur de statut
   (le fond du slot reste celui de l'état validated/submitted/draft/empty).
   1. Bordure orange épaisse 2px (déjà historique).
   2. Lift visuel : translate Y -3px + ombre marquée pour effet « relief ».
   3. Tab pointer ▼ : triangle orange sous le slot, métaphore onglet actif. */
.cra-nav-slot.is-current {
  border-color: var(--oct-orange);
  border-width: 2px;
  /* PAS de background:#fff — préserve le fond de statut (vert/orange/etc.) */
  padding: 7px 9px; /* compensation -1px de bordure pour garder l'alignement */
  transform: translateY(-3px);
  box-shadow: 0 6px 16px rgba(217, 122, 5, 0.30), 0 2px 4px rgba(0, 0, 0, 0.10);
  cursor: default;
  z-index: 1; /* passe au-dessus des slots adjacents pour l'ombre */
}
/* Tab pointer : petit triangle orange juste sous le slot, qui pointe vers
   la grille en dessous (style onglet actif). */
.cra-nav-slot.is-current::before {
  content: '';
  position: absolute;
  top: calc(100% + 2px);
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 7px solid transparent;
  border-right: 7px solid transparent;
  border-top: 7px solid var(--oct-orange);
}
/* PAS d'override de la couleur du label : laisser le texte suivre la couleur
   du fond de statut pour préserver la lisibilité du statut visuellement. */

/* Indicateur « à reprendre » : pastille rouge en haut-droite du slot. */
.cra-nav-slot.to-reprocess::after {
  content: '';
  position: absolute;
  top: 4px;
  right: 4px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #dc3545;
  box-shadow: 0 0 0 2px #fff;
}

/* Icône + pour les mois « à créer » : discrète en bas-droite du slot. */
.cra-nav-slot-add {
  position: absolute;
  bottom: 3px;
  right: 4px;
  font-size: 10px;
  color: var(--oct-orange);
  opacity: 0.6;
}
.cra-nav-slot:hover .cra-nav-slot-add { opacity: 1; }

/* Responsive — sur petits écrans, la mini-frise reste lisible
   (les 5 slots de 72px tiennent dans ~360px + flèches + gap). En cas
   de débordement, scroll horizontal de secours sur .cra-nav-slots. */
@media (max-width: 640px) {
  .cra-nav-slots {
    overflow-x: auto;
    scrollbar-width: thin;
  }
  .cra-nav-slot { min-width: 64px; padding: 7px 8px; }
}

/* ============================================================
   EVO-059 — Bloc 4 Écrans restants : classes canoniques de formulaire
   ------------------------------------------------------------
   Hand-off §10.1-10.3 : hiérarchie .field/.field-label/.field-hint,
   .control (40 px de hauteur, bordure neutre, focus ring token),
   callouts d'aide .callout--info / .callout--warning, onglets .tabs.
   Les classes legacy (.form-group/.form-label/.form-control) ne sont
   pas redéfinies ici — chaque écran utilise l'une OU l'autre famille.
   Le Bloc 4 migre uniquement cra/new + absence/list + absence/form.
   ============================================================ */

/* ----- Hiérarchie de formulaire ----- */
.field {
  display: block;
  margin-bottom: 14px;
}
.field:last-child { margin-bottom: 0; }

.field-label {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-700, #3d3d3d);
  margin-bottom: 6px;
  letter-spacing: 0.005em;
}
.field-label .req { color: var(--orange-500); margin-left: 2px; }

.field-hint {
  margin-top: 5px;
  font-size: 12px;
  color: var(--ink-500, var(--oct-text-muted));
  line-height: 1.45;
}

.control {
  display: block;
  width: 100%;
  height: 40px;
  padding: 0 12px;
  border: 1px solid var(--border-default);
  border-radius: 8px;
  background: #fff;
  color: var(--ink-900, #1a1a1a);
  font: inherit;
  font-size: 14px;
  line-height: 1.4;
  transition: border-color var(--motion-fast, 120ms) var(--ease-standard, ease),
              box-shadow var(--motion-fast, 120ms) var(--ease-standard, ease);
}
.control:focus,
.control:focus-visible {
  outline: none;
  border-color: var(--orange-500);
  box-shadow: 0 0 0 3px var(--orange-100, rgba(255,153,0,0.18));
}
.control:disabled,
.control[readonly] {
  background: var(--ink-25);
  color: var(--ink-500, var(--oct-text-muted));
  cursor: not-allowed;
}
textarea.control {
  height: auto;
  min-height: 80px;
  padding: 10px 12px;
  resize: vertical;
}
select.control { appearance: auto; padding-right: 8px; }

.field-row {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
}
.field-row > .field { flex: 1 1 200px; min-width: 0; }
.field-row > .field--narrow { flex: 0 0 200px; }

/* ----- Callouts d'aide (hand-off §10.2) ----- */
.callout {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 12px 16px;
  border-radius: 10px;
  font-size: 13.5px;
  line-height: 1.5;
  margin-bottom: 16px;
}
.callout__icon {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  line-height: 1;
}
.callout__body { flex: 1 1 auto; min-width: 0; }
.callout__title {
  font-weight: 700;
  font-size: 14px;
  margin-bottom: 3px;
  color: inherit;
}
.callout__body p,
.callout__body ul { margin: 0; }
.callout__body ul { padding-left: 18px; margin-top: 4px; }
.callout__actions {
  flex: 0 0 auto;
  display: flex;
  gap: 8px;
  align-items: center;
}

.callout--info {
  background: var(--info-soft);
  color: var(--info-base);
  border: 1px solid color-mix(in srgb, var(--info-base) 25%, transparent);
}
.callout--info .callout__icon { color: var(--info-base); }
.callout--info a:not(.btn) { color: var(--info-base); text-decoration: underline; }

.callout--warning {
  background: var(--warning-soft);
  color: var(--ink-900, #1a1a1a);
  border: 1px solid color-mix(in srgb, var(--orange-500) 30%, transparent);
  border-left: 4px solid var(--orange-500);
}
.callout--warning .callout__icon { color: var(--orange-700); }
.callout--warning .callout__title { color: var(--orange-700); }
.callout--warning a:not(.btn) { color: var(--orange-700); text-decoration: underline; }

/* ----- Onglets (hand-off §10.3) — utilise .tabs/.tab existants, on harmonise
   uniquement l'underline orange sur l'onglet actif. ----- */
.tabs--canonical {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border-default);
  margin-bottom: 16px;
}
.tabs--canonical .tab {
  position: relative;
  padding: 10px 16px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink-500, var(--oct-text-muted));
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border-radius: 8px 8px 0 0;
  transition: color var(--motion-fast, 120ms) var(--ease-standard, ease),
              background var(--motion-fast, 120ms) var(--ease-standard, ease);
}
.tabs--canonical .tab:hover { color: var(--ink-900, #1a1a1a); background: var(--ink-25); text-decoration: none; }
.tabs--canonical .tab.tab-active {
  color: var(--orange-700);
  font-weight: 700;
}
.tabs--canonical .tab.tab-active::after {
  content: '';
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: -1px;
  height: 3px;
  background: var(--orange-500);
  border-radius: 2px 2px 0 0;
}

/* ----- Bouton « + Ajouter une absence » (hand-off §10.4) ----- */
.btn--add {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  background: transparent;
  color: var(--orange-700);
  border: 1px dashed var(--orange-500);
  border-radius: 8px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background var(--motion-fast, 120ms) var(--ease-standard, ease);
}
.btn--add:hover { background: var(--warning-soft); text-decoration: none; color: var(--orange-700); }

/* ----- Lignes répétables d'absence (hand-off §10.4)
   Grid figée : type | début | fin | fraction | note | supprimer ----- */
.abs-row {
  display: grid;
  grid-template-columns: 1.1fr 1fr 1fr 1.1fr 1.3fr 32px;
  gap: 10px;
  align-items: start;
  padding: 10px 0;
  border-top: 1px solid var(--border-default);
}
.abs-row:first-child { border-top: 0; }
.abs-row__remove {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: 6px;
  color: var(--ink-500, var(--oct-text-muted));
  cursor: pointer;
}
.abs-row__remove:hover { background: var(--ink-25); color: #dc3545; }

.abs-total {
  display: flex;
  align-items: baseline;
  gap: 8px;
  justify-content: flex-end;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border-default);
  font-size: 13px;
  color: var(--ink-500, var(--oct-text-muted));
}
.abs-total .v {
  font-size: 18px;
  font-weight: 700;
  color: var(--ink-900, #1a1a1a);
  font-variant-numeric: tabular-nums;
}

/* ----- Responsive : abs-row passe en flux vertical sous 640 px ----- */
@media (max-width: 640px) {
  .abs-row {
    grid-template-columns: 1fr 32px;
    grid-template-areas:
      "type    remove"
      "start   start"
      "end     end"
      "frac    frac"
      "note    note";
  }
  .field-row { gap: 10px; }
}

/* ============================================================
   EVO-063 SL 1.4 — Mes CRA (liste) responsive mobile
   ------------------------------------------------------------
   Stratégie « fidélité mockup » (CLAUDE.md) : chaque écran reçoit 2
   blocs parallèles dans son template Twig (.d-desktop-only inchangé +
   .d-mobile-only re-écrit avec classes .m-* du DS mobile). Les utility
   classes ci-dessous gèrent le switch global, puis les classes
   spécifiques à cet écran (.m-cra-list-*, .m-cra-item-*) suivent.
   ============================================================ */

/* === Utility globales — switch desktop/mobile ===
   Chargées sur tous devices (pas dans mobile-components.css). `!important`
   sur les `display: none` pour résister à d'éventuels overrides spécifiques
   (ex. `.m-cra-list-bottom { display: flex }` qui sinon resterait visible
   en desktop via l'ordre cascade). */
.d-mobile-only  { display: none; }
.d-desktop-only { display: block; }
@media (max-width: 767px) {
    .d-mobile-only  { display: block; }
    .d-desktop-only { display: none !important; }
}
@media (min-width: 768px) {
    .d-mobile-only { display: none !important; }
}

/* === Classes spécifiques /cra mobile ===
   Pas de wrap @media : la visibilité est gérée par le parent .d-mobile-only.
   Le CSS reste téléchargé en desktop mais sans effet visuel.
   Eyebrow + dot orange : à promouvoir dans mobile-components.css si réutilisé
   sur 2+ écrans en SL ultérieures (dashboard mobile l'a aussi inline pour
   l'instant). */
.m-cra-list-page { padding-bottom: calc(var(--m-h-bottombar, 64px) + var(--s-3)); }

.m-hero-eyebrow {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: var(--m-fs-xs, 10.5px);
    font-weight: var(--m-fw-semibold, 600);
    color: var(--m-text-muted, var(--ink-400));
    text-transform: uppercase;
    letter-spacing: 0.4px;
    margin-bottom: 4px;
}
.m-hero-eyebrow-dot {
    display: inline-block;
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--m-brand, var(--orange-500));
}

.m-cra-list-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-2);
    /* margin-bottom aligné sur celui de .m-filter-segments (12px) pour avoir
       un espacement uniforme : eyebrow → head → filtres → cards. */
    margin: 4px 0 var(--m-sp-3, 12px);
}
.m-cra-list-head .m-page-title { margin: 0; flex: 1; min-width: 0; }
.m-cra-list-yearform { margin: 0; flex-shrink: 0; }

/* Mobile : sélecteur année compact (label « ANNÉE » masqué partout sur mobile
   pour libérer la largeur du H1 dynamique). Dashboard + Mes CRA + Mes absences :
   tous montrent juste « 2026 ▼ » en mobile. Cohérence cross-écrans demandée
   par Julien (EVO-063 SL 1.6). */
@media (max-width: 767px) {
    .year-select__lbl { display: none; }
    .year-select { padding: 0 var(--s-2); }
}

.m-cra-list-counters {
    font-size: var(--m-fs-sm, 12px);
    color: var(--m-text-muted, var(--ink-400));
    margin-bottom: var(--s-3);
}
/* Sous-titre cosmétique sous le H1 (EVO-063 SL 1.6) — affiché quand une
   année est sélectionnée (« Mes comptes rendus d'activité · 2026 »).
   Vide quand « Toutes ». Convention partagée Mes CRA + Mes absences. */
.m-cra-list-subtitle,
.m-abs-subtitle {
    font-size: var(--m-fs-sm, 12px);
    color: var(--m-text-muted, var(--ink-400));
    margin: 0 0 var(--m-sp-3, 12px);
}

/* Card item /cra — grid icône + body + KPI (spécifique cet écran) */
.m-cra-item {
    display: grid;
    grid-template-columns: 36px 1fr auto;
    gap: var(--m-sp-3, 12px);
    align-items: center;
    background: var(--m-surface, #fff);
    border: 1px solid var(--m-border, var(--ink-100));
    border-radius: var(--m-r-lg, 10px);
    padding: var(--m-sp-3, 12px);
    text-decoration: none;
    color: var(--m-text, var(--ink-900));
    margin-bottom: var(--m-sp-2, 8px);
}
.m-cra-item:active { background: var(--m-bg, var(--ink-25)); }
.m-cra-item-icon {
    width: 36px; height: 36px;
    border-radius: var(--m-r-md, 8px);
    display: flex; align-items: center; justify-content: center;
    font-size: var(--m-fs-lg, 16px);
    flex-shrink: 0;
}
.m-cra-item-icon--draft     { background: #f1f3f6;                                       color: #555f72; }
.m-cra-item-icon--submitted { background: var(--m-warning-soft, var(--orange-100));      color: var(--m-warning-strong, var(--orange-700)); }
.m-cra-item-icon--validated { background: var(--m-success-soft, var(--success-soft));    color: var(--m-success-strong, var(--success-dark)); }
.m-cra-item-icon--client    { background: var(--m-info-soft, var(--info-soft));          color: var(--m-info, var(--info-base)); }
.m-cra-item-body { min-width: 0; }
.m-cra-item-period {
    font-weight: var(--m-fw-bold, 700);
    font-size: var(--m-fs-md, 14px);
    line-height: 1.2;
    margin-bottom: 2px;
    text-transform: capitalize;
}
.m-cra-item-mission {
    font-size: var(--m-fs-sm, 12px);
    color: var(--m-text-muted, var(--ink-400));
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    line-height: 1.3;
}
.m-cra-item-meta {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    margin-top: 4px;
}
.m-cra-item-submitted {
    font-size: 10.5px;
    color: var(--m-text-muted, var(--ink-400));
}
.m-cra-item-kpi {
    text-align: right;
    flex-shrink: 0;
    min-width: 50px;
}
.m-cra-item-kpi .val {
    font-size: var(--m-fs-md, 14px);
    font-weight: var(--m-fw-bold, 700);
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.m-cra-list-empty {
    text-align: center;
    padding: var(--m-sp-6, 24px) var(--m-sp-4, 16px);
    color: var(--m-text-muted, var(--ink-400));
    font-size: var(--m-fs-sm, 12px);
}

/* BUG-035 — bandeau d'actions en pied de card CRA mobile.
   Le <a>.m-cra-item reste la zone primaire tappable (édition) ; les
   actions secondaires (Modifier/Voir, PDF, Supprimer) sont accolées
   visuellement à la card via une seconde "case" qui partage border /
   background / radius. La card haute perd son radius/border bottom
   pour fusionner avec le bandeau. */
.m-cra-item--with-actions {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    border-bottom: 0;
    margin-bottom: 0;
}
.m-cra-item-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--m-sp-2, 8px);
    padding: var(--m-sp-2, 8px) var(--m-sp-3, 12px);
    background: var(--m-surface, #fff);
    border: 1px solid var(--m-border, var(--ink-100));
    border-top: 1px solid var(--m-border-soft, #eef0f3);
    border-bottom-left-radius: var(--m-r-lg, 10px);
    border-bottom-right-radius: var(--m-r-lg, 10px);
    margin-bottom: var(--m-sp-2, 8px);
}

/* Sticky bottom mobile — fixed plutôt que sticky pour éviter dépendance
   à un overflow:auto parent (le scroll est sur body). Le flex du DS
   (.m-bottom-bar) est explicité ici pour résister à d'éventuels overrides
   spécifiques. Le KPI prend l'espace (flex:1, min-width:0 pour permettre
   l'ellipsis sur un libellé long), le bouton reste fixe (flex-shrink:0). */
.m-cra-list-bottom {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--m-z-bottombar, 90);
    display: flex;
    align-items: center;
    flex-wrap: nowrap;
}
.m-cra-list-bottom .m-bottom-bar-kpi {
    flex: 1 1 auto;
    min-width: 0;
}
.m-cra-list-bottom .m-bottom-bar-kpi .value {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.m-cra-list-bottom .m-btn { flex-shrink: 0; }

/* ============================================================
   EVO-063 SL 1.5 — Mes engagements responsive mobile
   ------------------------------------------------------------
   Classes spécifiques à /engagements mobile, consommant les
   atomes du DS mobile (.m-card, .m-chip, .m-progress, .m-banner).
   Synthèse tabulaire + accordéons pour multi-quota / multi-portage,
   reprenant le pattern EVO-054 desktop adapté au format compact
   mobile. Frise CRA en strip horizontal (exception « picker
   tabulaire intrinsèque » de la règle UX no-scroll-x).
   ============================================================ */

.m-eng-page { padding-bottom: var(--s-4); }
/* Espacement eyebrow → H1 plus aéré sur /engagements : pas de sélecteur année
   donc pas de wrapper flex pour centrer verticalement le H1 dans 38 px (comme
   sur Mes CRA / Mes absences). On ajoute un margin-top sur le H1 pour matcher
   le rendu visuel des autres écrans. */
.m-eng-page > .m-page-title {
    margin-top: var(--m-sp-3, 12px);
}

.m-eng-counters {
    font-size: var(--m-fs-sm, 12px);
    color: var(--m-text-muted, var(--ink-400));
    margin-bottom: var(--m-sp-3, 12px);
}

.m-eng-empty {
    text-align: center;
    padding: var(--m-sp-6, 24px);
    color: var(--m-text-muted, var(--ink-400));
    font-size: var(--m-fs-sm, 12px);
}

/* === Header de carte engagement (icône + code/title/client + chip) === */
.m-eng-card { padding: var(--m-sp-3, 12px); }
.m-eng-card-head {
    display: flex;
    align-items: flex-start;
    gap: var(--m-sp-2, 8px);
    margin-bottom: var(--m-sp-3, 12px);
}
.m-eng-card-icon {
    background: var(--m-brand-soft, var(--orange-100));
    color: var(--m-brand-strong, var(--orange-700));
    width: 36px; height: 36px;
    flex-shrink: 0;
}
.m-eng-card-id { flex: 1; min-width: 0; }
.m-eng-card-code {
    font-weight: var(--m-fw-bold, 700);
    font-size: var(--m-fs-md, 14px);
    line-height: 1.2;
}
.m-eng-card-title {
    font-size: var(--m-fs-sm, 12px);
    color: var(--m-text-muted, var(--ink-400));
    line-height: 1.3;
    margin-top: 2px;
}
.m-eng-card-client {
    font-size: var(--m-fs-sm, 12px);
    color: var(--m-text-muted, var(--ink-400));
    line-height: 1.3;
}
.m-eng-card-status {
    flex-shrink: 0;
    font-size: 10.5px;
}
.m-eng-card-status .bi { font-size: 6px; }

/* Chips métadonnées sous le header — wrap autorisé (≠ scroll) */
.m-eng-card-meta {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    margin-bottom: var(--m-sp-3, 12px);
}

/* Alertes (filtrées, multi-quota gère override dans l'accordéon) */
.m-eng-card-alerts {
    display: flex;
    flex-direction: column;
    gap: var(--m-sp-1, 4px);
    margin-bottom: var(--m-sp-3, 12px);
}

/* === Multi-block (container de section quota/portage/frise) === */
.m-multi-block {
    background: var(--m-bg, var(--ink-25));
    border: 1px solid var(--m-border, var(--ink-100));
    border-radius: var(--m-r-lg, 10px);
    padding: var(--m-sp-3, 12px);
    margin-bottom: var(--m-sp-2, 8px);
}
.m-multi-block:last-child { margin-bottom: 0; }
.m-multi-block-title {
    font-size: var(--m-fs-base, 13.5px);
    font-weight: var(--m-fw-semibold, 600);
    color: var(--m-text, var(--ink-900));
    margin-bottom: var(--m-sp-2, 8px);
    display: flex;
    align-items: center;
    gap: 6px;
}
.m-multi-block-title .bi { color: var(--m-text-muted, var(--ink-400)); }
.m-multi-block-title .count {
    color: var(--m-text-muted, var(--ink-400));
    font-weight: var(--m-fw-regular, 400);
}

/* === Synthèse tabulaire (multi-quota, multi-portage) === */
.m-eng-synth {
    background: var(--m-surface, #fff);
    border: 1px solid var(--m-border, var(--ink-100));
    border-radius: var(--m-r-md, 8px);
    margin-bottom: var(--m-sp-2, 8px);
    overflow: hidden;
}
.m-eng-synth-row {
    display: grid;
    grid-template-columns: 16px 1fr auto;
    align-items: center;
    gap: var(--m-sp-2, 8px);
    padding: 8px 10px;
    font-size: var(--m-fs-sm, 12px);
    border-bottom: 1px solid var(--m-border, var(--ink-100));
}
.m-eng-synth-row:last-child { border-bottom: 0; }
.m-eng-synth-row.is-current {
    background: rgba(30, 90, 156, 0.07);
    font-weight: var(--m-fw-semibold, 600);
}
.m-eng-synth-row .caret {
    color: var(--m-brand, var(--orange-500));
    font-size: 13px;
    visibility: hidden;
}
.m-eng-synth-row.is-current .caret { visibility: visible; }
.m-eng-synth-row .label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.m-eng-synth-row .state {
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
}

/* === Accordéons (<details>/<summary> natifs) — quota / portage === */
.m-acc {
    background: var(--m-surface, #fff);
    border: 1px solid var(--m-border, var(--ink-100));
    border-radius: var(--m-r-md, 8px);
    margin-bottom: var(--m-sp-1, 4px);
    overflow: hidden;
}
.m-acc.is-current { border-left: 3px solid var(--m-brand, var(--orange-500)); }
.m-acc-head {
    display: flex;
    align-items: center;
    gap: var(--m-sp-2, 8px);
    padding: var(--m-sp-2, 8px) var(--m-sp-3, 12px);
    cursor: pointer;
    font-size: var(--m-fs-sm, 12px);
    min-height: 40px;
    list-style: none;
}
.m-acc-head::-webkit-details-marker { display: none; }
.m-acc-head::marker { display: none; }
.m-acc-head .caret {
    color: var(--m-text-muted, var(--ink-400));
    font-size: 12px;
    transition: transform 150ms;
}
.m-acc[open] .m-acc-head .caret { transform: rotate(90deg); }
.m-acc-head .summary {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 6px;
    overflow: hidden;
}
.m-acc-head strong { font-weight: var(--m-fw-semibold, 600); flex-shrink: 0; }
.m-acc-head .sep { color: var(--m-text-muted, var(--ink-400)); flex-shrink: 0; }
.m-acc-head .extra {
    color: var(--m-text-muted, var(--ink-400));
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.m-acc-head .badge-current {
    background: var(--m-brand-soft, var(--orange-100));
    color: var(--m-brand-strong, var(--orange-700));
    font-size: 9.5px;
    font-weight: var(--m-fw-bold, 700);
    text-transform: uppercase;
    letter-spacing: 0.3px;
    padding: 2px 6px;
    border-radius: var(--m-r-pill, 9999px);
    flex-shrink: 0;
}
.m-acc-body {
    padding: var(--m-sp-2, 8px) var(--m-sp-3, 12px) var(--m-sp-3, 12px);
    font-size: var(--m-fs-sm, 12px);
    border-top: 1px solid var(--m-border, var(--ink-100));
    background: var(--m-bg, var(--ink-25));
}
.m-acc-body .bi { color: var(--m-text-muted, var(--ink-400)); margin-right: 2px; }
.m-acc-body > div + div { margin-top: 4px; }

/* Progress line sous progress bar (quota détaillé) */
.m-eng-progress-line {
    margin: 6px 0;
    font-size: var(--m-fs-sm, 12px);
    color: var(--m-text-muted, var(--ink-400));
    font-variant-numeric: tabular-nums;
}
.m-eng-progress-line strong { color: var(--m-text, var(--ink-900)); }

/* Bandeau override autorisé (dans accordéon ou single quota) */
.m-eng-override {
    background: var(--m-info-soft, var(--info-soft));
    border: 1px solid var(--m-info-line, color-mix(in srgb, var(--info-base) 25%, transparent));
    border-radius: var(--m-r-md, 8px);
    padding: 6px 10px;
    margin-top: 8px;
    color: var(--m-info, var(--info-base));
    font-size: var(--m-fs-sm, 12px);
    display: flex;
    gap: 6px;
    align-items: flex-start;
}
.m-eng-override .bi {
    font-size: 14px;
    flex-shrink: 0;
    margin-top: 1px;
    color: var(--m-info, var(--info-base));
}
.m-eng-override b { color: var(--m-info, var(--info-base)); font-weight: var(--m-fw-bold, 700); }

/* === Frise CRA 13 mois (12 + prévisionnel) ===
   Grille adaptative : tous les mois visibles d'un coup, wrap sur 2-3
   lignes selon la largeur viewport. Pas de scroll horizontal — chaque
   mois est directement tappable au doigt pour ouvrir le CRA correspondant.
   `auto-fit` + `minmax(50px, 1fr)` répartit l'espace automatiquement
   (sur 380 px : ~6 mois par ligne, donc 13 mois sur 3 lignes 6+6+1). */
.m-month-strip {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(50px, 1fr));
    gap: 4px;
    padding: var(--m-sp-1, 4px) 0 var(--m-sp-2, 8px);
}
.m-month {
    height: 64px;
    background: var(--m-bg, var(--ink-25));
    border: 1px solid var(--m-border, var(--ink-100));
    border-radius: var(--m-r-md, 8px);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    color: var(--m-text, var(--ink-900));
    gap: 2px;
    position: relative;
}
.m-month-lbl {
    font-size: 9.5px;
    font-weight: var(--m-fw-semibold, 600);
    color: var(--m-text-muted, var(--ink-400));
    text-transform: uppercase;
    line-height: 1;
}
.m-month-year {
    font-size: 9px;
    color: var(--m-text-muted, var(--ink-400));
    line-height: 1;
}
.m-month-state {
    font-size: 14px;
    line-height: 1;
}
.m-month.is-validated { background: var(--m-success-soft); border-color: var(--m-success-line); }
.m-month.is-validated .m-month-state { color: var(--m-success); }
.m-month.is-draft { background: var(--m-warning-soft); border-color: var(--m-warning-line); }
.m-month.is-draft .m-month-state { color: var(--m-warning-strong); }
.m-month.is-submitted .m-month-state { color: var(--m-info); }
.m-month.is-missing,
.m-month.is-empty { background: var(--m-danger-soft); border-color: var(--m-danger-line); }
.m-month.is-missing .m-month-state,
.m-month.is-empty .m-month-state { color: var(--m-danger); }
.m-month.is-out { opacity: 0.4; }
.m-month.is-current {
    border: 2px solid var(--m-brand);
    box-shadow: 0 0 0 3px var(--m-brand-soft);
    z-index: 1;
}

/* === Archive engagements terminés (repliable) === */
.m-eng-archive {
    padding: 0;
    margin-top: var(--m-sp-3, 12px);
}
.m-eng-archive summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    min-height: var(--m-touch, 44px);
}
.m-eng-archive summary::-webkit-details-marker { display: none; }
.m-eng-archive summary > .bi { color: var(--m-text-muted, var(--ink-400)); }
.m-eng-archive-label {
    flex: 1;
    font-weight: var(--m-fw-semibold, 600);
    font-size: var(--m-fs-base, 13.5px);
}
.m-eng-archive-caret { transition: transform 150ms; }
.m-eng-archive[open] .m-eng-archive-caret { transform: rotate(180deg); }
.m-eng-archive-list {
    list-style: none;
    padding: 0 14px 12px;
    margin: 0;
}
.m-eng-archive-list li {
    padding: 8px 0;
    border-top: 1px solid var(--m-border, var(--ink-100));
    font-size: var(--m-fs-sm, 12px);
}
.m-eng-archive-list li:first-child { border-top: 0; }
.m-eng-archive-code {
    font-weight: var(--m-fw-semibold, 600);
    color: var(--m-text, var(--ink-900));
}
.m-eng-archive-meta {
    color: var(--m-text-muted, var(--ink-400));
    margin-top: 2px;
}

/* ============================================================
   EVO-063 SL 1.6 — Mes absences liste responsive mobile
   ------------------------------------------------------------
   Cards d'absence groupées « À venir » / « Passées », stripe couleur
   selon type, recherche live branchée sur le controller live-filter
   existant (partagé avec la vue desktop). Tabs Liste/Calendrier.
   ============================================================ */
.m-abs-page { padding-bottom: calc(var(--m-h-bottombar, 64px) + var(--m-sp-3, 12px)); }

.m-abs-list-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-2, 8px);
    /* margin-bottom uniforme avec les filtres/sections suivants (12 px),
       cohérent avec .m-cra-list-head (EVO-063 SL 1.6 équilibrage). */
    margin: 4px 0 var(--m-sp-3, 12px);
}
.m-abs-list-head .m-page-title { margin: 0; flex: 1; min-width: 0; }
.m-abs-list-yearform { margin: 0; flex-shrink: 0; }

.m-abs-counters {
    font-size: var(--m-fs-sm, 12px);
    color: var(--m-text-muted, var(--ink-400));
    margin-bottom: var(--m-sp-3, 12px);
}

/* Recherche live mobile -- input avec icône loupe */
.m-abs-search {
    position: relative;
    margin-bottom: var(--m-sp-3, 12px);
}
.m-abs-search-icon {
    position: absolute;
    left: var(--m-sp-3, 12px);
    top: 50%;
    transform: translateY(-50%);
    color: var(--m-text-muted, var(--ink-400));
    font-size: 16px;
    pointer-events: none;
}
.m-abs-search-input {
    padding-left: calc(var(--m-sp-3, 12px) + 24px);
}

/* Empty state */
.m-abs-empty {
    text-align: center;
    padding: var(--m-sp-6, 24px);
    color: var(--m-text-muted, var(--ink-400));
}
.m-abs-empty > .bi {
    font-size: 32px;
    color: var(--m-text-muted, var(--ink-400));
    margin-bottom: var(--m-sp-2, 8px);
    display: block;
}
.m-abs-empty-title {
    font-weight: var(--m-fw-bold, 700);
    color: var(--m-text, var(--ink-900));
    font-size: var(--m-fs-md, 14px);
    margin-bottom: var(--m-sp-1, 4px);
}
.m-abs-empty-desc {
    font-size: var(--m-fs-sm, 12px);
    line-height: var(--m-lh-base, 1.4);
}

/* Section title (À venir / Passées) */
.m-abs-group {
    font-size: var(--m-fs-sm, 12px);
    font-weight: var(--m-fw-semibold, 600);
    color: var(--m-text-muted, var(--ink-400));
    text-transform: uppercase;
    letter-spacing: 0.3px;
    margin: var(--m-sp-3, 12px) 4px var(--m-sp-1, 4px);
}

/* Card par AbsenceDetail */
.m-abs-card {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--m-sp-3, 12px);
    align-items: center;
    background: var(--m-surface, #fff);
    border: 1px solid var(--m-border, var(--ink-100));
    border-radius: var(--m-r-lg, 10px);
    padding: var(--m-sp-3, 12px);
    padding-left: calc(var(--m-sp-3, 12px) + 4px);
    text-decoration: none;
    color: var(--m-text, var(--ink-900));
    position: relative;
    overflow: hidden;
}
.m-abs-card:active { background: var(--m-bg, var(--ink-25)); }
.m-abs-card-stripe {
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 4px;
}
.m-abs-card-body { min-width: 0; }
.m-abs-card-type {
    font-weight: var(--m-fw-bold, 700);
    font-size: var(--m-fs-md, 14px);
    line-height: 1.2;
}
.m-abs-card-frac {
    display: inline-block;
    margin-left: 6px;
    font-size: var(--m-fs-sm, 12px);
    font-weight: var(--m-fw-medium, 500);
    color: var(--m-text-muted, var(--ink-400));
}
.m-abs-card-dates {
    font-size: var(--m-fs-sm, 12px);
    color: var(--m-text-muted, var(--ink-400));
    margin-top: 2px;
    font-variant-numeric: tabular-nums;
}
.m-abs-card-note {
    font-size: var(--m-fs-sm, 12px);
    color: var(--m-text-muted, var(--ink-400));
    margin-top: 4px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.m-abs-card-note .bi { margin-right: 4px; }
.m-abs-card-days {
    text-align: right;
    flex-shrink: 0;
    min-width: 56px;
}
.m-abs-card-days .val {
    font-size: var(--m-fs-md, 14px);
    font-weight: var(--m-fw-bold, 700);
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
.m-abs-card-days .lbl {
    font-size: 10px;
    color: var(--m-text-muted, var(--ink-400));
    text-transform: uppercase;
    letter-spacing: 0.3px;
    margin-top: 2px;
}

/* Sticky bottom -- héritage .m-bottom-bar du DS + position fixed.
   Le masquage en desktop est garanti par .d-mobile-only { display: none !important }
   au-dessus (utility globale). */
.m-abs-bottom {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--m-z-bottombar, 90);
    background: var(--m-surface, #fff);
    border-top: 1px solid var(--m-border, var(--ink-100));
    padding: var(--m-sp-2, 8px) var(--m-sp-3, 12px) calc(var(--m-sp-2, 8px) + env(safe-area-inset-bottom, 0px));
    display: flex;
    align-items: center;
    gap: var(--m-sp-2, 8px);
    box-shadow: var(--m-shadow-bar, 0 -4px 12px rgba(0, 0, 0, 0.05));
    min-height: var(--m-h-bottombar, 64px);
    flex-wrap: nowrap;
}
.m-abs-bottom .m-bottom-bar-kpi { flex: 1 1 auto; min-width: 0; }
.m-abs-bottom .m-bottom-bar-kpi .label {
    font-size: var(--m-fs-xs, 10.5px);
    color: var(--m-text-muted, var(--ink-400));
    text-transform: uppercase;
    letter-spacing: 0.3px;
    line-height: 1;
}
.m-abs-bottom .m-bottom-bar-kpi .value {
    font-size: var(--m-fs-lg, 16px);
    font-weight: var(--m-fw-bold, 700);
    color: var(--m-text, var(--ink-900));
    line-height: var(--m-lh-tight, 1.2);
}
.m-abs-bottom .m-btn { flex-shrink: 0; }

/* ============================================================
   EVO-063 SL 1.7 — Mes absences calendrier responsive mobile
   ------------------------------------------------------------
   Grille 7 cols × N lignes (mois entier + débords mois précédent/suivant).
   Cellules sleek 56 px min-height, numéro du jour en haut, libellé absence
   centré en bas. Couleurs sémantiques injectées inline depuis le catalogue
   admin (firstAbsence.color). Today en anneau orange (P1-3 audit étude).
   ============================================================ */
.m-cal-page { padding-bottom: calc(var(--m-h-bottombar, 64px) + var(--m-sp-3, 12px)); }

/* Nav mois : chevron prev / monthLabel centré / chevron next */
.m-cal-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--m-sp-2, 8px);
}
.m-cal-nav-label {
    font-size: var(--m-fs-lg, 16px);
    font-weight: var(--m-fw-bold, 700);
    text-transform: capitalize;
    color: var(--m-text, var(--ink-900));
}
.m-cal-nav-btn {
    width: 36px;
    height: 36px;
    border: 1px solid var(--m-border, var(--ink-100));
    border-radius: var(--m-r-md, 8px);
    background: var(--m-surface, #fff);
    color: var(--m-text, var(--ink-900));
    font-size: var(--m-fs-lg, 16px);
    display: flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    flex-shrink: 0;
}
.m-cal-nav-btn:active { background: var(--m-bg, var(--ink-25)); }

/* Grille calendrier 7 colonnes — `minmax(0, 1fr)` impératif pour autoriser
   les cellules à se contraindre sous la largeur intrinsèque du contenu
   (libellés type d'absence longs comme « Congés payés »), sinon la grille
   déborde à droite et coupe les colonnes Ven/Sam/Dim. */
.m-cal-grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 2px;
    background: var(--m-border, var(--ink-100));
    border: 1px solid var(--m-border, var(--ink-100));
    border-radius: var(--m-r-md, 8px);
    overflow: hidden;
    margin-bottom: var(--m-sp-2, 8px);
}
.m-cal-head {
    background: var(--m-bg, var(--ink-25));
    padding: 6px 0;
    text-align: center;
    font-size: 10px;
    font-weight: var(--m-fw-semibold, 600);
    color: var(--m-text-muted, var(--ink-400));
    text-transform: uppercase;
    letter-spacing: 0.3px;
}
.m-cal-cell {
    background: var(--m-surface, #fff);
    min-height: 56px;
    min-width: 0;          /* indispensable pour que ellipsis du label kicke */
    padding: 4px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    text-decoration: none;
    color: var(--m-text, var(--ink-900));
    position: relative;
    overflow: hidden;
}
.m-cal-day-num {
    font-size: var(--m-fs-sm, 12px);
    font-weight: var(--m-fw-semibold, 600);
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
.m-cal-abs-label {
    font-size: 9px;
    font-weight: var(--m-fw-semibold, 600);
    line-height: 1.1;
    margin-top: auto;
    padding: 1px 3px;
    border-radius: 2px;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.m-cal-cell.is-other-month { background: var(--m-bg, var(--ink-25)); }
.m-cal-cell.is-other-month .m-cal-day-num {
    color: var(--m-text-muted, var(--ink-400));
    opacity: 0.5;
}
.m-cal-cell.is-weekend { background: #fafbfc; }
.m-cal-cell.is-weekend .m-cal-day-num {
    color: var(--m-text-muted, var(--ink-400));
    font-weight: var(--m-fw-medium, 500);
}
.m-cal-cell.is-holiday { background: var(--m-brand-soft, var(--orange-100)); }
/* P1-3 audit : « aujourd'hui » en ANNEAU, pas en disque plein (éviterait
   la confusion avec la couleur Formation qui est aussi du brand). */
.m-cal-cell.is-today .m-cal-day-num {
    background: transparent;
    color: var(--m-brand-strong, var(--orange-700));
    border: 2px solid var(--m-brand, var(--orange-500));
    border-radius: 50%;
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 10px;
    font-weight: var(--m-fw-bold, 700);
}

/* Légende couleurs sous le calendrier */
.m-cal-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--m-sp-2, 8px);
    padding: var(--m-sp-2, 8px) 0;
}
.m-cal-legend-item {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    color: var(--m-text-muted, var(--ink-400));
}
.m-cal-legend-dot {
    width: 10px; height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
}

/* ============================================================
   EVO-063 SL 1.6 — Sélecteur année (.year-select)
   ------------------------------------------------------------
   Promu depuis dashboard.css en classes globales pour réutilisation
   sur /absences (collab) et /cra (collab). Style identique à celui
   du dashboard (capsule espresso avec « ANNÉE » label + valeur bold).
   La cascade laisse intactes les définitions de dashboard.css (qui
   se chargent APRÈS sur la page dashboard, identique = idempotent).
   ============================================================ */
.year-select {
    display: flex; align-items: center; gap: var(--s-2);
    height: 38px; padding: 0 var(--s-3);
    border: 1px solid var(--border-subtle); border-radius: var(--r-8);
    background: var(--surface-card);
}
.year-select__lbl {
    font-family: var(--font-mono); font-size: var(--t-10);
    font-weight: var(--fw-medium); letter-spacing: 0.1em;
    text-transform: uppercase; color: var(--text-faint);
}
.year-select__btn {
    /* Reset rendu natif du <select> pour avoir un contrôle 100% — sinon le
       chevron natif iOS Safari peut chevaucher la valeur du selected option
       et la rendre invisible. */
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    border: 0;
    background: transparent;
    cursor: pointer;
    font-family: 'Inter', sans-serif;
    font-size: var(--t-14);
    font-weight: var(--fw-bold);
    color: var(--text-strong);
    /* Chevron custom en SVG inline (`currentColor` suit la couleur du texte) */
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%231A1612'><path d='M4 6l4 4 4-4z'/></svg>");
    background-repeat: no-repeat;
    background-position: right 4px center;
    background-size: 12px;
    padding: 0 22px 0 var(--s-2);
    height: 36px;
    line-height: 36px;
}
.year-select__btn:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
    border-radius: var(--r-8);
}
.year-select-wrap { display: inline-flex; align-items: center; gap: var(--s-2); }
.year-back {
    display: inline-flex; align-items: center; gap: var(--s-2);
    height: 38px; padding: 0 var(--s-3);
    border: 1px solid var(--border-subtle);
    border-radius: var(--r-8);
    background: var(--surface-card);
    font: var(--fw-medium) var(--t-13)/1 'Inter', sans-serif;
    color: var(--text-muted);
    text-decoration: none;
}
.year-back i { color: var(--orange-500); }
.year-back:hover { color: var(--text-strong); background: var(--surface-app); text-decoration: none; }

/* Header mobile dédié au form /absences/new — pas de padding-bottom
   réservé au sticky bottom (il n'y en a pas sur cet écran ; le bouton
   Enregistrer est dans le footer du form). */
.m-abs-form-page { padding-bottom: 0; }

/* Bandeau H1 + bouton Annuler à droite, sur la même ligne (symétrique
   avec le sélecteur année des écrans list/calendar). */
.m-abs-form-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-2);
    margin: 4px 0 var(--m-sp-2, 8px);
}
.m-abs-form-head .m-page-title { margin: 0; flex: 1; min-width: 0; }
.m-abs-form-cancel { flex-shrink: 0; }

/* Sous-titre lead du form mobile /absences/new (cohérent .m-abs-counters) */
.m-abs-form-lead {
    font-size: var(--m-fs-sm, 12px);
    color: var(--m-text-muted, var(--ink-400));
    margin-bottom: var(--m-sp-3, 12px);
    line-height: var(--m-lh-base, 1.4);
}

/* ============================================================
   EVO-063 SL 1.8 — Nouvelle absence responsive mobile
   ------------------------------------------------------------
   Form Symfony = 1 seul markup. Le rendu desktop/mobile differ via :
   - Wrappers <label class="abs-detail-cell"> autour de chaque widget,
     contenant un <span class="abs-detail-cell-lbl">. Le label est masque
     en desktop (libelles deja dans .abs-detail-head au-dessus de la grid),
     visible en mobile (uppercase au-dessus du champ).
   - Card-head .abs-detail-card-head (num pastille + type) : masque en
     desktop (positionnement inutile dans la grid 6-cols), visible en mobile
     comme header de chaque card detail (mockup absence-new.html).
   - En mobile : grid 6-cols -> 1-col, .abs-detail-card-head visible,
     numero via CSS counter, type label affiche.
   ============================================================ */

/* Desktop : labels inline et card-head masques. Les widgets s alignent
   sur la grid 6-cols existante (les <label> remplacent les widgets
   comme grid items au meme index). */
.abs-detail-cell {
    display: contents;        /* le <label> ne casse pas la grid en desktop */
}
.abs-detail-cell-lbl,
.abs-detail-card-head {
    display: none;             /* masques en desktop */
}

@media (max-width: 767px) {
    /* Period section : dates Debut / Fin empilees 1 col */
    .abs-form-wrap .field-row {
        flex-direction: column;
        align-items: stretch;
    }
    .abs-form-wrap .field-row > .field,
    .abs-form-wrap .field-row > .field--narrow {
        flex: 1 1 auto;
        min-width: 0;
    }

    /* Detail row : passe en card empilee, padding genereux, fond gris pale
       coherent avec le mockup absence-new.html (.m-abs-detail bg: --m-bg). */
    .abs-detail-row {
        grid-template-columns: 1fr;
        gap: 10px;
        padding: 12px 14px 14px;
        position: relative;
        background: var(--ink-25, #FBFAF7);
    }

    /* Card-head : numero pastille + type label + (trash repositionne par
       le bloc plus bas en position absolute). Counter incremente sur
       chaque .abs-detail-row, affiche dans .abs-detail-num via ::before. */
    .abs-form-wrap [data-collection-target="container"] {
        counter-reset: abs-detail-num;
    }
    .abs-detail-row { counter-increment: abs-detail-num; }

    .abs-detail-card-head {
        display: flex;
        align-items: center;
        gap: 8px;
        margin-bottom: 4px;
        padding-bottom: 4px;
        /* min-height = trash (32px) + 2 * top offset (10px) pour que la
           corbeille absolute haut-droite ne deborde pas sur le widget Type
           juste en-dessous. */
        min-height: 42px;
    }
    .abs-detail-num {
        width: 22px;
        height: 22px;
        border-radius: 50%;
        background: var(--orange-50);
        color: var(--orange-700);
        font-size: 12px;
        font-weight: 700;
        display: flex;
        align-items: center;
        justify-content: center;
        flex-shrink: 0;
    }
    .abs-detail-num::before { content: counter(abs-detail-num); }
    .abs-detail-card-type {
        flex: 1;
        font-weight: 600;
        font-size: 13.5px;
        color: var(--text-strong);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* Labels inline (uppercase au-dessus de chaque widget) */
    .abs-detail-cell {
        display: block;       /* re-casse le `display: contents` desktop */
    }
    .abs-detail-cell-lbl {
        display: block;
        font-size: 10.5px;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.3px;
        color: var(--text-muted);
        margin-bottom: 4px;
    }

    /* Widgets plein largeur, taille touch-friendly */
    .abs-detail-row .form-control,
    .abs-detail-row .form-select {
        width: 100%;
        padding: 9px 10px;
        font-size: 14px;
    }

    /* Trash / locked en haut a droite de la card (sur la ligne du card-head).
       Corbeille en rouge sur mobile (pas attendu un hover pour reveler la
       semantique destructive — moins de hover en tactile). */
    .abs-detail-remove,
    .abs-detail-locked {
        position: absolute;
        top: 10px;
        right: 10px;
        z-index: 1;
    }
    .abs-detail-remove {
        color: var(--danger-base, #B23A2A);
    }
    .abs-detail-remove:hover,
    .abs-detail-remove:active {
        background: var(--danger-soft, #FBE5E1);
        color: var(--danger-base, #B23A2A);
    }

    /* Card-header form : on garde uniquement le titre/sous-titre.
       Le bouton « + Ajouter une absence » du header est masque (il est
       deja present en bas du card-body, plus naturel a atteindre apres
       avoir scrolle a travers les lignes existantes). */
    .abs-form-wrap .card-header {
        flex-direction: column;
        align-items: flex-start;
        gap: 8px;
    }
    .abs-form-wrap .card-header > .btn,
    .abs-form-wrap .card-header > button { display: none; }

    /* Total declare : alignement propre mobile */
    .abs-detail-total {
        justify-content: space-between;
        flex-wrap: wrap;
    }

    /* Actions footer : empilees + plein largeur */
    .abs-form-wrap .d-flex.gap-2.mt-3 {
        flex-direction: column-reverse;
    }
    .abs-form-wrap .d-flex.gap-2.mt-3 > .btn { width: 100%; }
}

/* ============================================================
   EVO-063 SL 1.9 — Nouveau CRA responsive mobile
   ------------------------------------------------------------
   Form Symfony (engagement + month + year) + frise CRA. Approche :
   - Header mobile dedie (.m-cra-new-page) avec eyebrow + H1 + Annuler droite
   - CSS responsive sur le form : .field-row empile, frise en 4 cols touch,
     footer form (Annuler/Creer) masque (sticky bottom le remplace)
   - Sticky bottom mobile (.m-cra-new-bottom) avec Annuler + Creer le CRA,
     bouton submit lie au form via attribut HTML5 form=""
   ============================================================ */

/* Reservation espace pour le sticky bottom */
.m-cra-new-page { padding-bottom: 0; }

.m-cra-new-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-2);
    margin: 4px 0 var(--m-sp-2, 8px);
}
.m-cra-new-head .m-page-title { margin: 0; flex: 1; min-width: 0; }
.m-cra-new-cancel { flex-shrink: 0; }

.m-cra-new-lead {
    font-size: var(--m-fs-sm, 12px);
    color: var(--m-text-muted, var(--ink-400));
    margin-bottom: var(--m-sp-3, 12px);
    line-height: var(--m-lh-base, 1.4);
}

/* Sticky bottom mobile : Annuler + Creer le CRA */
.m-cra-new-bottom {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: var(--m-z-bottombar, 90);
    background: var(--m-surface, #fff);
    border-top: 1px solid var(--m-border, var(--ink-100));
    padding: var(--m-sp-2, 8px) var(--m-sp-3, 12px) calc(var(--m-sp-2, 8px) + env(safe-area-inset-bottom, 0px));
    display: flex;
    align-items: center;
    gap: var(--m-sp-2, 8px);
    box-shadow: var(--m-shadow-bar, 0 -4px 12px rgba(0, 0, 0, 0.05));
    min-height: var(--m-h-bottombar, 64px);
    flex-wrap: nowrap;
}
.m-cra-new-bottom .btn { flex-shrink: 0; }
.m-cra-new-bottom .btn-primary { flex: 1; justify-content: center; }
.m-cra-new-bottom[hidden] { display: none !important; }

@media (max-width: 767px) {
    /* Card padding compact mobile (form) + reservation espace sticky bottom */
    [data-controller="cra-frise-switch"] > .card {
        max-width: none;
        margin-bottom: calc(var(--m-h-bottombar, 64px) + var(--m-sp-3, 12px));
    }
    [data-controller="cra-frise-switch"] > .card .card-body {
        padding: var(--s-3);
    }

    /* Card "État des CRA sur cet engagement" (frise 12 mois desktop) :
       masquée en mobile car redondante avec la grille mois dédiée
       (états is-saisi vert dans la grille mobile font office). */
    [data-controller="cra-frise-switch"] > .card.mt-3 {
        display: none;
    }

    /* Sections form en mobile : pas de double bordure ni de marge dupliquée
       avec la .card.card-body qui les enveloppe. .m-form-section enlève sa
       bordure ici car la card parent en porte une. */
    [data-controller="cra-frise-switch"] .m-form-section {
        background: transparent;
        border: 0;
        border-radius: 0;
        margin-bottom: var(--m-sp-3, 12px);
        overflow: visible;
    }
    [data-controller="cra-frise-switch"] .m-form-section:last-child {
        margin-bottom: 0;
    }
    [data-controller="cra-frise-switch"] .m-form-section-body {
        padding: 0;
    }
    [data-controller="cra-frise-switch"] .m-form-section-head {
        padding: 0 0 var(--m-sp-2, 8px);
        border-bottom: 0;
    }
}

/* Desktop : neutraliser visuellement les wrappers .m-form-section
   et masquer le header mobile (icône + titre + sub) qui n'a pas
   de sens hors mobile. mobile-components.css n'est pas chargé en
   desktop, donc .m-form-section/.m-form-section-body n'ont pas
   de styles — il reste juste à masquer le header. */
@media (min-width: 768px) {
    .m-form-section-head { display: none; }
}

/* Callout générique en mobile : passe en flex column pour que le
   bouton d'action (.callout__actions) prenne la largeur dispo
   (sinon le texte du __body est compressé à 4-5 caractères et
   wrap en cascade — vu en SL 1.9 sur /cra/new avec un engagement
   sans mois dispo). */
@media (max-width: 767px) {
    .callout {
        flex-direction: column;
        align-items: stretch;
    }
    .callout__actions {
        margin-top: 8px;
    }
    .callout__actions .btn {
        width: 100%;
        justify-content: center;
    }
}

/* ============================================================
   EVO-063 SL 1.10 — CRA edit responsive mobile
   ------------------------------------------------------------
   Strategy : la table desktop (.cra-grid) reste dans le DOM (cra-grid
   controller Stimulus reste pleinement opérationnel) mais est masquée
   visuellement en mobile. Le markup mobile (.m-cra-edit-page) en tête
   du template fait office d'UI et sync avec la table via le controller
   cra-mobile-grid (outlet vers cra-grid).
   ============================================================ */
@media (max-width: 767px) {
    /* Réservation espace pour le sticky bottom */
    .m-cra-edit-page ~ .d-desktop-only { display: none !important; }
    .m-cra-edit-page {
        padding-bottom: calc(var(--m-h-bottombar, 64px) + var(--m-sp-3, 12px));
    }
    /* Si pas de sticky bottom (CRA validé non éditable sans action), pas de padding */
    .m-cra-edit-page:not(:has(~ .m-cra-edit-bottom)) {
        padding-bottom: 0;
    }

    /* Bottom-sheets : les <dialog> natifs deviennent des feuilles modales
       bottom-anchored en mobile pour matcher les patterns iOS/Android.
       Cible : validate-modal, reject-modal, invalidate-modal, retract-modal,
       confirm-modal (utils/confirm.js).
       Reste accessible via showModal() — pas de réécriture JS. */
    dialog[id$="-modal"],
    dialog.confirm-dialog {
        margin: 0 !important;
        width: 100% !important;
        max-width: none !important;
        max-height: 90vh;
        border-radius: var(--m-r-lg, 14px) var(--m-r-lg, 14px) 0 0 !important;
        position: fixed !important;
        bottom: 0;
        top: auto !important;
        left: 0;
        right: 0;
        padding-bottom: env(safe-area-inset-bottom, 0px) !important;
        overflow-y: auto;
    }
    dialog[id$="-modal"]::backdrop,
    dialog.confirm-dialog::backdrop {
        background: rgba(0, 0, 0, 0.4);
    }
    /* Boutons de la barre footer des dialogs : full-width stack en mobile */
    dialog[id$="-modal"] > form > div:last-child {
        flex-direction: column-reverse !important;
        gap: 6px !important;
    }
    dialog[id$="-modal"] > form > div:last-child .btn {
        width: 100%;
        justify-content: center;
    }
}

