/* =========================================================================
   ESDI MANAGER — 03-components.css
   Bootstrap 5 overrides : .btn, .card, .form-control + variants ESDI
   Spec : epics.md Story 1.3 AC4 + UX spec ligne 1173-1252 (Button Hierarchy, Form Patterns)
   ========================================================================= */

/* =========================================================================
   .btn — base + 5 variants ESDI
   Pill (radius-pill), padding 15×20px (height = 44px = touch target WCAG 2.5.5 AA)
   Hover = filter brightness(0.95), focus-visible = shadow cyan 3px
   ========================================================================= */

.btn {
    border-radius: var(--radius-pill);
    padding: 15px 20px; /* 15 + 14 (font-size, line-height 1) + 15 = 44px height */
    font-family: var(--font-sans);
    font-size: 14px;
    font-weight: 500;
    line-height: 1;
    text-decoration: none; /* évite underline si <a class="btn"> */
    border: 1px solid transparent;
    transition: filter var(--duration-micro) var(--ease-default),
                background-color var(--duration-micro) var(--ease-default),
                box-shadow var(--duration-micro) var(--ease-default);
    cursor: pointer;
}

.btn:hover:not(:disabled):not(.disabled) {
    filter: brightness(0.95);
    text-decoration: none;
}

.btn:focus-visible {
    box-shadow: var(--shadow-focus);
    outline: none;
}

.btn:disabled,
.btn.disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* --- Primary : Bleu ESDI plein (contraste 7.4:1 AAA validé) --- */
.btn-primary {
    background-color: var(--primary-500);
    color: #FFFFFF;
    border-color: var(--primary-500);
}

.btn-primary:hover:not(:disabled):not(.disabled),
.btn-primary:focus-visible,
.btn-primary:active {
    background-color: var(--primary-600);
    color: #FFFFFF;
    border-color: var(--primary-600);
}

/* --- Primary gradient : RÉSERVÉ Embaucher / hero CTA / login ---
   JAMAIS dans UI chrome quotidienne (UX spec ligne 584) */
.btn-primary-gradient {
    background: var(--gradient-brand);
    color: #FFFFFF;
    border-color: transparent;
}

.btn-primary-gradient:hover:not(:disabled):not(.disabled),
.btn-primary-gradient:focus-visible,
.btn-primary-gradient:active {
    background: var(--gradient-brand);
    filter: brightness(0.92);
    color: #FFFFFF;
}

/* --- Secondary : transparent + border --- */
.btn-secondary {
    background-color: transparent;
    color: var(--ink);
    border-color: var(--line);
}

.btn-secondary:hover:not(:disabled):not(.disabled),
.btn-secondary:focus-visible,
.btn-secondary:active {
    background-color: var(--bg-section-cool);
    color: var(--ink);
    border-color: var(--line);
}

/* --- Ghost : text-only Cyan ESDI (accent), pas de fond ni bordure --- */
.btn-ghost {
    background-color: transparent;
    color: var(--accent-600);
    border-color: transparent;
    padding: 13px 12px; /* slightly tighter horizontal, hauteur 44px préservée */
}

.btn-ghost:hover:not(:disabled):not(.disabled),
.btn-ghost:focus-visible {
    background-color: var(--sig-ai-bg);
    color: var(--accent-700);
}

/* --- Danger : Licencier / Supprimer définitivement ---
   TOUJOURS avec modal de confirmation (UX-DR ligne 1186).
   Hover = filter brightness pour éviter le quasi-noir d'un deep maroon bg. */
.btn-danger {
    background-color: var(--sig-alert);
    color: #FFFFFF;
    border-color: var(--sig-alert);
}

.btn-danger:hover:not(:disabled):not(.disabled),
.btn-danger:focus-visible,
.btn-danger:active {
    background-color: var(--sig-alert);
    filter: brightness(0.92);
    color: #FFFFFF;
    border-color: var(--sig-alert);
}

/* --- Icon-only : 40×40px touch target (WCAG 2.5.5 AA + Apple HIG borderline) --- */
.btn-icon {
    width: 40px;
    height: 40px;
    padding: 10px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--line);
    background-color: transparent;
    color: var(--ink-soft);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.btn-icon:hover:not(:disabled) {
    background-color: var(--bg-section-cool);
    color: var(--ink);
}

/* =========================================================================
   .card — radius 12px, padding space-5, border line + shadow-sm
   Optional 3px left status bar via data-status="ok|warn|alert|ai"
   ========================================================================= */

.card {
    border-radius: var(--radius-md);
    padding: var(--space-5);
    border: 1px solid var(--line);
    background-color: var(--bg-card);
    box-shadow: var(--shadow-sm);
}

/* Bootstrap met du padding sur .card-body — on s'aligne pour éviter le double padding */
.card > .card-body {
    padding: 0;
}

.card[data-status="ok"]    { border-left: 3px solid var(--sig-ok); }
.card[data-status="warn"]  { border-left: 3px solid var(--sig-warn); }
.card[data-status="alert"] { border-left: 3px solid var(--sig-alert); }
.card[data-status="ai"]    { border-left: 3px solid var(--sig-ai); }

/* =========================================================================
   .form-control — radius sm, padding 10×14, border line, focus accent (cyan) 3px
   Spec UX ligne 1224-1233 (Form Patterns)
   Font-size 15px (jamais <14 pour éviter zoom iOS)
   Focus border = Cyan ESDI accent (pas Bleu primary) pour pairing avec shadow-focus cyan.
   ========================================================================= */

.form-control,
.form-select {
    border-radius: var(--radius-sm);
    padding: 10px 14px;
    font-family: var(--font-sans);
    font-size: 15px;
    line-height: 1.5;
    border: 1px solid var(--line);
    background-color: var(--bg-card);
    color: var(--ink);
    transition: border-color var(--duration-micro) var(--ease-default),
                box-shadow var(--duration-micro) var(--ease-default);
}

.form-control:focus,
.form-select:focus {
    border-color: var(--accent-500);
    box-shadow: var(--shadow-focus);
    outline: none;
}

/* .form-select : réserver la place de la flèche déroulante. Le padding-right partagé (14px) avec
   .form-control ne suffit pas → sur un select étroit (width:auto / .w-auto), le texte passait SOUS
   le chevron (superposition lettres/flèche). On aligne sur l'intention Bootstrap (~2rem à droite). */
.form-select {
    padding-right: 34px;
}

.form-control::placeholder {
    color: var(--ink-faded);
    opacity: 1; /* surcharge Firefox */
}

.form-control:disabled {
    background-color: var(--bg-section-warm);
    color: var(--ink-soft);
    cursor: not-allowed;
}

/* WebKit autofill — neutralise le yellow bg Chrome qui override --bg-card / --ink.
   Critique sur le login form (première impression) + dark mode jarring sinon.
   box-shadow inset = trick standard (background-color est ignoré par WebKit autofill). */
.form-control:-webkit-autofill,
.form-control:-webkit-autofill:hover,
.form-control:-webkit-autofill:focus,
.form-control:-webkit-autofill:active {
    -webkit-box-shadow: 0 0 0 1000px var(--bg-card) inset;
    -webkit-text-fill-color: var(--ink);
    transition: background-color 9999s ease-out 0s;
}

/* Form label au-dessus (UX-DR62 — jamais flottants) */
.form-label {
    display: block;
    font-family: var(--font-sans);
    font-size: 13px;
    font-weight: 500;
    color: var(--ink);
    margin-bottom: var(--space-2);
}

/* Helper text sous le champ */
.form-text {
    display: block;
    font-family: var(--font-sans);
    font-size: 13px;
    color: var(--ink-faded);
    margin-top: var(--space-1);
}

/* Error text sous le champ (Bootstrap pattern : hidden par défaut, visible via .is-invalid sibling) */
.invalid-feedback {
    display: none; /* Bootstrap pattern — visible seulement quand sibling is .is-invalid */
    font-family: var(--font-sans);
    font-size: 13px;
    color: var(--sig-alert-text);
    margin-top: var(--space-1);
}

.form-control.is-invalid ~ .invalid-feedback,
.form-select.is-invalid ~ .invalid-feedback,
.was-validated .form-control:invalid ~ .invalid-feedback,
.was-validated .form-select:invalid ~ .invalid-feedback {
    display: block;
}

.form-control.is-invalid,
.form-select.is-invalid {
    border-color: var(--sig-alert);
}

.form-control.is-invalid:focus,
.form-select.is-invalid:focus {
    box-shadow: var(--shadow-focus-alert);
}

/* =========================================================================
   Story 2.4 — Sidebar tenant + Employee-card + Status-dot + Empty-state
   Spec : epics.md Story 2.4 AC4-AC8 + UX spec lignes 1042-1088 (composants UX-DR21/23) + 1255-1280 (navigation)
   ========================================================================= */

/* --- Sidebar tenant (UX-DR66 — 248px desktop, offcanvas mobile via Bootstrap 5 natif) --------------- */
.esdi-sidebar {
    padding: var(--space-6) var(--space-4);
    border-right: 1px solid var(--line);
    background-color: var(--bg);
}

/* Desktop : colonne sticky 248px. ⚠️ Scopé ≥768px (fix global 2026-07-14, refonte /chat) : appliqué
   à tous les breakpoints, position:sticky + height:100vh écrasaient le position:fixed du offcanvas-md
   Bootstrap en mobile → l'aside restait DANS LE FLUX et poussait toutes les pages d'un écran entier
   vers le bas sur mobile. */
@media (min-width: 768px) {
    .esdi-sidebar {
        width: var(--sidebar-width);
        height: 100vh;
        position: sticky;
        top: 0;
        overflow-y: auto;
        flex-shrink: 0;
    }
}

/* Mobile : drawer offcanvas Bootstrap. NB : avec le pattern responsive `offcanvas-md`, l'élément ne
   reçoit JAMAIS la classe `.offcanvas` seule (l'ancien sélecteur .esdi-sidebar.offcanvas était mort). */
@media (max-width: 767.98px) {
    .esdi-sidebar {
        width: 280px;
    }
}

.esdi-sidebar .nav-link {
    padding: var(--space-3) var(--space-4);
    color: var(--ink-soft);
    border-radius: var(--radius-sm);
    font-size: 14px;
    transition: background-color var(--duration-micro) var(--ease-default),
                color var(--duration-micro) var(--ease-default);
    display: flex;
    align-items: center;
}

.esdi-sidebar .nav-link:hover {
    background-color: var(--bg-section-cool);
    color: var(--ink);
    text-decoration: none;
}

.esdi-sidebar .nav-link.active {
    background-color: var(--bg-section-cool);
    color: var(--primary);
    font-weight: 500;
}

.esdi-sidebar__footer {
    border-color: var(--line) !important;
}

/* --- Employee-card (UX-DR21 — 40px avatar gradient + nom + slug + status dot) ----------------------- */
.esdi-employee-card {
    border-radius: var(--radius-md);
    border: 1px solid var(--line);
    box-shadow: var(--shadow-sm);
    cursor: pointer;
    transition: box-shadow var(--duration-medium) var(--ease-default),
                transform var(--duration-medium) var(--ease-default);
}

.esdi-employee-card:hover {
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

.esdi-employee-card:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
}

.esdi-employee-card__avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--gradient-brand);
    color: #FFFFFF; /* exception hard-coded : utility blanc sur gradient — pas un token color */
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 16px;
    line-height: 1;
}

/* --- Employee-hero (Story 2.5 — UX-DR33 : 80px avatar + name h1 + role + status pulse responsive) -- */
.esdi-employee-hero {
    padding: var(--space-6) var(--space-8);
    border-radius: var(--radius-md);
    background-color: var(--bg-section-cool);
    margin-bottom: var(--space-6);
}

.esdi-employee-hero__inner {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-5);
}

@media (min-width: 768px) {
    .esdi-employee-hero__inner {
        flex-direction: row;
        align-items: center;
    }
}

.esdi-employee-hero__avatar {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background: var(--gradient-brand);
    color: #FFFFFF; /* exception confirmée Story 2.4 : blanc sur gradient */
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 28px;
    line-height: 1;
    flex-shrink: 0;
}

.esdi-employee-hero__body {
    flex-grow: 1;
    min-width: 0;
}

.esdi-employee-hero__name {
    margin-bottom: var(--space-2);
    word-break: break-word;
}

/* --- Status-dot (UX-DR23 — 8px circle, 4 variants idle/active/paused/error) ------------------------ */
.esdi-status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
    background-color: var(--ink-faded); /* fallback default */
}

.esdi-status-dot--idle { background-color: var(--ink-faded); }
.esdi-status-dot--active { background-color: var(--sig-ok); }
.esdi-status-dot--paused { background-color: var(--sig-warn); }
.esdi-status-dot--error { background-color: var(--sig-alert); }

/* Story 7.4 — Dashboard "qui bosse en direct" pulse variants */
.esdi-status-dot--running {
    background-color: #3fbecc; /* cyan ESDI */
    box-shadow: 0 0 0 0 rgba(63, 190, 204, 0.6);
    animation: esdi-pulse-cyan 1.6s ease-in-out infinite;
}
.esdi-status-dot--waiting {
    background-color: #f59e0b; /* amber */
    box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.6);
    animation: esdi-pulse-amber 2.4s ease-in-out infinite;
}
.esdi-status-dot--failed {
    background-color: #ef4444; /* red */
    box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7);
    animation: esdi-pulse-red 1.2s ease-in-out infinite;
}
@keyframes esdi-pulse-cyan {
    0%   { box-shadow: 0 0 0 0 rgba(63, 190, 204, 0.6); }
    70%  { box-shadow: 0 0 0 8px rgba(63, 190, 204, 0); }
    100% { box-shadow: 0 0 0 0 rgba(63, 190, 204, 0); }
}
@keyframes esdi-pulse-amber {
    0%   { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0.6); }
    70%  { box-shadow: 0 0 0 6px rgba(245, 158, 11, 0); }
    100% { box-shadow: 0 0 0 0 rgba(245, 158, 11, 0); }
}
@keyframes esdi-pulse-red {
    0%   { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.7); }
    70%  { box-shadow: 0 0 0 8px rgba(239, 68, 68, 0); }
    100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
}

/* Story 7.4 / 16.9 — Dashboard /dashboard grid KPI + employees cards horizontales.
   16.9 : 2 KPI restants (Ratio H1 + Coût LLM déplacés vers les onglets dédiés) → grille 2 colonnes
   (repeat(4) laissait 2 cartes étriquées à gauche avec un vide à droite). */
.esdi-dashboard-kpi-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-4);
}
@media (max-width: 576px) {
    .esdi-dashboard-kpi-grid { grid-template-columns: 1fr; }
}

.esdi-dashboard-employees-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
    gap: var(--space-4);
}

.esdi-employee-live-card {
    display: grid;
    grid-template-columns: 56px minmax(0, 1fr) auto;
    gap: var(--space-3);
    align-items: start;
    padding: var(--space-4);
    background: var(--bg-card);
    border: 1px solid var(--line);
    border-radius: 12px;
    transition: border-color 0.15s ease, transform 0.15s ease;
    overflow: hidden;
}
.esdi-employee-live-card__content {
    min-width: 0;
    overflow: hidden;
}
.esdi-employee-live-card__content p {
    word-break: break-word;
    overflow-wrap: anywhere;
}
.esdi-employee-live-card__cta {
    align-self: stretch;
    display: flex;
    align-items: center;
}
.esdi-employee-live-card:hover {
    border-color: #3fbecc;
    transform: translateY(-1px);
}
.esdi-employee-live-card__avatar-wrap {
    position: relative;
    width: 56px;
    height: 56px;
}
.esdi-employee-live-card__avatar {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: linear-gradient(135deg, #3fbecc 0%, #1b5aa8 100%);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 22px;
    font-family: var(--font-mono, "Geist Mono", monospace);
}
.esdi-employee-live-card__dot {
    position: absolute;
    top: 2px;
    right: 2px;
    width: 12px;
    height: 12px;
    border: 2px solid var(--bg-card);
    box-sizing: content-box;
}
.esdi-employee-live-card__name {
    color: var(--ink-strong, #0f172a);
}
.esdi-employee-live-card__role {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.esdi-employee-live-card__last-action {
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}
.esdi-employee-live-card__cta a {
    white-space: nowrap;
}

/* Empty state dashboard
   🔴 2026-08-22 — `background: #f8fafc` ÉTAIT EN DUR : en thème sombre, la carte restait BLANCHE et
   son texte gris devenait illisible. Vu à l'écran le jour où la liste des automatisations est
   tombée à zéro — et c'est bien pour ça qu'il n'avait jamais été vu : **un état vide ne s'affiche
   que le jour où quelque chose ne va pas**, c'est-à-dire au pire moment pour être illisible.
   Même famille que le piège déjà noté dans ce dépôt (« dark : #fff en dur → override
   [data-theme=dark] »). On passe par les TOKENS, qui suivent le thème tout seuls. */
.esdi-dashboard-empty {
    text-align: center;
    padding: var(--space-6) var(--space-4);
    background: var(--bg-section-cool, #f8fafc);
    color: var(--ink);
    border: 1px dashed var(--border-faded, #e5e7eb);
    border-radius: 12px;
}

/* --- Nav-tabs in-page (Story 2.5 — UX-DR70 underline style PAS pill) ------------------------------- */
.esdi-nav-tabs {
    display: flex;
    gap: var(--space-6);
    border-bottom: 1px solid var(--line);
    margin-bottom: var(--space-6);
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
}

.esdi-nav-tabs__tab {
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    color: var(--ink-soft);
    padding: var(--space-3) 0;
    margin-bottom: -1px; /* aligne le border-bottom 2px avec le 1px underline parent */
    cursor: pointer;
    font-size: 14px;
    font-weight: 400;
    white-space: nowrap;
    transition: color var(--duration-micro) var(--ease-default),
                border-bottom-color var(--duration-micro) var(--ease-default);
}

.esdi-nav-tabs__tab:hover:not(.esdi-nav-tabs__tab--active) {
    color: var(--primary);
}

.esdi-nav-tabs__tab--active {
    border-bottom-color: var(--primary);
    color: var(--primary);
    font-weight: 500;
}

.esdi-nav-tabs__tab:focus-visible {
    /* outline (pas box-shadow) : résistant au clip de overflow-y:hidden sur .esdi-nav-tabs */
    outline: 2px solid var(--primary);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* --- Empty-state humanisé (UX-DR28 + UX spec ligne 1328) ------------------------------------------- */
.esdi-empty-state {
    padding: var(--space-12) var(--space-6);
    max-width: 480px;
    margin: 0 auto;
}

.esdi-empty-state__icon {
    width: 64px;
    height: 64px;
    color: var(--ink-faded);
    margin-bottom: var(--space-4);
}

/* --- Shell layout helper (sidebar + content side-by-side) ------------------------------------------- */
.esdi-shell-content {
    flex-grow: 1;
    min-width: 0; /* anti flex overflow horizontal */
}

/* --- Btn gradient signature (utilisé sur "Embaucher" + CTAs empty state — UX spec ligne 1260) ------ */
.esdi-btn-gradient {
    background: var(--gradient-brand);
    border: none;
    color: #FFFFFF; /* exception hard-coded sur gradient */
}

.esdi-btn-gradient:hover:not(:disabled):not(.disabled) {
    background: var(--gradient-brand);
    color: #FFFFFF;
    filter: brightness(1.08);
}

.esdi-btn-gradient:focus-visible {
    box-shadow: var(--shadow-focus);
}

/* ====================================================================
   Pages d'authentification — refonte 2026-07-14 (demande Kevin)
   Carte centrée sur fond « aurora » (dégradé signature diffus), champs à icône,
   toggle voir/masquer le mot de passe. Thème-aware (tokens) + responsive.
   Réutilisable login / signup / set-password.
   ==================================================================== */
.esdi-auth {
    position: relative;
    min-height: 100vh;
    min-height: 100dvh;
    display: grid;
    place-items: center;
    padding: 40px 20px;
    overflow: hidden;
    background: var(--bg);
}
/* Halos décoratifs (cyan + bleu) — flous, discrets, ne captent pas les clics */
.esdi-auth::before,
.esdi-auth::after {
    content: "";
    position: absolute;
    border-radius: 50%;
    filter: blur(70px);
    opacity: 0.5;
    pointer-events: none;
    z-index: 0;
}
.esdi-auth::before {
    width: 460px;
    height: 460px;
    top: -160px;
    right: -120px;
    background: radial-gradient(circle, rgba(63, 190, 204, 0.55), transparent 70%);
}
.esdi-auth::after {
    width: 520px;
    height: 520px;
    bottom: -200px;
    left: -140px;
    background: radial-gradient(circle, rgba(27, 90, 168, 0.45), transparent 70%);
}
@media (prefers-reduced-motion: no-preference) {
    .esdi-auth__card { animation: esdi-auth-in 0.5s var(--ease-default) both; }
}
@keyframes esdi-auth-in {
    from { opacity: 0; transform: translateY(14px); }
    to   { opacity: 1; transform: none; }
}

.esdi-auth__card {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 428px;
    background: var(--bg-card);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: 40px 36px 32px;
    overflow: hidden;
}
/* Filet dégradé signature en haut de la carte */
.esdi-auth__card::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 4px;
    background: var(--gradient-brand);
}

.esdi-auth__brand {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin-bottom: 22px;
}
.esdi-auth__brand img { height: 54px; width: auto; }
.esdi-auth__brand span {
    font-size: 1.15rem;
    font-weight: 400;
    color: var(--ink-faded);
    letter-spacing: 0.01em;
}
.esdi-auth__title {
    text-align: center;
    font-size: 1.5rem;
    font-weight: 600;
    color: var(--ink);
    margin: 0 0 4px;
}
.esdi-auth__subtitle {
    text-align: center;
    font-size: 0.875rem;
    color: var(--ink-soft);
    margin: 0 0 26px;
}

.esdi-auth__field { margin-bottom: 16px; }
.esdi-auth__field > .form-label {
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--ink-soft);
    margin-bottom: 6px;
}
.esdi-auth__control { position: relative; }
.esdi-auth__control > .esdi-auth__icon {
    position: absolute;
    left: 14px;
    top: 50%;
    transform: translateY(-50%);
    width: 18px;
    height: 18px;
    color: var(--ink-faded);
    pointer-events: none;
}
.esdi-auth__control > .form-control {
    height: 48px;
    padding-left: 42px;
    border-radius: var(--radius-sm);
    border-color: var(--line);
    background: var(--bg);
    color: var(--ink);
    transition: border-color var(--duration-micro) var(--ease-default),
                box-shadow var(--duration-micro) var(--ease-default);
}
.esdi-auth__control > .form-control::placeholder { color: var(--ink-faded); }
.esdi-auth__control > .form-control:focus {
    border-color: var(--accent);
    box-shadow: var(--shadow-focus);
    background: var(--bg-card);
}
/* champ mot de passe : place pour le bouton œil */
.esdi-auth__control--password > .form-control { padding-right: 44px; }
.esdi-auth__toggle {
    position: absolute;
    right: 6px;
    top: 50%;
    transform: translateY(-50%);
    border: 0;
    background: transparent;
    color: var(--ink-faded);
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-xs);
    cursor: pointer;
    transition: color var(--duration-micro), background var(--duration-micro);
}
.esdi-auth__toggle:hover { color: var(--accent); background: var(--bg-section-cool); }
.esdi-auth__toggle svg { width: 18px; height: 18px; }

.esdi-auth__submit {
    height: 48px;
    font-weight: 600;
    font-size: 0.95rem;
    border-radius: var(--radius-sm);
    margin-top: 6px;
}
.esdi-auth__footer {
    text-align: center;
    margin-top: 22px;
    padding-top: 18px;
    border-top: 1px solid var(--line);
}
.esdi-auth__footer .small { color: var(--ink-faded); }

@media (max-width: 575.98px) {
    .esdi-auth__card { padding: 32px 22px 26px; }
    .esdi-auth::before, .esdi-auth::after { opacity: 0.35; }
}

/* ====================================================================
   Story 2.6 — Wizard Settings Company Profile
   Stepper progress horizontal/vertical + form sections + chip input
   + radio group + multi-select + toast feedback + collaborateurs repeater
   ==================================================================== */

/* --- Stepper progress bar (Décision #3) --- */
.esdi-wizard-stepper {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-2);
    position: relative;
    margin-bottom: var(--space-8);
    padding: 0;
    list-style: none;
}

/* Ligne connectrice horizontale entre steps (desktop) */
.esdi-wizard-stepper::before {
    content: '';
    position: absolute;
    top: 16px;
    left: 16px;
    right: 16px;
    height: 2px;
    background-color: var(--line);
    z-index: 0;
}

.esdi-wizard-step {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    background: transparent;
    border: none;
    padding: 0;
    cursor: pointer;
    flex: 1;
    min-width: 0;
    transition: opacity 200ms ease;
}

.esdi-wizard-step:focus-visible {
    outline: none;
}

.esdi-wizard-step:focus-visible .esdi-wizard-step__number {
    box-shadow: var(--shadow-focus);
}

.esdi-wizard-step__number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background-color: var(--bg-card);
    border: 2px solid var(--line);
    color: var(--ink-soft);
    font-weight: 600;
    font-size: 14px;
    transition: background-color 200ms ease, border-color 200ms ease, color 200ms ease;
}

.esdi-wizard-step__label {
    font-size: 13px;
    color: var(--ink-soft);
    text-align: center;
    line-height: 1.3;
    transition: color 200ms ease;
}

/* Active state */
.esdi-wizard-step--active .esdi-wizard-step__number {
    background-color: var(--primary);
    border-color: var(--primary);
    color: #FFFFFF;
}

.esdi-wizard-step--active .esdi-wizard-step__label {
    color: var(--primary);
    font-weight: 600;
}

/* Done state (checkmark) */
.esdi-wizard-step--done .esdi-wizard-step__number {
    background-color: var(--sig-ok-bg);
    border-color: var(--sig-ok);
    color: var(--sig-ok);
}

.esdi-wizard-step--done .esdi-wizard-step__number::after {
    content: '✓';
    position: absolute;
    color: var(--sig-ok);
    font-weight: 700;
    font-size: 16px;
}

.esdi-wizard-step--done .esdi-wizard-step__number > * {
    display: none; /* masque le chiffre, le ✓ prend sa place */
}

.esdi-wizard-step--done .esdi-wizard-step__label {
    color: var(--sig-ok-text);
}

/* Mobile : stepper compact (numéros visibles, labels masqués <576px) */
@media (max-width: 575.98px) {
    .esdi-wizard-stepper {
        gap: var(--space-1);
    }

    .esdi-wizard-step__label {
        font-size: 11px;
    }

    /* Affiche le label uniquement sur step actif (UX spec mobile-first) */
    .esdi-wizard-step:not(.esdi-wizard-step--active) .esdi-wizard-step__label {
        display: none;
    }
}

/* --- Form sections --- */
.esdi-form-section {
    padding: var(--space-6) var(--space-8);
    background-color: var(--bg-section-cool);
    border-radius: var(--radius-md);
    border: 1px solid var(--line);
    margin-bottom: var(--space-6);
}

@media (max-width: 767.98px) {
    .esdi-form-section {
        padding: var(--space-4);
    }
}

.esdi-form-section__header {
    margin-bottom: var(--space-5);
    padding-bottom: var(--space-4);
    border-bottom: 1px solid var(--line);
}

.esdi-form-group {
    margin-bottom: var(--space-4);
}

.esdi-form-group label {
    display: block;
    font-weight: 500;
    font-size: 14px;
    color: var(--ink);
    margin-bottom: var(--space-2);
}

/* --- Chip input (vocabulaire métier Screen 2) --- */
.esdi-chip-input {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.esdi-chip-input__chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    padding: var(--space-2);
    background-color: var(--bg-card);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    min-height: 44px;
}

.esdi-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-3);
    background-color: var(--sig-ai-bg);
    color: var(--sig-ai-text);
    border-radius: var(--radius-pill);
    font-size: 13px;
    font-weight: 500;
}

.esdi-chip__remove {
    background: transparent;
    border: none;
    color: var(--sig-ai-text);
    cursor: pointer;
    font-size: 18px;
    line-height: 1;
    padding: 0 var(--space-1);
    border-radius: 50%;
    width: 20px;
    height: 20px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.esdi-chip__remove:hover {
    background-color: rgba(31, 103, 114, 0.15);
}

.esdi-chip-input__add {
    display: flex;
    gap: var(--space-2);
    align-items: center;
}

.esdi-chip-input__add .form-control {
    flex: 1;
}

/* --- Radio group (volume_clients Screen 3) --- */
.esdi-radio-group {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

@media (min-width: 768px) {
    .esdi-radio-group {
        flex-direction: row;
        flex-wrap: wrap;
        gap: var(--space-3);
    }
}

.esdi-radio-group__option {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    background-color: var(--bg-card);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-weight: 500;
    transition: border-color 150ms ease, background-color 150ms ease;
    min-height: 44px; /* WCAG touch target */
}

.esdi-radio-group__option:hover {
    border-color: var(--primary-300);
}

.esdi-radio-group__option input[type="radio"] {
    margin: 0;
    accent-color: var(--primary);
}

.esdi-radio-group__option:has(input[type="radio"]:checked) {
    background-color: var(--primary-50);
    border-color: var(--primary);
}

/* --- Multi-select (canal_prefere Screen 3) --- */
.esdi-multi-select {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.esdi-multi-select__option {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background-color: var(--bg-card);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-weight: 500;
    transition: border-color 150ms ease, background-color 150ms ease;
    min-height: 44px;
}

.esdi-multi-select__option:hover {
    border-color: var(--primary-300);
}

.esdi-multi-select__option input[type="checkbox"] {
    margin: 0;
    accent-color: var(--primary);
}

.esdi-multi-select__option:has(input[type="checkbox"]:checked) {
    background-color: var(--primary-50);
    border-color: var(--primary);
}

/* --- Wizard actions (boutons Continuer/Précédent/Terminer) --- */
.esdi-wizard-actions {
    display: flex;
    justify-content: space-between;
    gap: var(--space-3);
    margin-top: var(--space-6);
    padding-top: var(--space-5);
    border-top: 1px solid var(--line);
}

.esdi-wizard-actions > :only-child {
    margin-left: auto;
}

@media (max-width: 575.98px) {
    .esdi-wizard-actions {
        flex-direction: column-reverse;
    }
    .esdi-wizard-actions > * {
        width: 100%;
    }
}

/* --- Collaborateurs repeater (Screen 4) --- */
.esdi-collab-list {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.esdi-collab-item {
    padding: var(--space-3);
    background-color: var(--bg-card);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
}

.esdi-collab-item .esdi-form-group {
    margin-bottom: 0;
}

/* --- Toast feedback (pattern Story 2.3 P12 retro) --- */
.esdi-toast {
    position: fixed;
    top: var(--space-6);
    right: var(--space-6);
    z-index: 1080; /* au-dessus de Bootstrap modal z-index */
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-md);
    max-width: 480px;
    animation: esdiToastSlideIn 200ms ease-out;
    font-size: 14px;
    font-weight: 500;
}

@media (max-width: 767.98px) {
    .esdi-toast {
        top: auto;
        bottom: var(--space-6);
        right: var(--space-4);
        left: var(--space-4);
        max-width: none;
    }
}

@keyframes esdiToastSlideIn {
    from {
        opacity: 0;
        transform: translateY(-8px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.esdi-toast i {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
}

.esdi-toast--success {
    background-color: var(--sig-ok-bg);
    border-left: 4px solid var(--sig-ok);
    color: var(--sig-ok-text);
}

.esdi-toast--error {
    background-color: var(--sig-alert-bg);
    border-left: 4px solid var(--sig-alert);
    color: var(--sig-alert-text);
}

/* prefers-reduced-motion : désactive l'animation toast */
@media (prefers-reduced-motion: reduce) {
    .esdi-toast {
        animation: none;
    }
    .esdi-wizard-step,
    .esdi-wizard-step__number,
    .esdi-wizard-step__label,
    .esdi-radio-group__option,
    .esdi-multi-select__option {
        transition: none;
    }
}

/* ============================================================================
 * Story 3.2 — UI Settings LLM (presets cards + form 3 fields + accordion + result panel)
 * UX-DR15 + UX-DR57 + UX-DR74 + UX-DR127 (progressive disclosure)
 * ============================================================================ */

/* -- Section 1 : Preset cards grid (5 cards, responsive) -- */
.esdi-preset-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
}

.esdi-preset-card {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
    padding: 20px;
    background: var(--bg, #fff);
    border: 2px solid var(--border, #e5e7eb);
    border-radius: 12px;
    cursor: pointer;
    transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
    text-align: left;
}

.esdi-preset-card:hover {
    border-color: var(--cyan-esdi, #3fbecc);
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(63, 190, 204, 0.15);
}

.esdi-preset-card:focus-visible {
    outline: 2px solid var(--cyan-esdi, #3fbecc);
    outline-offset: 2px;
}

.esdi-preset-card--selected {
    border-color: var(--cyan-esdi, #3fbecc);
    background: linear-gradient(135deg, rgba(63, 190, 204, 0.05) 0%, rgba(27, 90, 168, 0.05) 100%);
    box-shadow: 0 0 0 4px rgba(63, 190, 204, 0.1);
}

.esdi-preset-card__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    background: rgba(63, 190, 204, 0.08);
    border-radius: 10px;
}

.esdi-preset-card--selected .esdi-preset-card__icon {
    background: rgba(63, 190, 204, 0.15);
}

.esdi-preset-card__name {
    margin: 0;
    font-size: 16px;
    font-weight: 600;
    color: var(--text, #111827);
}

.esdi-preset-card__tagline {
    margin: 0;
    font-size: 13px;
    color: var(--text-muted, #6b7280);
    line-height: 1.4;
}

/* -- Section 2 : Form 3 fields (controlled inputs) -- */
.esdi-llm-form {
    max-width: 700px;
}

/* Cards readonly visual cue */
.esdi-llm-form input[readonly] {
    background-color: var(--bg-muted, #f9fafb);
    cursor: not-allowed;
}

/* -- Accordion Avancé (UX-DR127 progressive disclosure) -- */
.esdi-llm-advanced-accordion {
    padding: 16px 0;
    border-top: 1px solid var(--border, #e5e7eb);
}

.esdi-llm-advanced-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    background: none;
    border: none;
    padding: 0;
    font-size: 14px;
    font-weight: 500;
    color: var(--text-muted, #6b7280);
    cursor: pointer;
    transition: color 0.15s ease;
}

.esdi-llm-advanced-toggle:hover {
    color: var(--cyan-esdi, #3fbecc);
}

.esdi-llm-advanced-toggle:focus-visible {
    outline: 2px solid var(--cyan-esdi, #3fbecc);
    outline-offset: 2px;
    border-radius: 4px;
}

.esdi-llm-advanced-content {
    padding-left: 24px;
    border-left: 2px solid var(--border, #e5e7eb);
}

/* -- Test result panel (success / error) -- */
.esdi-llm-test-result {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 16px;
    border-radius: 10px;
    border-left: 4px solid;
}

.esdi-llm-test-result strong {
    display: block;
    font-size: 15px;
    margin-bottom: 4px;
}

.esdi-llm-test-result--success {
    background: rgba(34, 197, 94, 0.06);
    border-left-color: var(--success, #22c55e);
    color: var(--success-text, #15803d);
}

.esdi-llm-test-result--success i {
    color: var(--success, #22c55e);
    flex-shrink: 0;
    margin-top: 2px;
}

.esdi-llm-test-result--error {
    background: rgba(239, 68, 68, 0.06);
    border-left-color: var(--danger, #ef4444);
    color: var(--danger-text, #b91c1c);
}

.esdi-llm-test-result--error i {
    color: var(--danger, #ef4444);
    flex-shrink: 0;
    margin-top: 2px;
}

.esdi-llm-test-result code {
    background: rgba(0, 0, 0, 0.04);
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 12px;
}

.esdi-llm-test-result details summary {
    cursor: pointer;
    color: var(--text-muted, #6b7280);
}

/* -- Actions (Test + Save buttons) -- */
.esdi-llm-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    align-items: flex-start;
}

.esdi-llm-actions form {
    margin: 0;
}

/* Responsive : mobile stack actions vertical */
@media (max-width: 640px) {
    .esdi-llm-actions {
        flex-direction: column;
        align-items: stretch;
    }
    .esdi-llm-actions form,
    .esdi-llm-actions button {
        width: 100%;
    }
}

/* prefers-reduced-motion : disable preset card hover transform + transitions */
@media (prefers-reduced-motion: reduce) {
    .esdi-preset-card,
    .esdi-llm-advanced-toggle {
        transition: none;
    }
    .esdi-preset-card:hover {
        transform: none;
    }
}

/* ============================================================================
 * Story 3.2 — UI Modal contextualisée provider (P4 Kevin demande)
 * Pattern <dmx-value>+dmx-show overlay (PAS Bootstrap modal natif Antipattern #17)
 * ============================================================================ */

.esdi-modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    background: rgba(0, 0, 0, 0.5);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    z-index: 1050;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    animation: esdi-modal-fade-in 0.18s ease-out;
}

@keyframes esdi-modal-fade-in {
    from { opacity: 0; }
    to { opacity: 1; }
}

.esdi-modal {
    background: #fff;
    border-radius: 16px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
    max-width: 680px;
    width: 100%;
    max-height: 90vh;
    min-height: 0; /* P6 fix : permet aux enfants flex de se réduire correctement */
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: esdi-modal-slide-in 0.22s cubic-bezier(0.16, 1, 0.3, 1);
}

/* P6 fix : le form englobant (formTest) doit aussi être flex column pour propager le layout
   header → body (scroll) → footer aux enfants modal__* */
.esdi-modal > form {
    display: flex;
    flex-direction: column;
    min-height: 0;
    flex: 1 1 auto;
    overflow: hidden;
}

@keyframes esdi-modal-slide-in {
    from {
        opacity: 0;
        transform: translateY(20px) scale(0.97);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.esdi-modal__header {
    display: flex;
    align-items: flex-start;
    gap: 16px;
    padding: 24px 28px 20px;
    border-bottom: 1px solid var(--border, #e5e7eb);
    flex-shrink: 0; /* P6 fix : empêche le header d'être squeezed quand body grandit */
}

.esdi-modal__title-wrap {
    flex-grow: 1;
}

.esdi-modal__title {
    margin: 0 0 6px 0;
    font-size: 20px;
    font-weight: 600;
    color: var(--text, #111827);
}
.esdi-modal__title svg { width: 19px; height: 19px; vertical-align: -3px; margin-right: 7px; color: var(--cyan-esdi, #3fbecc); }

.esdi-modal__subtitle {
    margin: 0;
    font-size: 13px;
    color: var(--text-muted, #6b7280);
    line-height: 1.5;
}

.esdi-modal__subtitle em {
    color: var(--cyan-esdi, #3fbecc);
    font-style: normal;
    font-weight: 500;
}

.esdi-modal__close {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    margin: 0;
    border: none;
    border-radius: 9px;
    background: transparent;
    color: var(--text-muted, #6b7280);
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease;
}
.esdi-modal__close:hover { background: var(--bg-muted, #f1f5f9); color: var(--text, #111827); }
.esdi-modal__close > svg { width: 18px; height: 18px; }

.esdi-modal__body {
    padding: 24px 28px;
    overflow-y: auto;
    flex: 1 1 auto;
    min-height: 0; /* P6 fix : Flexbox gotcha — sans min-height:0, body refuse de scroller et pousse footer hors modal */
}

.esdi-modal__footer {
    display: flex;
    gap: 12px;
    justify-content: flex-end;
    align-items: center;
    padding: 18px 28px;
    border-top: 1px solid var(--border, #e5e7eb);
    background: var(--bg-muted, #f9fafb);
    flex-shrink: 0; /* P6 fix : empêche le footer d'être poussé hors modal quand body grandit (test result panel ajoute hauteur) */
}

/* Mobile : full-screen modal */
@media (max-width: 640px) {
    .esdi-modal-overlay {
        padding: 0;
    }
    .esdi-modal {
        max-width: 100%;
        max-height: 100vh;
        border-radius: 0;
        height: 100vh;
    }
    .esdi-modal__footer {
        flex-direction: column-reverse;
        align-items: stretch;
    }
    .esdi-modal__footer button {
        width: 100%;
    }
}

@media (prefers-reduced-motion: reduce) {
    .esdi-modal-overlay,
    .esdi-modal {
        animation: none;
    }
}

/* ============================================================================
   Story 3.3 — Dashboard LLM usage (KPI cards UX-DR20 + alert banner + skeleton)
   ============================================================================ */

/* --- KPI cards (pattern GMAIA OverviewPage / Stripe Dashboard) --------------- */
.esdi-kpi-card {
    padding: 1.5rem;
    border-radius: 12px;
    background: var(--bg-card);
    border: 1px solid var(--line);
    transition: transform 220ms cubic-bezier(0.16, 1, 0.3, 1),
                box-shadow 220ms cubic-bezier(0.16, 1, 0.3, 1);
    height: 100%;
}

.esdi-kpi-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
}

.esdi-kpi-card__label {
    margin-bottom: 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

.esdi-kpi-card__value {
    font-weight: 700;
    line-height: 1.1;
    color: var(--ink, #1f2937);
}

.esdi-kpi-card__hint {
    color: var(--ink-faded, #6b7280);
}

/* Pastel variants par catégorie (cohérent UX-DR Stripe-style) */
.esdi-kpi-card--blue {
    background: linear-gradient(135deg, #eff6ff 0%, #ffffff 60%);
    border-color: #dbeafe;
}

.esdi-kpi-card--cyan {
    background: linear-gradient(135deg, #ecfeff 0%, #ffffff 60%);
    border-color: #cffafe;
}

.esdi-kpi-card--green {
    background: linear-gradient(135deg, #f0fdf4 0%, #ffffff 60%);
    border-color: #dcfce7;
}

.esdi-kpi-card--green .esdi-kpi-card__value {
    color: #15803d;
}

.esdi-kpi-card--orange {
    background: linear-gradient(135deg, #fff7ed 0%, #ffffff 60%);
    border-color: #fed7aa;
}

.esdi-kpi-card--orange .esdi-kpi-card__value {
    color: #c2410c;
}

.esdi-kpi-card--red {
    background: linear-gradient(135deg, #fef2f2 0%, #ffffff 60%);
    border-color: #fecaca;
}

.esdi-kpi-card--red .esdi-kpi-card__value {
    color: #b91c1c;
}

/* --- Tabular-nums utility (Geist Mono numeric alignment) -------------------- */
.tabular-nums {
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum';
}

/* --- Cost alert banner (Décision #5 Story 3.3 — V1 toast UI uniquement) ----- */
.esdi-cost-alert-banner {
    background: linear-gradient(135deg, #fff7ed 0%, #ffedd5 100%);
    border-left: 4px solid #f59e0b;
    border-radius: 8px;
    padding: 1rem 1.25rem;
    color: var(--ink, #1f2937);
}

.esdi-cost-alert-banner h6 {
    color: #92400e;
}

.esdi-cost-alert-banner code {
    background: rgba(255, 255, 255, 0.6);
    padding: 0.05rem 0.35rem;
    border-radius: 4px;
    font-size: 0.875em;
    color: #92400e;
}

/* --- Skeleton shimmer (loading state Story 3.3) ----------------------------- */
.esdi-skeleton {
    background: linear-gradient(
        90deg,
        #f3f4f6 0%,
        #e5e7eb 50%,
        #f3f4f6 100%
    );
    background-size: 200% 100%;
    animation: esdi-skeleton-shimmer 1.5s ease-in-out infinite;
    border: 1px solid #f3f4f6;
}

@keyframes esdi-skeleton-shimmer {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

@media (prefers-reduced-motion: reduce) {
    .esdi-skeleton {
        animation: none;
    }
}

/* --- Timeseries placeholder bars (V1 simple histogram, Chart.js V1.5) ------- */
.esdi-timeseries-bar {
    width: 24px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    cursor: help;
}

.esdi-timeseries-bar__fill {
    width: 100%;
    background: linear-gradient(180deg, var(--accent, #06b6d4) 0%, var(--accent-soft, #67e8f9) 100%);
    border-radius: 2px 2px 0 0;
    transition: opacity 220ms;
}

.esdi-timeseries-bar:hover .esdi-timeseries-bar__fill {
    opacity: 0.85;
}

.esdi-timeseries-bar__label {
    font-variant-numeric: tabular-nums;
    font-size: 10px;
}

/* ============================================================
   Story 5.5 — Validation cards (FR40 propose-valide UI)
   ============================================================ */

.esdi-validation-card {
    background: #fff;
    border: 1px solid var(--border-soft, #e5e7eb);
    border-radius: 12px;
    padding: 16px 18px;
    transition: box-shadow 220ms cubic-bezier(0.16, 1, 0.3, 1);
}

.esdi-validation-card:hover {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}

.esdi-validation-textarea {
    font-family: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 13px;
    line-height: 1.5;
    resize: vertical;
    min-height: 160px;
    background: #fafbfc;
}

.esdi-validation-textarea:focus {
    background: #fff;
}

.esdi-clamp-3 {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 1.5;
}

.esdi-badge-count {
    background: var(--primary, #0f172a);
    color: #fff;
    padding: 6px 12px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.esdi-info-banner {
    background: rgba(249, 250, 251, 0.6);
    border: 1px dashed var(--border-soft, #e5e7eb);
    border-radius: 8px;
    padding: 10px 14px;
}

.esdi-info-banner [data-lucide] {
    color: var(--accent, #06b6d4);
    vertical-align: -2px;
}

/* =========================================================================
   Page /chat — REFONTE 2026-07-14 (ex Story 7.2, demande Kevin)
   Layout grid : RAIL compact 68px (avatars) + 1fr thread+input.
   - Desktop : le rail s'étend au survol en OVERLAY 288px (zéro reflow du fil)
     et peut être ÉPINGLÉ ouvert (classe .is-pinned, persistée localStorage).
   - Mobile (<768px) : le panneau devient un TIROIR off-canvas + backdrop
     (ouvert par le bouton du header du fil) — fini le bloc 40vh.
   ========================================================================= */

.esdi-chat-grid {
    display: grid;
    grid-template-columns: auto 1fr;
    height: calc(100vh - var(--topbar-height, 64px));
    height: calc(100dvh - var(--topbar-height, 64px)); /* mobile : barre d'URL dynamique */
    min-height: 480px;
    background: var(--bg);
    overflow: hidden;
}

/* ----- Zone 1 : panneau conversations (rail compact) ----- */
.esdi-chat-sidebar {
    position: relative;
    width: 68px;
    z-index: 60; /* l'overlay au survol passe au-dessus du fil */
}
.esdi-chat-sidebar.is-pinned { width: 288px; }

.esdi-chat-sidebar__panel {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 68px;
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    overflow-x: hidden;
    background: var(--bg-card, var(--bg));
    border-right: 1px solid var(--line);
    padding: 12px 10px;
    transition: width 0.2s cubic-bezier(0.2, 0.7, 0.3, 1), box-shadow 0.2s ease;
    scrollbar-width: thin;
}

@media (min-width: 768px) {
    .esdi-chat-sidebar.is-pinned .esdi-chat-sidebar__panel,
    .esdi-chat-sidebar:hover .esdi-chat-sidebar__panel,
    .esdi-chat-sidebar:focus-within .esdi-chat-sidebar__panel {
        width: 288px;
    }
    /* expansion au survol NON épinglée = overlay avec ombre portée */
    .esdi-chat-sidebar:not(.is-pinned):hover .esdi-chat-sidebar__panel,
    .esdi-chat-sidebar:not(.is-pinned):focus-within .esdi-chat-sidebar__panel {
        box-shadow: 10px 0 30px rgba(15, 23, 42, 0.14);
    }
    /* en rail : pas de scrollbar visible (elle décentre les avatars) */
    .esdi-chat-sidebar:not(.is-pinned):not(:hover):not(:focus-within) .esdi-chat-sidebar__panel {
        overflow-y: hidden;
    }
}

/* Libellés texte : invisibles en rail (opacity ET largeur 0 — sinon le texte caché
   décentre l'icône des boutons centrés), fondu à l'expansion */
.esdi-chat-sidebar__label {
    opacity: 0;
    max-width: 0;
    overflow: hidden;
    white-space: nowrap;
    transition: opacity 0.16s ease 0.05s, max-width 0.2s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.esdi-chat-sidebar.is-pinned .esdi-chat-sidebar__label,
.esdi-chat-sidebar:hover .esdi-chat-sidebar__label,
.esdi-chat-sidebar:focus-within .esdi-chat-sidebar__label,
.esdi-chat-sidebar.is-open .esdi-chat-sidebar__label {
    opacity: 1;
    max-width: 210px;
}

/* Tête du panneau : bouton « Nouvelle conversation » + épingle (desktop) / croix (mobile) */
.esdi-chat-sidebar__head {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 14px;
    flex-shrink: 0;
}
.esdi-chat-new-btn {
    flex: 1 1 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
    overflow: hidden;
    min-width: 0;
    height: 36px;
    padding-left: 8px;  /* le padding 20px du .esdi-btn-gradient écrasait l'icône (width 0) en rail */
    padding-right: 8px;
}
.esdi-chat-new-btn svg,
.esdi-chat-new-btn [data-lucide] { flex-shrink: 0; }
.esdi-chat-sidebar__pin {
    flex: 0 0 auto;
    width: 0;
    height: 32px;
    padding: 0;
    border: 0;
    overflow: hidden;
    opacity: 0;
    background: transparent;
    color: var(--ink-faded, #6b7280);
    border-radius: 8px;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: opacity 0.16s ease 0.05s, background 0.15s ease, color 0.15s ease;
}
.esdi-chat-sidebar.is-pinned .esdi-chat-sidebar__pin,
.esdi-chat-sidebar:hover .esdi-chat-sidebar__pin,
.esdi-chat-sidebar:focus-within .esdi-chat-sidebar__pin {
    width: 30px;
    opacity: 1;
}
.esdi-chat-sidebar__pin:hover { background: rgba(63, 190, 204, 0.12); color: var(--primary, #1b5aa8); }
.esdi-chat-sidebar.is-pinned .esdi-chat-sidebar__pin { color: var(--accent, #3fbecc); }
.esdi-chat-sidebar.is-pinned .esdi-chat-sidebar__pin svg { transform: rotate(45deg); }
.esdi-chat-sidebar__closebtn {
    flex: 0 0 auto;
    border: 0;
    background: transparent;
    color: var(--ink-faded, #6b7280);
    padding: 5px;
    border-radius: 8px;
    line-height: 0;
    cursor: pointer;
}
.esdi-chat-sidebar__closebtn:hover { background: rgba(0, 0, 0, 0.06); color: var(--ink); }

/* Interlocuteurs */
.esdi-chat-interlocutor { margin-bottom: 14px; flex-shrink: 0; }
.esdi-chat-interlocutor__list {
    display: flex;
    flex-direction: column;
    gap: 3px;
}
.esdi-chat-interlocutor__item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    border: 0;
    background: transparent;
    padding: 5px 6px;
    border-radius: 10px;
    cursor: pointer;
    font-size: 0.9rem;
    text-align: left;
    color: var(--ink, inherit);
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    transition: background 0.15s ease;
}
.esdi-chat-interlocutor__item:hover { background: rgba(63, 190, 204, 0.10); }
.esdi-chat-interlocutor__item--active { background: rgba(63, 190, 204, 0.16); font-weight: 600; }
.esdi-chat-interlocutor__item .esdi-chat-sidebar__avatar { width: 34px; height: 34px; font-size: 13px; }
/* en rail, l'interlocuteur actif reste repérable : anneau cyan autour de l'avatar */
.esdi-chat-interlocutor__item--active .esdi-chat-sidebar__avatar {
    box-shadow: 0 0 0 2px var(--bg-card, #fff), 0 0 0 4px var(--accent, #3fbecc);
}

/* Historique : invisible en rail (fondu à l'expansion), lignes pleine largeur (bleed) */
.esdi-chat-history {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    margin: 0 -10px;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.16s ease 0.06s;
}
.esdi-chat-sidebar.is-pinned .esdi-chat-history,
.esdi-chat-sidebar:hover .esdi-chat-history,
.esdi-chat-sidebar:focus-within .esdi-chat-history,
.esdi-chat-sidebar.is-open .esdi-chat-history {
    opacity: 1;
    pointer-events: auto;
}
.esdi-chat-history > label { padding: 0 16px; }
.esdi-chat-history__item { cursor: pointer; position: relative; }
.esdi-chat-history__actions { display: none; gap: 2px; margin-left: auto; align-items: center; }
.esdi-chat-history__item:hover .esdi-chat-history__actions { display: flex; }
.esdi-chat-history__act {
    border: 0;
    background: transparent;
    cursor: pointer;
    padding: 2px 5px;
    border-radius: 6px;
    font-size: 0.8rem;
    opacity: 0.55;
    line-height: 1;
}
.esdi-chat-history__act:hover { opacity: 1; background: rgba(0, 0, 0, 0.10); }

.esdi-chat-sidebar__list {
    list-style: none;
    padding: 6px 0;
    margin: 0;
    flex-grow: 1;
}

.esdi-chat-sidebar__item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 9px 16px;
    cursor: pointer;
    border-left: 3px solid transparent;
    transition: background 0.15s, border-color 0.15s;
}

.esdi-chat-sidebar__item:hover {
    background: rgba(63, 190, 204, 0.05);
}

.esdi-chat-sidebar__item--active {
    background: rgba(63, 190, 204, 0.1);
    border-left-color: var(--accent, #3fbecc);
}

/* Tiroir mobile + backdrop */
@media (max-width: 767.98px) {
    .esdi-chat-grid { grid-template-columns: 1fr; }
    .esdi-chat-sidebar {
        position: fixed;
        top: var(--topbar-height, 64px);
        bottom: 0;
        left: 0;
        width: min(320px, 88vw);
        transform: translateX(-106%);
        transition: transform 0.24s cubic-bezier(0.2, 0.7, 0.3, 1);
        z-index: 1041;
    }
    .esdi-chat-sidebar.is-open {
        transform: none;
        box-shadow: 14px 0 34px rgba(15, 23, 42, 0.28);
    }
    .esdi-chat-sidebar__panel {
        position: static;
        width: 100% !important;
        height: 100%;
        box-shadow: none !important;
    }
    .esdi-chat-sidebar .esdi-chat-sidebar__label { opacity: 1; }
    .esdi-chat-sidebar .esdi-chat-history { opacity: 1; pointer-events: auto; }
    .esdi-chat-sidebar__pin { display: none !important; }
}
.esdi-chat-sidebar-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(15, 23, 42, 0.45);
    z-index: 1040;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease, visibility 0.2s;
}
.esdi-chat-sidebar-backdrop.is-visible { opacity: 1; visibility: visible; }

.esdi-chat-sidebar__avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--accent, #3fbecc) 0%, var(--primary, #1b5aa8) 100%);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 14px;
    flex-shrink: 0;
}

.esdi-chat-sidebar__avatar--manager {
    background: linear-gradient(135deg, #6b7280 0%, #1f2937 100%);
}

.esdi-chat-sidebar__meta {
    flex-grow: 1;
    min-width: 0;
}

.esdi-chat-sidebar__name {
    margin: 0;
    font-size: 14px;
    font-weight: 500;
    color: var(--ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.esdi-chat-sidebar__role {
    margin: 0;
    font-size: 12px;
    color: var(--ink-faded, #6b7280);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.esdi-chat-sidebar__empty {
    padding: 16px;
    text-align: center;
    border-top: 1px solid var(--line);
}

/* ----- Zone 2+3 : main thread + input ----- */
.esdi-chat-main {
    display: flex;
    flex-direction: column;
    min-height: 0; /* allow flex children to scroll */
    /* Épique 28 : ancre du voile de dépôt (`.esdi-chat-drop`, en position absolue). Sans cette ligne, le
       voile se rattacherait au premier ancêtre positionné — c'est-à-dire au document — et couvrirait la
       page entière, sidebar comprise. */
    position: relative;
}

/* (Chips « Digest du jour » supprimées — refonte 2026-07-14, bandeau retiré de la page.) */

.esdi-chat-main__header {
    padding: 12px 20px;
    border-bottom: 1px solid var(--line);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    background: var(--bg);
    flex-shrink: 0;
}

.esdi-chat-thread {
    flex-grow: 1;
    overflow-y: auto;
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 16px;
    background: var(--bg);
}

.esdi-chat-thread__empty {
    margin: auto;
    text-align: center;
    padding: 32px;
    color: var(--ink-faded, #6b7280);
}

/* ----- Bubbles ----- */
.esdi-chat-bubble {
    display: flex;
    gap: 10px;
    max-width: 78%;
    align-items: flex-start;
    min-width: 0; /* fix débordement : autorise la compression des contenus insécables */
    animation: esdi-bubble-in 0.26s cubic-bezier(0.2, 0.7, 0.3, 1) both;
}

/* Apparition douce des messages (envoi + réception) — refonte 2026-07-14 */
@keyframes esdi-bubble-in {
    from { opacity: 0; transform: translateY(10px) scale(0.985); }
    to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .esdi-chat-bubble { animation: none; }
}

.esdi-chat-bubble--user {
    margin-left: auto;
    flex-direction: row-reverse;
}

.esdi-chat-bubble--assistant,
.esdi-chat-bubble--tool,
.esdi-chat-bubble--system {
    margin-right: auto;
}

.esdi-chat-bubble__avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--accent, #3fbecc) 0%, var(--primary, #1b5aa8) 100%);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 13px;
    flex-shrink: 0;
}

.esdi-chat-bubble--user .esdi-chat-bubble__avatar {
    background: linear-gradient(135deg, #4b5563 0%, #1f2937 100%);
}

.esdi-chat-bubble--tool .esdi-chat-bubble__avatar {
    background: #f59e0b;
}

.esdi-chat-bubble--system .esdi-chat-bubble__avatar {
    background: #9ca3af;
}

.esdi-chat-bubble__body {
    flex-grow: 1;
    background: var(--bg-section-warm, #f9fafb);
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 10px 14px;
    min-width: 0;
}

.esdi-chat-bubble--user .esdi-chat-bubble__body {
    background: linear-gradient(135deg, rgba(63, 190, 204, 0.12) 0%, rgba(27, 90, 168, 0.08) 100%);
    border-color: rgba(63, 190, 204, 0.3);
}

.esdi-chat-bubble--tool .esdi-chat-bubble__body {
    background: rgba(245, 158, 11, 0.05);
    border-color: rgba(245, 158, 11, 0.3);
    font-family: var(--font-mono, ui-monospace, "Geist Mono", monospace);
    font-size: 13px;
}

.esdi-chat-bubble__content {
    white-space: pre-wrap;
    overflow-wrap: anywhere; /* fix : les longues chaînes insécables (URL, commandes) ne sortent plus de la bulle/l'écran */
    word-break: break-word;
    line-height: 1.5;
    color: var(--ink);
    max-width: 100%;
}

/* Repli des messages très longs (refonte 2026-07-14) : classe posée par esdiEnhanceBubbles().
   Le fondu bas utilise un mask (indépendant du fond de la bulle → OK user/assistant/tool + dark). */
.esdi-chat-bubble__content.esdi-clamp.is-clamped {
    max-height: 300px;
    overflow: hidden;
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 72px), transparent);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 72px), transparent);
}
.esdi-chat-expand {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-top: 6px;
    padding: 3px 10px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--bg, #fff);
    color: var(--primary, #1b5aa8);
    font-size: 11.5px;
    font-weight: 600;
    line-height: 1.5;
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
}
.esdi-chat-expand:hover {
    border-color: var(--accent, #3fbecc);
    background: rgba(63, 190, 204, 0.08);
}

/* Horodatage discret des bulles (refonte 2026-07-14) */
.esdi-chat-bubble__time {
    margin-top: 4px;
    font-family: var(--font-mono, "Geist Mono", monospace);
    font-size: 9.5px;
    letter-spacing: 0.04em;
    color: var(--ink-faded, #9ca3af);
    opacity: 0.7;
    text-align: right;
    user-select: none;
}

.esdi-chat-bubble__tool-calls {
    margin-top: 8px;
}

.esdi-chat-bubble__tool-call {
    background: rgba(0, 0, 0, 0.03);
    border-radius: 8px;
    padding: 6px 10px;
    margin-top: 4px;
    font-size: 13px;
}

.esdi-chat-bubble__tool-call summary {
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 6px;
    user-select: none;
}

.esdi-chat-bubble__tool-args {
    margin: 6px 0 0 0;
    padding: 8px;
    background: rgba(0, 0, 0, 0.05);
    border-radius: 6px;
    font-family: var(--font-mono, ui-monospace, "Geist Mono", monospace);
    font-size: 12px;
    overflow-x: auto;
    white-space: pre;
}

.esdi-chat-bubble__meta {
    margin-top: 4px;
    font-size: 11px;
}

/* ----- Typing indicator ----- */
.esdi-chat-typing-indicator {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 0;
    color: var(--ink-faded, #6b7280);
    font-size: 13px;
}

.esdi-chat-typing-indicator__dots {
    display: inline-flex;
    gap: 4px;
}

/* 2026-07-19 (Kevin) — raisonnement de l'agent EN DIRECT (discret) : italique, muté, borné à ~3 lignes avec
   fondu, l'assistant « pense » à voix basse comme ChatGPT/Claude. */
.esdi-chat-thinking-live {
    font-style: italic;
    opacity: 0.75;
    line-height: 1.35;
    max-height: 3.4em;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    -webkit-mask-image: linear-gradient(to bottom, #000 55%, transparent);
    mask-image: linear-gradient(to bottom, #000 55%, transparent);
}

.esdi-chat-typing-indicator__dots span {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--accent, #3fbecc);
    animation: chat-typing-bounce 1.4s infinite;
}

.esdi-chat-typing-indicator__dots span:nth-child(2) {
    animation-delay: 0.2s;
}

.esdi-chat-typing-indicator__dots span:nth-child(3) {
    animation-delay: 0.4s;
}

@keyframes chat-typing-bounce {
    0%, 60%, 100% { opacity: 0.3; transform: translateY(0); }
    30% { opacity: 1; transform: translateY(-4px); }
}

/* ----- Résultats d'outil condensés en pastille (2026-07-15, Kevin) ----- */
.esdi-tool-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: 1px solid var(--line);
    background: var(--bg-section-cool);
    color: var(--ink-soft);
    border-radius: var(--radius-pill);
    padding: 3px 12px 3px 10px;
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1.4;
    cursor: pointer;
    transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.esdi-tool-pill:hover { border-color: var(--accent-500); color: var(--ink); }
.esdi-tool-pill__ico { width: 14px; height: 14px; color: var(--accent-600); flex: 0 0 auto; }
.esdi-tool-pill__chevron { width: 13px; height: 13px; color: var(--ink-faded); flex: 0 0 auto; transition: transform 0.15s ease; }
.esdi-tool-pill.is-open .esdi-tool-pill__chevron { transform: rotate(90deg); }
/* la bulle d'outil devient compacte quand son contenu est une pastille (plus de gros cadre ambré) */
.esdi-chat-bubble--tool:has(.esdi-tool-pill) .esdi-chat-bubble__body {
    background: transparent;
    border: 0;
    padding: 2px 0;
    font-family: var(--font-sans);
    font-size: inherit;
}
.esdi-chat-bubble--tool:has(.esdi-tool-pill) .esdi-chat-bubble__avatar { display: none; }
.esdi-chat-bubble--tool:has(.esdi-tool-pill) .esdi-chat-bubble__meta { display: none; }
/* le contenu brut déplié : mono, encadré, scrollable */
.esdi-chat-bubble--tool .esdi-chat-bubble__content[data-tool-pill-done] {
    margin-top: 6px;
    padding: 8px 10px;
    background: var(--bg-section-cool);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono, monospace);
    font-size: 11.5px;
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 340px;
    overflow: auto;
}

/* ----- TO-DO LISTE live de l'agent (2026-07-15, Kevin) — carte sticky en tête du fil ----- */
.esdi-chat-todo {
    position: sticky;
    top: 0;
    z-index: 6;
    flex-shrink: 0; /* le fil est en flex-column : sans ça la carte s'écrase à ~24px quand le fil est plein */
    margin: 0 0 16px;
    padding: 12px 14px 10px;
    border: 1px solid var(--line);
    border-radius: var(--radius-md);
    background: var(--bg-card);
    box-shadow: var(--shadow-md);
    max-height: 44vh;
    overflow-y: auto;
    overflow-x: hidden;
    animation: esdi-chat-todo-in 0.35s var(--ease-default) both;
}
.esdi-chat-todo::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 3px;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
    background: var(--gradient-brand);
}
@keyframes esdi-chat-todo-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.esdi-chat-todo__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 8px;
}
.esdi-chat-todo__title {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-weight: 600;
    font-size: 13px;
    color: var(--ink);
}
.esdi-chat-todo__title svg { width: 16px; height: 16px; color: var(--accent-600); }
.esdi-chat-todo__count {
    font-family: var(--font-mono, monospace);
    font-size: 12px;
    font-weight: 600;
    color: var(--accent-700, #26737c);
    background: var(--bg-section-cool);
    padding: 2px 9px;
    border-radius: var(--radius-pill);
}
.esdi-chat-todo__close {
    border: 0;
    background: transparent;
    color: var(--ink-faded);
    cursor: pointer;
    font-size: 13px;
    line-height: 1;
    padding: 3px 6px;
    border-radius: var(--radius-xs);
    transition: color 0.15s, background 0.15s;
}
.esdi-chat-todo__close:hover { color: var(--ink); background: var(--bg-section-cool); }
.esdi-chat-todo__bar {
    height: 5px;
    border-radius: var(--radius-pill);
    background: var(--bg-section-cool);
    overflow: hidden;
    margin-bottom: 10px;
}
.esdi-chat-todo__fill {
    display: block;
    height: 100%;
    border-radius: var(--radius-pill);
    background: var(--gradient-brand);
    transition: width 0.5s var(--ease-default);
}
.esdi-chat-todo__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.esdi-chat-todo__item {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 5px 6px;
    border-radius: var(--radius-sm);
    font-size: 13.5px;
    line-height: 1.35;
    color: var(--ink-soft);
    transition: background 0.2s, color 0.2s;
}
.esdi-chat-todo__ico {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    margin-top: 1px;
    border-radius: 50%;
    border: 2px solid var(--line);
    background: transparent;
    position: relative;
    transition: border-color 0.2s, background 0.2s;
}
/* étape EN COURS : point cyan qui respire + texte accentué */
.esdi-chat-todo__item--active { background: var(--sig-ai-bg, #E3F4F7); color: var(--ink); font-weight: 600; }
.esdi-chat-todo__item--active .esdi-chat-todo__ico {
    border-color: var(--accent-500);
    box-shadow: 0 0 0 0 rgba(63, 190, 204, 0.5);
    animation: esdi-chat-todo-pulse 1.6s infinite;
}
.esdi-chat-todo__item--active .esdi-chat-todo__ico::after {
    content: '';
    position: absolute;
    inset: 3px;
    border-radius: 50%;
    background: var(--accent-500);
}
@keyframes esdi-chat-todo-pulse {
    0% { box-shadow: 0 0 0 0 rgba(63, 190, 204, 0.45); }
    70% { box-shadow: 0 0 0 6px rgba(63, 190, 204, 0); }
    100% { box-shadow: 0 0 0 0 rgba(63, 190, 204, 0); }
}
/* étape FAITE : pastille verte + coche, texte barré discret */
.esdi-chat-todo__item--done { color: var(--ink-faded); }
.esdi-chat-todo__item--done .esdi-chat-todo__text { text-decoration: line-through; }
.esdi-chat-todo__item--done .esdi-chat-todo__ico {
    border-color: var(--sig-ok);
    background: var(--sig-ok);
}
.esdi-chat-todo__item--done .esdi-chat-todo__ico::after {
    content: '';
    position: absolute;
    left: 4px;
    top: 1px;
    width: 4px;
    height: 8px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

/* ----- Input bas ----- */
.esdi-chat-input {
    display: flex;
    /* Épique 28 — SANS `wrap`, la rangée des pièces jointes (`flex: 0 0 100%`) reste sur la MÊME ligne
       que le reste et prend toute la largeur : le champ de saisie et le bouton « Envoyer » sont écrasés
       à zéro et disparaissent dès qu'on colle une capture. Vécu le 2026-08-02, signalé par Kevin.
       C'est `wrap` qui donne à la rangée sa propre ligne — pas `flex-basis` toute seule. */
    flex-wrap: wrap;
    gap: 8px;
    padding: 12px 16px;
    border-top: 1px solid var(--line);
    background: var(--bg);
    flex-shrink: 0;
    align-items: flex-end;
}

.esdi-chat-input__textarea {
    /* Épique 28 — `flex-grow: 1` seul ne suffit PLUS depuis que le conteneur autorise le retour à la
       ligne : Bootstrap pose `width: 100%` sur `.form-control`, donc la base flex `auto` résout à toute
       la largeur et le champ réclame une ligne pour lui seul — les boutons se retrouvaient chacun sur
       la leur, et la barre occupait quatre lignes. `flex: 1 1 0` + `min-width: 0` lui font PARTAGER sa
       ligne avec le trombone, le « / » et « Envoyer », en occupant ce qui reste. */
    flex: 1 1 0;
    min-width: 0;
    resize: none; /* auto-grow JS (refonte 2026-07-14) */
    min-height: 44px;
    max-height: 200px;
    font-family: var(--font-sans);
    font-size: 14px;
    line-height: 1.5;
    border-radius: 12px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.esdi-chat-input__textarea:focus {
    border-color: var(--accent, #3fbecc);
    box-shadow: 0 0 0 3px rgba(63, 190, 204, 0.15);
}

.esdi-chat-input__send {
    flex-shrink: 0;
    height: 44px;
    width: 44px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 12px;
    transition: transform 0.12s ease, filter 0.15s ease;
}
.esdi-chat-input__send:hover:not(:disabled) { filter: brightness(1.06); }
.esdi-chat-input__send:active:not(:disabled) { transform: scale(0.9); }

/* ============================================================================
   Épique 28 — DÉPOSER, COLLER, VOIR (barre de chat + pièces jointes du fil)
   ============================================================================ */

/* Bouton trombone — même gabarit que le bouton « / » pour que la barre reste alignée. */
.esdi-chat-input__attach {
    width: 30px;
    height: 30px;
    padding: 0;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1.5px solid var(--line);
    color: var(--muted);
    border-radius: 8px;
    background: transparent;
    transition: border-color .15s ease, color .15s ease, transform .12s ease;
}
.esdi-chat-input__attach:hover {
    border-color: var(--accent, #3fbecc);
    color: var(--primary, #1b5aa8);
}
.esdi-chat-input__attach:active { transform: scale(.92); }

/* Rangée des pièces en attente : occupe toute la largeur de la barre, AU-DESSUS du champ.
   `order:-1` évite de restructurer le formulaire (qui est un dmx-serverconnect-form : le
   moins on touche à sa forme, le moins on risque de casser sa sérialisation). */
.esdi-chat-pieces {
    flex: 0 0 100%;
    order: -1;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 8px;
}
.esdi-chat-pieces[hidden] { display: none; }

.esdi-chat-piece {
    position: relative;
    display: flex;
    align-items: center;
    gap: 8px;
    max-width: 260px;
    padding: 6px 8px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--bg-soft, rgba(0, 0, 0, .02));
    font-size: 12.5px;
}
.esdi-chat-piece__apercu {
    width: 34px;
    height: 34px;
    flex-shrink: 0;
    border-radius: 6px;
    object-fit: cover;
    background: var(--line);
}
.esdi-chat-piece__ico {
    width: 34px;
    height: 34px;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 6px;
    background: var(--line);
    color: var(--muted);
}
.esdi-chat-piece__nom {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.esdi-chat-piece__etat { color: var(--muted); font-size: 11px; }
.esdi-chat-piece--erreur { border-color: #dc3545; }
.esdi-chat-piece--erreur .esdi-chat-piece__etat { color: #dc3545; }
.esdi-chat-piece__retirer {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    padding: 0;
    line-height: 1;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--muted);
    font-size: 15px;
}
.esdi-chat-piece__retirer:hover { background: var(--line); color: var(--fg); }

/* Barre de progression du dépôt : un fil sous la vignette, pas un spinner —
   sur un fichier de 30 Mo, savoir OÙ on en est vaut mieux que savoir que « ça tourne ». */
.esdi-chat-piece__jauge {
    position: absolute;
    left: 8px;
    right: 8px;
    bottom: 3px;
    height: 2px;
    border-radius: 2px;
    background: var(--line);
    overflow: hidden;
}
.esdi-chat-piece__jauge span {
    display: block;
    height: 100%;
    width: 0;
    background: var(--accent, #3fbecc);
    transition: width .2s ease;
}

/* Voile de dépôt — couvre le fil, jamais la barre (on doit pouvoir viser sans peur). */
.esdi-chat-drop {
    position: absolute;
    inset: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(63, 190, 204, .10);
    backdrop-filter: blur(2px);
    border: 2px dashed var(--accent, #3fbecc);
    border-radius: 12px;
    pointer-events: none;   /* le survol reste au conteneur : pas de clignotement dragenter/dragleave */
}
.esdi-chat-drop[hidden] { display: none; }
.esdi-chat-drop__carte {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 22px 30px;
    border-radius: 14px;
    background: var(--bg);
    box-shadow: 0 12px 34px rgba(0, 0, 0, .16);
    color: var(--primary, #1b5aa8);
    text-align: center;
}
.esdi-chat-drop__carte span { color: var(--muted); font-size: 12.5px; }

/* ----- Pièces jointes affichées DANS une bulle ----- */
.esdi-chat-attach {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 8px;
}
.esdi-chat-attach__item { display: contents; }

.esdi-chat-attach__vignette {
    padding: 0;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: transparent;
    overflow: hidden;
    line-height: 0;
    cursor: zoom-in;
    transition: border-color .15s ease;
}
.esdi-chat-attach__vignette:hover { border-color: var(--accent, #3fbecc); }
.esdi-chat-attach__vignette img {
    max-width: 260px;
    max-height: 200px;
    object-fit: contain;
    display: block;
}

.esdi-chat-attach__carte {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--bg);
    font-size: 12.5px;
    max-width: 300px;
}
.esdi-chat-attach__ico { color: var(--muted); display: inline-flex; }
.esdi-chat-attach__meta { display: flex; flex-direction: column; min-width: 0; }
.esdi-chat-attach__nom { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.esdi-chat-attach__poids { color: var(--muted); font-size: 11px; }
.esdi-chat-attach__lien {
    color: var(--muted);
    display: inline-flex;
    padding: 4px;
    border-radius: 6px;
}
.esdi-chat-attach__lien:hover { color: var(--primary, #1b5aa8); background: var(--line); }

/* Visionneuse plein écran (clic sur une vignette). */
.esdi-chat-loupe {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, .82);
    padding: 30px;
    cursor: zoom-out;
}
.esdi-chat-loupe[hidden] { display: none; }
.esdi-chat-loupe img {
    max-width: 100%;
    max-height: 100%;
    border-radius: 8px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, .5);
}
.esdi-chat-loupe__nom {
    position: absolute;
    bottom: 16px;
    left: 0;
    right: 0;
    text-align: center;
    color: #fff;
    font-size: 12.5px;
    opacity: .85;
}

/* Bouton « / » (aide-mémoire commandes) — ex-styles inline, thémés (refonte 2026-07-14) */
.esdi-chat-input__slash {
    font-family: var(--font-mono, "Geist Mono", monospace);
    font-weight: 700;
    width: 30px;
    height: 30px;
    padding: 0;
    line-height: 1;
    border: 1.5px solid var(--accent, #3fbecc);
    color: var(--primary, #1b5aa8);
    border-radius: 8px;
}

/* Jauge de contexte (Story 9h-1) — ex-styles inline, thémés (refonte 2026-07-14) */
.esdi-chat-ctx {
    font-family: var(--font-mono, "Geist Mono", monospace);
    font-size: 10px;
    font-weight: 600;
    line-height: 1;
    padding: 5px 7px;
    border: 1px solid var(--line, #e2e8f0);
    border-radius: 8px;
    white-space: nowrap;
    cursor: default;
    color: var(--ink-faded, #64748b);
}
.esdi-chat-ctx--warn {
    color: #b45309;
    border-color: rgba(245, 158, 11, 0.5);
}

/* Bannière « longue conversation » (Story 9h-1) — fermable (refonte 2026-07-14) */
.esdi-chat-context-warn {
    position: sticky;
    top: 0;
    z-index: 5;
    margin: 0 0 0.9rem;
    padding: 0.55rem 2.2rem 0.55rem 0.85rem;
    border-radius: 10px;
    background: #eefbfd;
    border: 1px solid #bfeaf0;
    color: #155e75;
    font-size: 0.82rem;
    line-height: 1.35;
    box-shadow: 0 2px 8px rgba(27, 90, 168, 0.08);
}
.esdi-chat-context-warn__close {
    position: absolute;
    top: 0.3rem;
    right: 0.35rem;
    border: 0;
    background: transparent;
    color: inherit;
    opacity: 0.55;
    cursor: pointer;
    padding: 0.15rem 0.35rem;
    border-radius: 6px;
    font-size: 0.8rem;
    line-height: 1;
}
.esdi-chat-context-warn__close:hover { opacity: 1; background: rgba(21, 94, 117, 0.08); }

/* Ajustements mobile du fil (refonte 2026-07-14) */
@media (max-width: 767.98px) {
    .esdi-chat-bubble { max-width: 94%; }
    .esdi-chat-main__header { padding: 10px 12px; }
    .esdi-chat-thread { padding: 14px 12px; gap: 12px; }
    .esdi-chat-input { padding: 10px 10px calc(10px + env(safe-area-inset-bottom, 0px)); }
}

/* Status dot variants déjà définis Story 2.4 — variant idle ajout */
.esdi-status-dot--idle {
    background: var(--ink-faded, #9ca3af);
}

/* ============================================================================
 * Story 7.6 — UI Connecteurs MCP Google Workspace (/connectors)
 * ============================================================================ */

/* Banner mode démo OAuth V1 (orange-faded) — Antipattern #A V1.5 retirer quand vrai Google */
.esdi-mode-demo-banner {
    background: rgba(255, 165, 0, 0.08);
    border: 1px solid rgba(255, 165, 0, 0.3);
    border-left: 4px solid #f59e0b;
    border-radius: 6px;
    padding: 14px 18px;
}

/* Grid auto-fit responsive : 3 cards desktop / 2 tablet / 1 mobile */
.esdi-connector-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 16px;
}

/* Card connecteur — pattern Story 7.4 esdi-employee-live-card adapté (vertical au lieu d'horizontal) */
.esdi-connector-card {
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    overflow: hidden;
    transition: border-color 0.15s, transform 0.15s;
}

.esdi-connector-card:hover {
    border-color: var(--primary);
}

.esdi-connector-card__header {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    min-width: 0;
}

.esdi-connector-card__icon {
    flex-shrink: 0;
    width: 48px;
    height: 48px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, rgba(63, 190, 204, 0.1), rgba(27, 90, 168, 0.1));
    border-radius: 8px;
    color: var(--primary);
}

.esdi-connector-card__title-row {
    flex-grow: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    flex-wrap: wrap;
}

.esdi-connector-card__badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: 12px;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.2;
}

.esdi-connector-card__badge--installed {
    background: rgba(34, 197, 94, 0.12);
    color: #15803d;
}

.esdi-connector-card__description {
    margin: 0;
    line-height: 1.5;
}

.esdi-connector-card__tools {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.esdi-chip {
    display: inline-block;
    padding: 3px 8px;
    background: var(--bg-faded, #f3f4f6);
    border: 1px solid var(--line);
    border-radius: 4px;
    font-size: 11px;
    line-height: 1.4;
    color: var(--ink);
}

.esdi-chip--mono {
    font-family: var(--font-mono, ui-monospace, monospace);
}

.esdi-connector-card__cta {
    margin-top: auto;
}

/* Section Installés — rows horizontales (avatar 32px / content 1fr / button auto) */
.esdi-connectors-installed-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.esdi-connector-installed-row {
    display: grid;
    grid-template-columns: 40px minmax(0, 1fr) auto;
    gap: 16px;
    padding: 14px 18px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 6px;
    align-items: center;
}

.esdi-connector-installed-row__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--primary);
}

.esdi-connector-installed-row__content {
    min-width: 0;
    overflow: hidden;
}

.esdi-connector-installed-row__name {
    line-height: 1.3;
}

.esdi-connector-installed-row__cta {
    flex-shrink: 0;
}

/* Toast notifications (réutilise pattern Story 2.3 / 2.6) */
.esdi-toast-container {
    position: fixed;
    top: 80px;
    right: 24px;
    z-index: 1090;
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;
}

.esdi-toast {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    border-radius: 6px;
    font-size: 14px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    pointer-events: auto;
    animation: esdi-toast-slide-in 0.2s ease-out;
}

.esdi-toast--success {
    background: #ecfdf5;
    border: 1px solid #6ee7b7;
    color: #065f46;
}

.esdi-toast--error {
    background: #fef2f2;
    border: 1px solid #fca5a5;
    color: #991b1b;
}

@keyframes esdi-toast-slide-in {
    from { opacity: 0; transform: translateX(20px); }
    to { opacity: 1; transform: translateX(0); }
}

/* ============================================================================
 * Story 7.7 — Logs observability page /logs (poll 5s actions_log)
 * ============================================================================ */

.esdi-logs-main {
    padding: 24px;
    max-width: 100%;
    overflow-x: hidden;
}

.esdi-logs-header {
    margin-bottom: 16px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--line, #e2e6ea);
}

.esdi-logs-filters {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 12px;
    align-items: end;
}

.esdi-logs-empty {
    text-align: center;
    padding: 60px 20px;
    color: var(--muted, #6c757d);
    background: var(--bg-subtle, #fafbfc);
    border-radius: 8px;
    border: 1px dashed var(--line, #e2e6ea);
}

.esdi-logs-table-wrapper {
    overflow-x: auto;
    border: 1px solid var(--line, #e2e6ea);
    border-radius: 6px;
    background: var(--bg, #fff);
    max-height: calc(100vh - 320px);
    -webkit-overflow-scrolling: touch;
}

.esdi-logs-table {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--font-mono, "Geist Mono", "JetBrains Mono", monospace);
    font-size: 12px;
    line-height: 1.5;
}

.esdi-logs-table thead {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--bg-subtle, #f4f6f8);
    box-shadow: 0 1px 0 var(--line, #e2e6ea);
}

.esdi-logs-table th {
    padding: 8px 12px;
    font-weight: 600;
    text-align: left;
    color: var(--text, #1a1a1a);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-size: 10px;
    border-bottom: 1px solid var(--line, #e2e6ea);
    white-space: nowrap;
}

.esdi-logs-table tbody tr {
    border-bottom: 1px solid var(--line-subtle, #f0f2f4);
    transition: background 0.1s ease;
}

.esdi-logs-table tbody tr:hover {
    background: var(--bg-subtle, #fafbfc);
}

.esdi-logs-cell {
    padding: 6px 12px;
    vertical-align: top;
    word-break: break-word;
}

.esdi-logs-cell--ts {
    color: var(--muted, #6c757d);
    white-space: nowrap;
    font-size: 11px;
}

.esdi-logs-cell--slug {
    color: var(--primary, #3fbecc);
    font-weight: 500;
    white-space: nowrap;
}

.esdi-logs-cell--num {
    color: var(--muted, #6c757d);
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.esdi-logs-cell--summary {
    max-width: 400px;
}

.esdi-logs-cell--summary details summary {
    cursor: pointer;
    color: var(--text, #1a1a1a);
    list-style: none;
}

.esdi-logs-cell--summary details summary::-webkit-details-marker { display: none; }
.esdi-logs-cell--summary details[open] summary {
    color: var(--primary, #3fbecc);
}

.esdi-logs-jsonb {
    background: var(--bg-subtle, #fafbfc);
    border: 1px solid var(--line, #e2e6ea);
    border-radius: 4px;
    padding: 8px;
    margin: 6px 0 0;
    font-size: 11px;
    line-height: 1.4;
    max-height: 240px;
    overflow: auto;
    white-space: pre-wrap;
    word-break: break-all;
    color: var(--text, #1a1a1a);
}

.esdi-logs-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    background: var(--line, #e2e6ea);
    color: var(--muted, #6c757d);
    white-space: nowrap;
}

.esdi-logs-badge--tool_call_llm           { background: rgba(255, 165, 0, 0.15);  color: #b35900; }
.esdi-logs-badge--tool_call_deterministic { background: rgba(34, 197, 94, 0.15);  color: #15803d; }
.esdi-logs-badge--manager_delegate        { background: rgba(27, 90, 168, 0.15);  color: #1b5aa8; }
.esdi-logs-badge--digest_cron             { background: rgba(63, 190, 204, 0.15); color: #1b8a96; }
.esdi-logs-badge--imap_fetch              { background: rgba(99, 102, 241, 0.15); color: #4338ca; }
.esdi-logs-badge--llm_draft               { background: rgba(168, 85, 247, 0.15); color: #6b21a8; }
.esdi-logs-badge--smtp_draft              { background: rgba(236, 72, 153, 0.15); color: #9d174d; }
.esdi-logs-badge--validation              { background: rgba(34, 197, 94, 0.15);  color: #15803d; }
.esdi-logs-badge--rejection               { background: rgba(239, 68, 68, 0.15);  color: #b91c1c; }
.esdi-logs-badge--budget_alert            { background: rgba(245, 158, 11, 0.15); color: #b45309; }
.esdi-logs-badge--circuit_breaker_trigger { background: rgba(239, 68, 68, 0.2);   color: #991b1b; }

.esdi-logs-table tr[data-severity="major"]     { background: rgba(245, 158, 11, 0.04); }
.esdi-logs-table tr[data-severity="critical"]  { background: rgba(239, 68, 68, 0.06); }

@media (max-width: 768px) {
    .esdi-logs-main { padding: 12px; }
    .esdi-logs-table { font-size: 11px; }
    .esdi-logs-cell { padding: 4px 8px; }
}

/* ============================================================================
 * Story 7.10 — Propose-Valide inline validation card (chat thread FR43)
 * ============================================================================ */

.esdi-chat-bubble--pending-validation .esdi-chat-bubble__body {
    background: rgba(245, 158, 11, 0.04);
    border-left: 3px solid rgba(245, 158, 11, 0.5);
    padding-left: 12px;
}

.esdi-validation-card-inline {
    border: 1px solid rgba(245, 158, 11, 0.3);
    border-radius: 6px;
    background: rgba(245, 158, 11, 0.06);
    padding: 12px;
    margin-bottom: 8px;
}

.esdi-validation-card-inline__badge {
    display: inline-block;
    padding: 4px 10px;
    border-radius: 999px;
    font-family: var(--font-mono, "Geist Mono", monospace);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.06em;
    margin-bottom: 8px;
}
.esdi-validation-card-inline__badge--pending {
    background: rgba(245, 158, 11, 0.18);
    color: #b45309;
}
.esdi-validation-card-inline__badge--validated {
    background: rgba(34, 197, 94, 0.18);
    color: #15803d;
}
.esdi-validation-card-inline__badge--edited {
    background: rgba(63, 190, 204, 0.18);
    color: #1b8a96;
}
.esdi-validation-card-inline__badge--rejected {
    background: rgba(239, 68, 68, 0.18);
    color: #b91c1c;
}

.esdi-validation-card-inline__title {
    font-weight: 600;
    margin-bottom: 6px;
    color: var(--text, #1a1a1a);
}
.esdi-validation-card-inline__title code {
    font-family: var(--font-mono, "Geist Mono", monospace);
    background: rgba(0, 0, 0, 0.05);
    padding: 1px 6px;
    border-radius: 3px;
    color: var(--primary, #3fbecc);
}

.esdi-validation-card-inline__preview {
    background: var(--bg, #fff);
    border: 1px solid var(--line, #e2e6ea);
    border-radius: 4px;
    padding: 8px 10px;
    margin: 6px 0;
    font-family: var(--font-mono, "Geist Mono", monospace);
    font-size: 12px;
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-all;
    max-height: 200px;
    overflow: auto;
}

.esdi-validation-card-inline__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 10px;
}
.esdi-validation-card-inline__actions .btn {
    font-family: var(--font-mono, "Geist Mono", monospace);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.04em;
}

/* ── Icônes Lucide inline (restyle console admin 2026-07-12) ─────────────────── */
/* Dimensionnement par défaut des icônes lucide inline + spinner réutilisable.
   Les <i data-lucide> sans style explicite prennent 1em (au fil du texte). */
[data-lucide]:not([style*="width"]) { width: 1em; height: 1em; vertical-align: -.14em; }
svg.lucide { vertical-align: -.14em; }
.esdi-spin { animation: esdi-spin-rot 1s linear infinite; display: inline-block; }
@keyframes esdi-spin-rot { to { transform: rotate(360deg); } }

/* ── Toggle de thème clair / sombre / auto (2026-07-14) — piloté par /js/theme.js ── */
.esdi-theme-toggle {
    display: inline-flex;
    gap: 2px;
    padding: 3px;
    border-radius: var(--radius-pill, 100px);
    background: var(--bg-section-cool, #EEF1F7);
    border: 1px solid var(--line, #EAE4DA);
    line-height: 0;
}
.esdi-theme-toggle button {
    border: 0;
    background: transparent;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    color: var(--ink-faded, #8F92A6);
    cursor: pointer;
    transition: background-color var(--duration-micro, 150ms) var(--ease-default), color var(--duration-micro, 150ms) var(--ease-default);
}
.esdi-theme-toggle button:hover { color: var(--ink, #1F2133); }
.esdi-theme-toggle button.is-active {
    background: var(--bg-card, #fff);
    color: var(--primary, #1b5aa8);
    box-shadow: var(--shadow-sm);
}
.esdi-theme-toggle button:focus-visible { outline: none; box-shadow: var(--shadow-focus); }
.esdi-theme-toggle button svg { width: 15px; height: 15px; }

/* ============================================================================
   2026-07-16 (Kevin) — Indicateur GLOBAL discret « en cours » (topbar).
   Pastille pulsée cyan ESDI visible sur toutes les pages dès qu'une tâche
   tourne (feed.json → running). Discret : petit, tons doux, clic → /dashboard.
   ========================================================================== */
.esdi-activity-pulse {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    text-decoration: none;
    font-size: .72rem;
    font-weight: 500;
    color: var(--text-muted, #6c757d);
    padding: .18rem .55rem;
    border-radius: 999px;
    border: 1px solid rgba(63, 190, 204, .35);
    background: rgba(63, 190, 204, .08);
    white-space: nowrap;
}
.esdi-activity-pulse:hover {
    color: var(--text, inherit);
    border-color: rgba(63, 190, 204, .6);
    background: rgba(63, 190, 204, .14);
}
.esdi-activity-pulse__dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #3fbecc;
    animation: esdiActivityPulse 1.6s ease-in-out infinite;
    flex: 0 0 auto;
}
@keyframes esdiActivityPulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(63, 190, 204, .55); opacity: 1; }
    50%      { box-shadow: 0 0 0 5px rgba(63, 190, 204, 0);  opacity: .55; }
}
@media (prefers-reduced-motion: reduce) {
    .esdi-activity-pulse__dot { animation: none; }
}

/* ============================================================================
   Story 9h-4 — Refonte connexion Moteurs IA (/settings/llm)
   Cards catalogue + badges méthode + chips capacités + bouton OAuth + modal.
   Tokens design system (--bg/--border/--text/--text-muted/--cyan-esdi) → dark OK.
   ============================================================================ */

/* Badges méthode de connexion sur les cards (Clé API / 1-clic / Local) */
.esdi-method-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: auto;
}
.esdi-method-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
    background: rgba(107, 114, 128, 0.1);
    color: var(--text-muted, #6b7280);
    border: 1px solid var(--border, #e5e7eb);
}
.esdi-method-badge--oauth {
    background: linear-gradient(135deg, rgba(63, 190, 204, 0.12) 0%, rgba(27, 90, 168, 0.12) 100%);
    color: var(--cyan-esdi, #3fbecc);
    border-color: rgba(63, 190, 204, 0.35);
}
.esdi-method-badge--local {
    background: rgba(16, 163, 127, 0.1);
    color: #10a37f;
    border-color: rgba(16, 163, 127, 0.3);
}
.esdi-method-badge i { width: 11px; height: 11px; }

/* Chips capacités (fenêtre contexte, RPM détecté) — table configs + modal */
.esdi-cap-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border-radius: 6px;
    font-size: 11.5px;
    font-family: var(--font-mono, 'Geist Mono', monospace);
    background: rgba(63, 190, 204, 0.08);
    color: var(--text, #111827);
    border: 1px solid rgba(63, 190, 204, 0.2);
    white-space: nowrap;
}
.esdi-cap-chip i { width: 11px; height: 11px; color: var(--cyan-esdi, #3fbecc); }

/* Bouton OAuth 1-clic (grand, dans la modal) */
.esdi-oauth-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    width: 100%;
    padding: 12px 20px;
    border-radius: 10px;
    border: 2px solid var(--cyan-esdi, #3fbecc);
    background: linear-gradient(135deg, rgba(63, 190, 204, 0.06) 0%, rgba(27, 90, 168, 0.06) 100%);
    color: var(--text, #111827);
    font-weight: 600;
    font-size: 15px;
    text-decoration: none;
    cursor: pointer;
    transition: all 0.18s ease;
}
.esdi-oauth-btn:hover {
    background: linear-gradient(135deg, rgba(63, 190, 204, 0.14) 0%, rgba(27, 90, 168, 0.14) 100%);
    color: var(--text, #111827);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(63, 190, 204, 0.2);
}
.esdi-oauth-btn[aria-disabled="true"] {
    opacity: 0.55;
    cursor: not-allowed;
    pointer-events: none;
}
.esdi-oauth-btn i { width: 20px; height: 20px; color: var(--cyan-esdi, #3fbecc); }

/* Séparateur « ou » entre OAuth et clé API */
.esdi-llm-divider {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 18px 0 14px;
    color: var(--text-muted, #6b7280);
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.esdi-llm-divider::before,
.esdi-llm-divider::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--border, #e5e7eb);
}

/* Lien « Obtenir une clé » sous le champ clé API */
.esdi-get-key-link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 12.5px;
    color: var(--cyan-esdi, #3fbecc);
    text-decoration: none;
}
.esdi-get-key-link:hover { text-decoration: underline; color: var(--cyan-esdi, #3fbecc); }
.esdi-get-key-link i { width: 12px; height: 12px; }

/* Note fournisseur dans la modal (encart discret) */
.esdi-provider-note {
    display: flex;
    gap: 8px;
    padding: 10px 12px;
    border-radius: 8px;
    background: rgba(107, 114, 128, 0.06);
    border: 1px solid var(--border, #e5e7eb);
    font-size: 12.5px;
    color: var(--text-muted, #6b7280);
    line-height: 1.45;
}
.esdi-provider-note i { flex-shrink: 0; width: 14px; height: 14px; margin-top: 1px; }

/* Bannière OAuth retour (succès / erreur) */
.esdi-oauth-banner {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 16px;
    border-radius: 10px;
    margin-bottom: 20px;
    font-size: 14px;
}
.esdi-oauth-banner--success {
    background: rgba(16, 163, 127, 0.08);
    border: 1px solid rgba(16, 163, 127, 0.3);
    color: var(--text, #111827);
}
.esdi-oauth-banner--error {
    background: rgba(220, 38, 38, 0.07);
    border: 1px solid rgba(220, 38, 38, 0.25);
    color: var(--text, #111827);
}
.esdi-oauth-banner i { flex-shrink: 0; width: 18px; height: 18px; margin-top: 1px; }
.esdi-oauth-banner--success i { color: #10a37f; }
.esdi-oauth-banner--error i { color: #dc2626; }

/* ============ Charte graphique de l'entreprise (Story 26-2) ============ */
.esdi-cg-couleurs { display: flex; flex-direction: column; gap: 8px; }
.esdi-cg-couleur { display: grid; grid-template-columns: 110px 44px 1fr auto; align-items: center; gap: 10px; }
.esdi-cg-couleur label { margin: 0; font-size: 0.85rem; color: #5b6b7d; }
.esdi-cg-couleur input[type="color"] { width: 44px; height: 32px; padding: 2px; border: 1px solid #d7e0ea;
  border-radius: 6px; background: #fff; cursor: pointer; }
.esdi-cg-couleur input[type="text"] { max-width: 130px; font-family: var(--font-mono, monospace); }
@media (max-width: 575.98px) { .esdi-cg-couleur { grid-template-columns: 1fr 44px auto; } .esdi-cg-couleur label { grid-column: 1 / -1; } }

/* L'aperçu montre AVANT d'enregistrer ce que les assistants produiront : les styles en ligne y sont
   posés par le script (ce sont les couleurs de l'utilisateur), d'où le peu de règles ici. */
.esdi-cg-apercu { border: 1px solid #e2e9f1; border-radius: 8px; padding: 12px; background:
  repeating-conic-gradient(#f4f7fb 0% 25%, #ffffff 0% 50%) 50% / 16px 16px; }
.esdi-cg-carte { padding: 24px 28px; box-shadow: 0 2px 10px rgba(0,0,0,0.06); }
.esdi-cg-carte__eyebrow { font-size: 0.72rem; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; }
.esdi-cg-carte__titre { font-size: 1.6rem; font-weight: 700; line-height: 1.15; margin: 6px 0 8px; }
.esdi-cg-carte__corps { font-size: 0.92rem; line-height: 1.5; opacity: 0.9; }
.esdi-cg-carte__pastilles { display: flex; gap: 8px; margin-top: 16px; }
.esdi-cg-carte__pastilles span { width: 34px; height: 34px; display: inline-block; }

/* Story 26-3 — « récupérer depuis mon site ». Un liseré à gauche, comme pour toute proposition à valider :
   le bloc doit se lire comme un devis, pas comme un réglage déjà appliqué. */
.esdi-cg-site { border-left: 3px solid var(--esdi-cyan, #3fbecc); padding-left: 12px; }
.esdi-cg-prop li { margin: 2px 0; }
.esdi-cg-puce { width: 16px; height: 16px; border-radius: 4px; display: inline-block;
  border: 1px solid rgba(0,0,0,0.15); flex: 0 0 auto; }

/* ============ Boîtes mail connectées (une par utilisateur, 2026-07-29) ============ */
.esdi-mb-list { display: flex; flex-direction: column; gap: 8px; }
.esdi-mb-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  border: 1px solid #e2e9f1; border-radius: 8px; padding: 10px 12px; background: #fbfcfe; }
/* Boîte décochée : grisée pour qu'on voie d'un coup d'œil que les assistants ne s'en servent pas.
   Les cases restent cliquables — c'est par là qu'on la remet en service. */
.esdi-mb-row--off { background: #f6f7f9; border-style: dashed; }
.esdi-mb-row--off .esdi-mb-row__addr,
.esdi-mb-row--off .esdi-mb-row__meta { opacity: 0.55; text-decoration: none; }
.esdi-mb-row__addr { font-weight: 600; font-size: 0.92rem; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.esdi-mb-row__meta { color: var(--esdi-text-muted, #8a94a6); font-size: 0.8rem; margin-top: 2px; }
.esdi-mb-row__actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.esdi-mb-check { display: inline-flex; align-items: center; gap: 5px; font-size: 0.83rem; margin: 0; cursor: pointer; color: #5b6b7d; }
.esdi-mb-badge { display: inline-block; padding: 1px 7px; border-radius: 10px; font-size: 0.7rem; font-weight: 600;
  background: #eef3f8; color: #5b6b7d; border: 1px solid #d7e0ea; }
.esdi-mb-badge--def { background: rgba(63,190,204,0.14); color: #1b7f8c; border-color: rgba(63,190,204,0.35); }
.esdi-mb-badge--off { background: #f4f5f7; color: #8a94a6; }

/* ============ Modale de relecture email au client (Epic 23) ============ */
/* En-tête façon logiciel de messagerie : libellé à gauche, champ à droite, lignes séparées par un filet.
   On voit « De / Pour / Copie / Objet » d'un coup d'œil — l'expéditeur n'est plus une surprise. */
.esdi-er-head { display: grid; grid-template-columns: 62px 1fr; align-items: center; gap: 0 10px;
  border: 1px solid #d7e0ea; border-radius: 8px; padding: 2px 10px; margin-bottom: 6px; background: #fbfcfe; }
.esdi-er-head__lab { margin: 0; padding: 7px 0; font-size: 0.84rem; color: #6b7a8d; font-weight: 600; }
.esdi-er-head > .form-control { border: none; background: transparent; box-shadow: none; padding: 7px 0;
  border-radius: 0; font-size: 0.9rem; }
.esdi-er-head > .form-control:focus { box-shadow: none; background: transparent; }
.esdi-er-head > *:nth-child(n+3) { border-top: 1px solid #eef2f7; }
.esdi-er-head select.form-control { font-weight: 600; color: var(--text, #111827); }
@media (max-width: 480px) { .esdi-er-head { grid-template-columns: 1fr; }
  .esdi-er-head__lab { padding-bottom: 0; }
  .esdi-er-head > *:nth-child(n+3) { border-top: none; } }
.esdi-er-attachments { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0; min-height: 24px; }
.esdi-er-empty { color: var(--esdi-text-muted, #8a94a6); font-size: 0.85rem; font-style: italic; }
.esdi-er-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 6px 4px 10px; border-radius: 16px;
  background: #eef3f8; border: 1px solid #d7e0ea; font-size: 0.82rem; max-width: 100%; }
.esdi-er-chip svg { width: 14px; height: 14px; flex-shrink: 0; color: #5b6b7d; }
.esdi-er-chip__x { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px;
  border: none; background: transparent; cursor: pointer; line-height: 1; color: #7a8698; padding: 0; border-radius: 50%;
  transition: background 0.12s ease, color 0.12s ease; }
.esdi-er-chip__x svg { width: 13px; height: 13px; }
.esdi-er-chip__x:hover { color: #c0392b; background: rgba(192,57,43,0.10); }
.esdi-er-pick svg, .esdi-er-picker__bar svg { width: 15px; height: 15px; vertical-align: -3px; margin-right: 4px; color: #5b6b7d; }
.esdi-er-picker { margin-top: 8px; border: 1px solid #d7e0ea; border-radius: 8px; overflow: hidden; }
.esdi-er-picker__bar { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 6px 10px; background: #f4f7fb; border-bottom: 1px solid #e2e9f1; font-size: 0.85rem; }
.esdi-er-picker__list { max-height: 220px; overflow-y: auto; }
.esdi-er-pick { padding: 7px 12px; cursor: pointer; font-size: 0.88rem; border-bottom: 1px solid #f0f3f7; }
.esdi-er-pick:last-child { border-bottom: none; }
.esdi-er-pick:hover { background: #eef3f8; }


/* ============================================================
   PASTILLE CERTIFIÉE — « prestation ESDI, vendue en supplément »
   ------------------------------------------------------------
   UN SEUL marqueur pour tout ce qui n'est pas inclus dans l'abonnement : Employés Signature,
   automatisations conçues par ESDI, prestations à venir. Ajouté 2026-07-30 (demande Kevin :
   « plus comme un logo certifié à la façon d'Instagram »).

   Le badge est une IMAGE DE FOND (data-URI), pas une icône Lucide ni un <svg> répété dans le
   markup : (a) `lucide.createIcons()` tourne avant que les lignes d'un dmx-repeat ne soient peintes
   et remplace le SVG — l'icône disparaît une fois sur deux (piège vécu, cf.
   project_bridge_v010_binary_folders) ; (b) un seul point de vérité pour le dessin, réutilisé par
   toutes les pages sans dupliquer 10 lignes de SVG.

   Dessin : rosette 12 lobes (polygone à rayons alternés + jointures arrondies, comme les badges
   « vérifié ») en doré ESDI, coche blanche par-dessus.
   ============================================================ */
.esdi-certified {
  display: inline-block; flex-shrink: 0;
  width: 15px; height: 15px; vertical-align: -3px;
  background-repeat: no-repeat; background-position: center; background-size: contain;
  background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%3E%3Cpolygon%20points='12.00,2.70%2013.94,4.76%2016.65,3.95%2017.30,6.70%2020.05,7.35%2019.24,10.06%2021.30,12.00%2019.24,13.94%2020.05,16.65%2017.30,17.30%2016.65,20.05%2013.94,19.24%2012.00,21.30%2010.06,19.24%207.35,20.05%206.70,17.30%203.95,16.65%204.76,13.94%202.70,12.00%204.76,10.06%203.95,7.35%206.70,6.70%207.35,3.95%2010.06,4.76'%20fill='%23d9a520'%20stroke='%23d9a520'%20stroke-width='3'%20stroke-linejoin='round'/%3E%3Cpath%20d='M7.9%2012.2%20L10.6%2014.9%20L16.1%209.2'%20fill='none'%20stroke='%23ffffff'%20stroke-width='2.4'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3C/svg%3E");
}
.esdi-certified--sm { width: 12px; height: 12px; vertical-align: -2px; }
.esdi-certified--lg { width: 19px; height: 19px; vertical-align: -4px; }

/* Pastille posée en bas à droite d'un avatar rond. Le parent porte .esdi-premium-host.
   L'anneau blanc (box-shadow) la détache du dégradé de l'avatar — sans lui, le doré se noie. */
.esdi-premium-host { position: relative; display: inline-flex; flex-shrink: 0; }
.esdi-certified--onavatar {
  position: absolute; right: -3px; bottom: -3px; z-index: 2;
  width: 15px; height: 15px; border-radius: 50%;
  box-shadow: 0 0 0 2px var(--bg-card, #fff);
  pointer-events: none;
}

/* 2026-08-13 — PASTILLE « MESSAGE NON LU » sur l'avatar d'un assistant, dans le rail du chat.
   Posée EN HAUT à droite, quand la pastille « certifié » occupe le bas : les deux coexistent sur un
   assistant Signature qui vous a répondu, et se chevaucher les rendrait illisibles toutes les deux.
   Même anneau que sa voisine, pour la même raison — sans lui, elle se noie dans le dégradé de l'avatar.
   `min-width` + padding : un compteur à deux chiffres s'élargit au lieu d'être rogné. */
.esdi-chat-nonlu {
  position: absolute; right: -4px; top: -4px; z-index: 3;
  min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 999px;
  background: var(--bs-primary, #1b5aa8); color: #fff;
  font-size: .58rem; font-weight: 700; line-height: 16px; text-align: center;
  box-shadow: 0 0 0 2px var(--bg-card, #fff);
  pointer-events: none;
}
.esdi-chat-nonlu[hidden] { display: none; }

/* Chip lisible : pastille + libellé, quand il y a la place de nommer la chose. */
.esdi-premium {
  display: inline-flex; align-items: center; gap: 4px; white-space: nowrap;
  padding: 1px 8px 1px 6px; border-radius: 999px;
  background: linear-gradient(135deg, #fdf3d4, #f7e3ab);
  border: 1px solid #e6c56b; color: #7a5a12;
  font-size: 0.7rem; font-weight: 600; letter-spacing: 0.02em; line-height: 1.6;
  vertical-align: 2px;
}
.esdi-premium .esdi-certified { vertical-align: 0; }
/* Forme nue : la pastille seule, là où il n'y a pas la place (rail du chat, onglets, listes denses). */
.esdi-premium--bare { background: none; border: none; padding: 0; }

/* Variante bas-GAUCHE : sur les cartes « Équipe IA en direct », le coin bas-droit de l'avatar porte
   déjà la pastille d'état (travaille / au repos / en erreur). Superposer les deux les rendrait
   illisibles toutes les deux. */
.esdi-certified--bl { right: auto; left: -3px; }

/* =========================================================================
   RENDU MARKDOWN DES RÉPONSES D'ASSISTANT (chat) — 2026-07-31, demande Kevin
   Moteur : public/js/esdi-markdown.js ; branchement : views/chat/index.ejs.

   Objectif : une réponse de LLM doit se LIRE (titres, listes, tableaux, code)
   au lieu de s'afficher en bloc de texte parsemé d'astérisques. Le conteneur
   .esdi-md remplace visuellement .esdi-chat-bubble__content — qui reste dans le
   DOM, masqué : c'est LUI que dmx met à jour, donc notre source de vérité.

   Un seul jeu de couleurs pour la coloration syntaxique : le bloc de code est
   sur fond « Encre Plume » dans LES DEUX thèmes (comme Claude Code / ChatGPT).
   Ça évite une seconde palette à maintenir en dark, et ça détache nettement le
   code du fil de discussion.
   ========================================================================= */

.esdi-md {
  white-space: normal;              /* ≠ .esdi-chat-bubble__content (pre-wrap) : ici c'est du HTML */
  overflow-wrap: anywhere;
  word-break: break-word;
  line-height: 1.62;
  color: var(--ink);
  max-width: 100%;
  font-size: 14.5px;
}
.esdi-md > * { margin: 0; }
.esdi-md > * + * { margin-top: 10px; }
.esdi-md > * + .esdi-md-h { margin-top: 18px; }   /* un titre respire davantage au-dessus */

/* Une réponse structurée mérite plus de largeur qu'une phrase : les bulles qui
   portent un rendu Markdown s'élargissent (un tableau de 5 colonnes dans 78 % de
   la colonne devient illisible). */
.esdi-chat-bubble--assistant:has(.esdi-md) { max-width: 94%; }

/* ----- titres ----- */
.esdi-md-h {
  font-weight: 650;
  line-height: 1.3;
  color: var(--ink);
  letter-spacing: -0.01em;
}
.esdi-md-h--1 { font-size: 17px; }
.esdi-md-h--2 { font-size: 16px; }
.esdi-md-h--3 { font-size: 15px; }
.esdi-md-h--4, .esdi-md-h--5, .esdi-md-h--6 {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--ink-soft);
}
/* Filet sous les titres de premier niveau — repère de section discret. */
.esdi-md-h--1, .esdi-md-h--2 { padding-bottom: 5px; border-bottom: 1px solid var(--line); }

.esdi-md-p { margin: 0; }

/* ----- listes (puces « chevron », numéros en pastille) ----- */
.esdi-md-list { margin: 0; padding: 0; list-style: none; }
.esdi-md-list li { position: relative; padding-left: 22px; }
.esdi-md-list li + li { margin-top: 5px; }
.esdi-md-list .esdi-md-list { margin-top: 5px; }        /* sous-liste collée à son parent */

.esdi-md-list--ul > li::before {
  content: "";
  position: absolute;
  left: 6px;
  top: 0.55em;
  width: 6px;
  height: 6px;
  border-top: 1.6px solid var(--accent-600);
  border-right: 1.6px solid var(--accent-600);
  transform: rotate(45deg);           /* chevron dessiné en CSS : zéro requête, net à tout zoom */
}
.esdi-md-list--ul .esdi-md-list--ul > li::before { opacity: 0.6; }  /* niveau 2 plus discret */

.esdi-md-list--ol { counter-reset: esdi-md-ol; }
.esdi-md-list--ol > li { padding-left: 30px; counter-increment: esdi-md-ol; }
.esdi-md-list--ol > li::before {
  content: counter(esdi-md-ol);
  position: absolute;
  left: 0;
  top: 0.08em;
  width: 20px;
  height: 20px;
  border-radius: 999px;
  background: var(--bg-section-cool);
  color: var(--primary);
  border: 1px solid var(--line);
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 11px;
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Cases à cocher : l'icône Lucide remplace la puce. */
.esdi-md-list--task > li { padding-left: 0; }
.esdi-md-list--task > li::before { content: none; }
.esdi-md-task { display: inline-flex; align-items: flex-start; gap: 7px; }
.esdi-md-task__ico { width: 15px; height: 15px; flex: 0 0 auto; margin-top: 3px; color: var(--ink-faded); }
.esdi-md-task.is-done .esdi-md-task__ico { color: var(--sig-ok); }
.esdi-md-task.is-done > span:last-child { color: var(--ink-faded); text-decoration: line-through; }

/* ----- tableaux ----- */
.esdi-md-tablewrap {
  overflow-x: auto;                  /* un tableau large scrolle DANS la bulle, il n'en sort pas */
  border: 1px solid var(--line);
  border-radius: var(--radius-sm, 8px);
  background: var(--bg-card);
  -webkit-overflow-scrolling: touch;
}
.esdi-md-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
  white-space: nowrap;               /* on préfère scroller que d'empiler les mots dans une cellule */
}
.esdi-md-table th {
  background: var(--bg-section-cool);
  color: var(--ink-soft);
  font-weight: 600;
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  text-align: left;
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
}
.esdi-md-table td { padding: 7px 12px; border-top: 1px solid var(--line); vertical-align: top; }
.esdi-md-table tbody tr:first-child td { border-top: 0; }
.esdi-md-table tbody tr:nth-child(even) { background: color-mix(in srgb, var(--bg-section-cool) 45%, transparent); }
.esdi-md-table tbody tr:hover { background: color-mix(in srgb, var(--accent-500) 8%, transparent); }

/* ----- code ----- */
.esdi-md-code {
  font-family: var(--font-mono, ui-monospace, "Geist Mono", monospace);
  font-size: 0.88em;
  padding: 1px 5px;
  border-radius: 5px;
  background: color-mix(in srgb, var(--accent-500) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent-500) 22%, transparent);
  color: var(--ink);
  overflow-wrap: anywhere;
}

.esdi-md-codeblock {
  border-radius: var(--radius-sm, 8px);
  overflow: hidden;
  border: 1px solid #2c2e42;
  background: #1F2133;               /* Encre Plume — identique en clair et en sombre (cf. en-tête) */
}
.esdi-md-codeblock__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 5px 8px 5px 12px;
  background: rgba(255, 255, 255, 0.05);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.esdi-md-codeblock__lang {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #9aa0bd;
}
.esdi-md-copy {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: transparent;
  color: #c3c7dd;
  border-radius: 999px;
  padding: 2px 10px 2px 8px;
  font-size: 11.5px;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.esdi-md-copy:hover { background: rgba(255, 255, 255, 0.1); color: #fff; }
.esdi-md-copy.is-done { color: var(--sig-ok, #22a06b); border-color: var(--sig-ok, #22a06b); }
.esdi-md-copy__ico { width: 12px; height: 12px; }
.esdi-md-pre {
  margin: 0;
  padding: 12px 14px;
  overflow-x: auto;
  font-family: var(--font-mono, ui-monospace, "Geist Mono", monospace);
  font-size: 12.5px;
  line-height: 1.55;
  color: #e4e6f2;
  tab-size: 2;
}
.esdi-md-pre code { font: inherit; color: inherit; background: none; padding: 0; white-space: pre; }

/* Palette de coloration — pensée pour le fond Encre, donc valable dans les 2 thèmes. */
.esdi-md-t-kw  { color: #79d5e1; }                     /* mots-clés — Cyan ESDI 300 */
.esdi-md-t-str { color: #8fd694; }                     /* chaînes */
.esdi-md-t-num { color: #f0b27a; }                     /* nombres, true/false/null */
.esdi-md-t-fn  { color: #f2d08a; }                     /* appels de fonction */
.esdi-md-t-com { color: #8a8fae; font-style: italic; } /* commentaires */

/* ----- citations & encarts ----- */
.esdi-md-quote {
  margin: 0;
  padding: 2px 0 2px 12px;
  border-left: 3px solid var(--accent-500);
  color: var(--ink-soft);
}
.esdi-md-quote > * + * { margin-top: 8px; }

.esdi-md-callout {
  border: 1px solid var(--line);
  border-left-width: 3px;
  border-radius: var(--radius-sm, 8px);
  padding: 9px 12px;
  background: var(--bg-section-cool);
}
.esdi-md-callout__head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.esdi-md-callout__ico { width: 14px; height: 14px; flex: 0 0 auto; }
.esdi-md-callout__body { margin-top: 5px; }
.esdi-md-callout__body > * + * { margin-top: 8px; }

.esdi-md-callout--note      { background: var(--sig-ai-bg);    border-color: var(--sig-ai); }
.esdi-md-callout--note      .esdi-md-callout__head { color: var(--sig-ai-text); }
.esdi-md-callout--tip       { background: var(--sig-ok-bg);    border-color: var(--sig-ok); }
.esdi-md-callout--tip       .esdi-md-callout__head { color: var(--sig-ok-text); }
.esdi-md-callout--important { background: var(--primary-50);   border-color: var(--primary); }
.esdi-md-callout--important .esdi-md-callout__head { color: var(--primary); }
.esdi-md-callout--warning   { background: var(--sig-warn-bg);  border-color: var(--sig-warn); }
.esdi-md-callout--warning   .esdi-md-callout__head { color: var(--sig-warn-text); }
.esdi-md-callout--caution   { background: var(--sig-alert-bg); border-color: var(--sig-alert); }
.esdi-md-callout--caution   .esdi-md-callout__head { color: var(--sig-alert-text); }

/* ----- divers ----- */
.esdi-md-hr { border: 0; border-top: 1px solid var(--line); margin: 14px 0; opacity: 0.9; }

.esdi-md-link { color: var(--primary); text-decoration: none; border-bottom: 1px solid transparent; }
.esdi-md-link:hover { color: var(--primary-600); border-bottom-color: currentColor; }
.esdi-md-link__ico { width: 11px; height: 11px; margin-left: 2px; vertical-align: -1px; opacity: 0.7; }

/* Lien vers un document de l'espace de travail : il ouvre un FICHIER, pas une page — il doit se
   reconnaître comme tel (l'icône est devant, et le lien se pose comme une pastille cliquable). */
.esdi-md-link--doc {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px 3px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill, 999px);
  background: var(--bg-section-cool);
  border-bottom-color: var(--line);
  font-weight: 500;
}
.esdi-md-link--doc:hover { border-color: var(--accent-500); background: color-mix(in srgb, var(--accent-500) 10%, var(--bg-section-cool)); }
.esdi-md-link__ico--lead { margin-left: 0; opacity: 1; color: var(--accent-600); width: 13px; height: 13px; }

.esdi-md-arrow { color: var(--accent-600); font-weight: 600; padding: 0 1px; }

.esdi-md-img {
  max-width: 100%;
  height: auto;
  border-radius: var(--radius-sm, 8px);
  border: 1px solid var(--line);
  display: block;
}

.esdi-md strong { font-weight: 650; color: var(--ink); }
.esdi-md del { color: var(--ink-faded); }

/* Repli des réponses très longues : même mécanique que le contenu texte
   (esdiEnhanceBubbles pose .esdi-clamp sur le conteneur rendu, pas sur la source), mais
   beaucoup plus permissive — une réponse mise en page a le droit d'être longue ; le repli
   n'est là que pour les cas extrêmes (seuil de déclenchement dans views/chat/index.ejs). */
.esdi-md.esdi-clamp.is-clamped {
  max-height: 820px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 72px), transparent);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 72px), transparent);
}

/* ============================================================================
   Épique 29-6 — page « Le profil de votre entreprise ».
   L'assistant en quatre écrans devient une page en cartes : on voit tout, on
   remplit dans l'ordre qu'on veut, on enregistre par section.
   ============================================================================ */
.esdi-profil-tete {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 20px;
    margin: 8px 0 18px;
}
.esdi-profil-tete__texte { flex: 1 1 320px; min-width: 0; }

.esdi-profil-jauge {
    flex: 0 0 210px;
    padding: 12px 14px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--bg-soft, rgba(0, 0, 0, .02));
}
.esdi-profil-jauge__chiffre {
    font-family: var(--font-mono, "Geist Mono", monospace);
    font-size: 26px;
    font-weight: 700;
    line-height: 1;
    color: var(--primary, #1b5aa8);
}
.esdi-profil-jauge__pct { font-size: 15px; opacity: .7; margin-left: 1px; }
.esdi-profil-jauge__barre {
    height: 5px;
    border-radius: 3px;
    background: var(--line);
    overflow: hidden;
    margin: 8px 0 6px;
}
.esdi-profil-jauge__barre span {
    display: block;
    height: 100%;
    border-radius: 3px;
    background: linear-gradient(135deg, #3fbecc, #1b5aa8);
    transition: width .35s ease;
}
.esdi-profil-jauge__legende { font-size: 12px; color: var(--muted); }

/* Le raccourci vers l'entretien : présent mais discret — c'est une alternative, pas une injonction. */
.esdi-profil-discuter {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border: 1px dashed var(--accent, #3fbecc);
    border-radius: 12px;
    text-decoration: none;
    color: inherit;
    background: rgba(63, 190, 204, .05);
    transition: background .15s ease;
}
.esdi-profil-discuter:hover { background: rgba(63, 190, 204, .11); color: inherit; }
.esdi-profil-discuter__ico { color: var(--primary, #1b5aa8); display: inline-flex; }

.esdi-profil-cartes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
    gap: 16px;
    margin-top: 18px;
}
.esdi-profil-carte {
    border: 1px solid var(--line);
    border-radius: 14px;
    background: var(--bg);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
.esdi-profil-carte__tete {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--line);
}
.esdi-profil-carte__ico {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 9px;
    background: rgba(63, 190, 204, .12);
    color: var(--primary, #1b5aa8);
}
.esdi-profil-carte__corps { padding: 14px 16px; flex-grow: 1; }
.esdi-profil-carte__pied {
    padding-top: 6px;
    display: flex;
    justify-content: flex-end;
}

.esdi-profil-champ { margin-bottom: 16px; }
.esdi-profil-champ__label {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 600;
    margin-bottom: 5px;
}
.esdi-profil-champ__essentiel {
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    padding: 1px 6px;
    border-radius: 20px;
    background: rgba(63, 190, 204, .16);
    color: var(--primary, #1b5aa8);
}
.esdi-profil-champ__vide {
    font-size: 11px;
    color: #b8860b;
    font-weight: 500;
}
.esdi-profil-champ__saisie { font-size: 13.5px; }
/* L'effet est en dessous, pas en infobulle : une explication qu'il faut aller chercher n'est pas lue. */
.esdi-profil-champ__effet {
    font-size: 11.5px;
    color: var(--muted);
    margin: 5px 0 0;
    line-height: 1.45;
}

/* ----- Épique 29-6 : la carte se LIT, la modale ÉDITE (demande Kevin 2026-08-02) ----- */
.esdi-profil-carte__modifier { flex-shrink: 0; }
.esdi-profil-carte__lecture { padding: 6px 16px 16px; }

.esdi-profil-lu {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 8px 0;
    border-bottom: 1px solid var(--line);
}
.esdi-profil-lu:last-child { border-bottom: 0; }
.esdi-profil-lu__label {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12px;
    color: var(--muted);
}
.esdi-profil-lu__valeur {
    font-size: 13.5px;
    line-height: 1.45;
    white-space: pre-wrap;      /* une signature tient sur trois lignes : on les garde */
    overflow-wrap: anywhere;
}
.esdi-profil-lu__vide {
    font-size: 12.5px;
    font-style: italic;
    color: #b8860b;
}

/* La modale : jamais un composant Bootstrap natif ici (cf. antipatterns #15/#17) — un simple voile
   plus une boîte, présents dès le rendu et masqués par dmx-show. */
.esdi-modale {
    position: fixed;
    inset: 0;
    z-index: 1080;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.esdi-modale__fond {
    position: absolute;
    inset: 0;
    background: rgba(10, 12, 20, .5);
    backdrop-filter: blur(2px);
}
.esdi-modale__boite {
    position: relative;
    z-index: 1;
    width: min(620px, 100%);
    max-height: 88vh;
    display: flex;
    flex-direction: column;
    background: var(--bg);
    border-radius: 16px;
    box-shadow: 0 24px 70px rgba(0, 0, 0, .3);
    overflow: hidden;
}
.esdi-modale__tete {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 16px 18px;
    border-bottom: 1px solid var(--line);
}
.esdi-modale__tete > .min-w-0 { flex-grow: 1; }
.esdi-modale__fermer {
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--muted);
    font-size: 16px;
    line-height: 1;
}
.esdi-modale__fermer:hover { background: var(--line); color: var(--fg); }
.esdi-modale__corps {
    padding: 16px 18px;
    overflow-y: auto;           /* c'est le CORPS qui défile, jamais la page derrière */
    flex-grow: 1;
}
.esdi-modale__pied {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 12px 18px;
    border-top: 1px solid var(--line);
}
/* Épique 29 (correctif 2026-08-02) : l'alerte « il reste des essentielles » dans la jauge. */
.esdi-profil-jauge__alerte { color: #b8860b; font-weight: 600; }

/* ============================================================================
   RAPPORTS D'AUTOMATISATION (2026-08-06) — la carte-rapport de /automations
   (onglet Rapports) et de la fiche /automations/:id. Un compte rendu d'équipe
   qu'on LIT, pas une ligne de journal. Rendu par /js/esdi-rapport.js
   (source .esdi-rapport-src masquée + frère .esdi-md--rapport).
   ============================================================================ */
/* ⚠️ La carte hérite de .esdi-connector-installed-row, qui est une GRILLE à trois
   colonnes (icône | contenu | bouton) : les utilitaires flex-column n'y font RIEN,
   et le rapport tombait dans la colonne du milieu (~140 px) — texte replié tous les
   deux mots, sections qui se chevauchent (constaté par Kevin le 2026-08-05). La
   carte-rapport impose donc SON flux : une colonne pleine largeur. */
.esdi-rapport-card { display: flex; flex-direction: column; align-items: stretch; }

/* Un run non lu porte un liseré (le bleu de la pastille) : l'œil trouve en un
   balayage ce qui est nouveau. */
.esdi-rapport-card--nouveau { border-left: 3px solid var(--esdi-blue, #1b5aa8); }
/* « C'est celle-ci » (35-13a) — halo bref après un lien profond depuis la cloche. Le défilement
   seul ne suffit pas : sur une liste de cartes qui se ressemblent, l'œil ne sait pas laquelle on
   vient de lui montrer. Il s'efface tout seul — un surlignage permanent deviendrait du bruit. */
.esdi-rapport-card--vise {
    animation: esdi-vise 2.6s ease-out;
    border-left: 3px solid var(--esdi-cyan, #3fbecc);
}
@keyframes esdi-vise {
    0%   { background: rgba(63, 190, 204, .22); }
    70%  { background: rgba(63, 190, 204, .12); }
    100% { background: transparent; }
}
/* Un mouvement qui n'apporte rien à qui l'a désactivé : la carte reste simplement désignée. */
@media (prefers-reduced-motion: reduce) {
    .esdi-rapport-card--vise { animation: none; background: rgba(63, 190, 204, .12); }
}

/* ⏳ Le bloc des décisions : ce que l'équipe a préparé et qui n'attend qu'un
   feu vert — Valider / Relire / Refuser se font SUR le rapport. */
.esdi-rapport-decisions {
    border: 1px solid rgba(27, 90, 168, .25);
    border-radius: .5rem;
    background: rgba(63, 190, 204, .06);
    padding: .5rem .65rem;
}
.esdi-rapport-decisions__titre {
    font-size: .74rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--esdi-blue, #1b5aa8);
    margin-bottom: .35rem;
}
/* « Toutes prises depuis » (35-10) — VERT, et volontairement plus discret que le bloc en attente :
   c'est une mise au point sur un rapport périmé, pas une action à mener. Le mode sombre est déclaré
   ici même : un `#fff` en dur ou une couleur claire non surchargée devient illisible dessus — piège
   déjà payé sur ce fichier. */
.esdi-rapport-decisions--prises {
    border-color: rgba(25, 135, 84, .3);
    background: rgba(25, 135, 84, .07);
}
.esdi-rapport-decisions--prises .esdi-rapport-decisions__titre { color: #146c43; }
[data-theme="dark"] .esdi-rapport-decisions--prises {
    border-color: rgba(75, 190, 140, .35);
    background: rgba(75, 190, 140, .10);
}
[data-theme="dark"] .esdi-rapport-decisions--prises .esdi-rapport-decisions__titre { color: #6ee7b7; }
/* « Ce qui a coincé » (35-12e) — ambre : ni le vert du fait accompli, ni le rouge d'une panne
   fatale. La plupart de ces accrocs sont des itérations perdues sur un run qui a par ailleurs
   travaillé ; les peindre en rouge ferait lire un échec là où il y a un résultat partiel. */
.esdi-rapport-decisions--accroc {
    border-color: rgba(197, 129, 0, .3);
    background: rgba(255, 193, 7, .08);
}
.esdi-rapport-decisions--accroc .esdi-rapport-decisions__titre { color: #8a6100; }
[data-theme="dark"] .esdi-rapport-decisions--accroc {
    border-color: rgba(255, 193, 7, .35);
    background: rgba(255, 193, 7, .10);
}
[data-theme="dark"] .esdi-rapport-decisions--accroc .esdi-rapport-decisions__titre { color: #fcd34d; }
/* « 4ᵉ fois d'affilée » (35-12c) — une panne qui DURE ne se lit pas comme une panne du jour. Le badge
   monte d'un cran en intensité par rapport à l'ambre du bloc : c'est l'information qui doit accrocher
   l'œil dans une liste d'accrocs, pas l'accroc lui-même. */
.esdi-badge-recurrent {
    display: inline-block;
    margin-left: .3rem;
    padding: .02rem .3rem;
    border: 1px solid rgba(197, 129, 0, .45);
    border-radius: 6px;
    background: rgba(255, 193, 7, .18);
    color: #7a5500;
    font-size: .72rem;
    font-weight: 600;
    white-space: nowrap;
    vertical-align: 1px;
}
[data-theme="dark"] .esdi-badge-recurrent {
    border-color: rgba(255, 193, 7, .5);
    background: rgba(255, 193, 7, .16);
    color: #fcd34d;
}
.esdi-rapport-decision { padding: .3rem 0; }
.esdi-rapport-decision + .esdi-rapport-decision { border-top: 1px dashed rgba(27, 90, 168, .18); }
.esdi-rapport-decision__apercu {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin-top: .1rem;
}

/* « supprimée » (35-14c) — l'automatisation n'existe plus, son compte rendu si. Gris neutre : ce
   n'est ni une alerte ni un échec, c'est un état de l'historique. */
.esdi-chip--efface {
    border-color: rgba(120, 120, 120, .35);
    background: rgba(120, 120, 120, .10);
    color: #6b7280;
    font-size: .7rem;
}
[data-theme="dark"] .esdi-chip--efface { color: #9ca3af; background: rgba(160, 160, 160, .12); }

/* 📕 Le compte rendu replié (35-13c) — le chevron doit se lire comme un bouton, pas comme un titre :
   sans indice cliquable, on ne déplie pas ce qu'on ne sait pas dépliable. */
.esdi-rapport-pli { margin-bottom: .35rem; }
.esdi-rapport-pli__resume {
    cursor: pointer;
    display: inline-block;
    padding: .1rem .45rem .1rem .15rem;
    border-radius: .35rem;
    user-select: none;
}
.esdi-rapport-pli__resume:hover { color: var(--esdi-blue, #1b5aa8); background: rgba(27, 90, 168, .06); }
[data-theme="dark"] .esdi-rapport-pli__resume:hover { color: var(--esdi-cyan, #3fbecc); background: rgba(63, 190, 204, .10); }
.esdi-rapport-pli[open] > .esdi-rapport-pli__resume { margin-bottom: .2rem; }

/* Le rapport respire. */
.esdi-md--rapport { font-size: .86rem; line-height: 1.6; margin: .35rem 0 .6rem; }
.esdi-md--rapport h2, .esdi-md--rapport h3 {
    font-size: .82rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--ink-faded, #8F92A6);
    margin: .9rem 0 .35rem;
}
.esdi-md--rapport ul, .esdi-md--rapport ol { margin: .2rem 0 .5rem; padding-left: 1.1rem; }
.esdi-md--rapport li { margin-bottom: .15rem; }
.esdi-md--rapport p { margin-bottom: .45rem; }
.esdi-md--rapport hr { margin: .7rem 0; opacity: .35; }
.esdi-md--rapport code { font-size: .8em; }

/* ══ Story 31-22 — LA SOCIÉTÉ, TOUJOURS AFFICHÉE ═══════════════════════════════════════════════
   Une seule société → un libellé (aucun menu : un choix unique n'est pas un choix). Deux ou plus →
   le sélecteur de 15.5. Les DEUX vivent au même endroit, contre le fil d'Ariane : sinon « où
   suis-je » change de coin d'écran selon le compte, et il faut apprendre deux interfaces. */
.esdi-societe {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    min-width: 0;                       /* sans quoi un nom long pousse la topbar au lieu de se tronquer */
    padding: .15rem .5rem;
    border-radius: 99px;
    background: var(--bg-subtle, #F3F0EA);
    color: var(--ink-soft, #555870);
    font-size: .78rem;
    font-weight: 600;
}
.esdi-societe svg { width: 14px; height: 14px; flex: 0 0 auto; }
.esdi-societe__nom {
    min-width: 0;
    max-width: 22ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.esdi-societe-choix { flex: 0 1 auto; min-width: 0; }

/* En très petit écran, le nom s'efface : l'icône suffit à dire qu'on est dans une société, et la
   place manque déjà (la topbar débordait de ~180 px sur 375 px avant le fix du 2026-07-14). */
@media (max-width: 575.98px) {
    .esdi-societe__nom { display: none; }
}
