/* PLAKA — Mobile First */
:root {
    --bg: #e8eaee;
    --bg-card: #ffffff;
    --bg-input: #dfe3e9;
    --bg-hover: #dbdfe6;
    --border: #cfd4dc;
    --text: #0a0c10;
    --text-muted: #4a5261;
    --primary: #14456f;
    --primary-hover: #0f3557;
    /* Encre à poser SUR un aplat `--primary`. Chaque thème la choisit avec sa
       teinte : blanche sur un bleu d'encre, sombre sur un bleu clair — sinon le
       libellé du bouton principal passe sous 3:1. */
    --primary-ink: #ffffff;
    /* Encre des usages TEXTE de la couleur de marque — un libellé, une légende,
       un lien. Distincte de `--primary-ink`, qui s'écrit sur un aplat : celle-ci
       s'écrit sur le fond de la page. Un thème dont la marque ne tient pas 4,5:1
       en encre la redéfinit ; les autres la laissent suivre `--primary`. */
    --accent-ink: var(--primary);
    /* La barre d'actions ancrée, mesurée et publiée par `plk_bar.js` : sa
       hauteur varie avec la largeur ET le nombre d'actions de l'écran, sa
       position avec le défilement. Ce qu'elle recouvre se lit sur elle, jamais
       sur une constante. Les deux valent 0 sur un écran qui n'en porte pas. */
    --plk-bar-h: 0px;      /* sa hauteur — réserve sous le contenu */
    --plk-bar-socle: 0px;  /* la bande basse qu'elle occupe durablement */
    --success: #24664a;
    --error: #8f3729;
    --radius: 10px;
    --topbar-h: 48px;
    /* 16 templates appellent `--card` et `--text-dim` avec un repli en dur
       (`var(--card, #151c26)`, `var(--text-dim, #97a3b2)`) : ces deux-là
       doivent donc rester définies ici, sinon le repli sombre l'emporte. */
    --card: var(--bg-card);
    --text-dim: var(--text-muted);
    --accent: #14456f;
    --accent-soft: rgba(20, 69, 111, 0.11);
    --hair: rgba(10, 12, 16, 0.14);
    --sb-bg: #e1e5ea;
}

/* ── Thèmes ──────────────────────────────────────────────────────────────
   Posé par base_admin.html sur <html data-theme="…"> (localStorage
   `plaka_theme`, choisi dans /admin/settings, mémorisé par appareil).
   Sans attribut, les valeurs :root ci-dessus s'appliquent — elles sont
   claires. Tout le CSS de l'app étant écrit en variables, un thème = un jeu
   d'overrides. */

:root[data-theme="jour"] {
    --text-dim: var(--text-muted);
    --bg: #e9edf4;
    --bg-card: #ffffff;
    --bg-input: #e6eaf2;
    --bg-hover: #dde3ee;
    --border: #c6cddd;
    --text: #171c2b;
    --text-muted: #5c6380;
    --primary: #2f5ed4;
    --primary-hover: #2549ad;
    --primary-ink: #ffffff;
    --success: #0d8f5a;
    --error: #c94a49;
    --accent: #2f5ed4;
    --accent-soft: rgba(47, 94, 212, 0.11);
    --hair: rgba(23, 28, 60, 0.14);
    --sb-bg: #f6f8fc;
}
/* Jour : sur fond clair les hairlines ne suffisent plus — ombres franches. */
[data-theme="jour"] .ck-vips, [data-theme="jour"] .ck-feed,
[data-theme="jour"] .ck-ords, [data-theme="jour"] .ck-paycard,
[data-theme="jour"] .pipe-card, [data-theme="jour"] .notif-card,
[data-theme="jour"] .ck-tile, [data-theme="jour"] .ck-ordrow.go {
    box-shadow: 0 1px 3px rgba(23, 28, 60, 0.10), 0 1px 2px rgba(23, 28, 60, 0.06);
}

:root[data-theme="joy"] {
    --text-dim: var(--text-muted);
    --bg: #fff6ec;
    --bg-card: #ffffff;
    --bg-input: #ffefdd;
    --bg-hover: #ffe8d2;
    --border: #f6d9bd;
    --text: #43284b;
    /* 3,08:1 sur --bg et 2,78:1 sur --bg-hover : le texte atténué était sous
       le seuil sur les QUATRE surfaces claires du thème, soit 582 des 1 481
       occurrences relevées. Même teinte mauve, luminosité descendue jusqu'à
       4,5:1 sur la plus sombre d'entre elles. */
    --text-muted: #836079;
    --primary: #ff5f7e;
    --primary-hover: #f24b6d;
    /* 2,65:1 en encre sur blanc — même teinte, luminosité descendue */
    --success: #157d50;
    /* 3,49:1 en encre sur blanc — même teinte, luminosité descendue */
    --error: #da1814;
    --accent: #ff5f7e;
    --accent-soft: rgba(255, 95, 126, 0.13);
    --hair: rgba(150, 80, 60, 0.14);
    --sb-bg: #fffaf4;
    --radius: 14px;
}
/* Joy : l'énergie candy — gradient en topbar, actifs pêchus, ombres chaudes,
   arrondis plus francs. Équilibre volontaire : structure, densité et zéro
   animation parasite — c'est un outil, pas un jeu. */
[data-theme="joy"] .topbar {
    background: linear-gradient(90deg, #ff5f7e 0%, #ff8a5c 55%, #ffb648 100%);
    border-bottom: none;
}
[data-theme="joy"] .topbar .wm-name, [data-theme="joy"] .topbar .wm-os,
[data-theme="joy"] .topbar .btn-ghost { color: #fff; }
[data-theme="joy"] .topbar .sbp-hint-k { color: rgba(255, 255, 255, 0.92); border-color: rgba(255,255,255,0.4); }
[data-theme="joy"] .topbar .hamburger span { background: #fff; }
[data-theme="joy"] .sb-item.active {
    background: linear-gradient(90deg, rgba(255, 95, 126, 0.16), rgba(255, 182, 72, 0.13));
    border-left-color: #ff5f7e;
}
[data-theme="joy"] .ck-vips, [data-theme="joy"] .ck-feed,
[data-theme="joy"] .ck-ords, [data-theme="joy"] .ck-paycard,
[data-theme="joy"] .pipe-card, [data-theme="joy"] .notif-card,
[data-theme="joy"] .ck-tile, [data-theme="joy"] .ck-ordrow.go {
    box-shadow: 0 2px 10px rgba(255, 120, 90, 0.10);
}
[data-theme="joy"] .ck-hello-line {
    background: linear-gradient(90deg, #ff5f7e, #ff8a5c 45%, #b64bd8);
    -webkit-background-clip: text; background-clip: text; color: transparent;
    width: fit-content;
}
[data-theme="joy"] .ck-zen {
    color: #0e8f5a; border-color: rgba(31, 181, 115, 0.4);
    background: rgba(31, 181, 115, 0.07);
}
[data-theme="joy"] .ck-pill.sent { color: #0e8f5a; background: rgba(31, 181, 115, 0.14); }
[data-theme="joy"] .ck-pill.pending { color: #2b6fd8; background: rgba(80, 140, 235, 0.13); }

* { margin: 0; padding: 0; box-sizing: border-box; }

/* Masque les éléments Alpine tant que l'init n'a pas retiré l'attribut
   (sinon l'UI est visible/tappable avant que les @click soient attachés). */
[x-cloak] { display: none !important; }

body.dark {
    background: var(--bg);
    color: var(--text);
    font-family: -apple-system, BlinkMacSystemFont, 'SF Pro', 'Segoe UI', sans-serif;
    font-size: 15px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
    overscroll-behavior: none;
}

/* Topbar */
.topbar {
    height: var(--topbar-h);
    background: var(--bg-card);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 1rem;
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 100;
}
.topbar-left { display: flex; align-items: center; gap: 0.5rem; flex: 1; min-width: 0; }
.topbar-links {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
}
.topbar-links::-webkit-scrollbar { display: none; }
.topbar-right { display: flex; align-items: center; flex-shrink: 0; margin-left: 0.5rem; }
.logo { font-weight: 700; font-size: 1.1rem; color: var(--primary); letter-spacing: 1px; }
.logo-img { height: 20px; width: auto; filter: brightness(0); opacity: 0.86; }
.nav-sep { color: var(--border); }
.nav-link { color: var(--text-muted); text-decoration: none; padding: 0.25rem 0.5rem; font-size: 0.9rem; white-space: nowrap; flex-shrink: 0; }
.nav-link.active { color: var(--text); }

/* Hamburger button — mobile only */
.hamburger {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 5px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 6px;
    -webkit-tap-highlight-color: transparent;
}
.hamburger span {
    display: block;
    width: 20px;
    height: 2px;
    background: var(--text);
    border-radius: 2px;
    transition: transform 0.25s, opacity 0.2s;
}
.hamburger.active span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.hamburger.active span:nth-child(2) { opacity: 0; }
.hamburger.active span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Mobile menu overlay */
.mobile-menu {
    display: none;
    position: fixed;
    inset: 0;
    top: var(--topbar-h);
    background: rgba(0,0,0,0.6);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    z-index: 99;
    opacity: 0;
    transition: opacity 0.25s;
    pointer-events: none;
}
.mobile-menu.open { opacity: 1; pointer-events: auto; }
.mobile-menu-inner {
    background: var(--bg-card);
    border-bottom: 1px solid var(--border);
    padding: 8px 0;
    max-height: calc(100vh - var(--topbar-h));
    overflow-y: auto;
}
.mobile-menu-link {
    display: block;
    padding: 14px 24px;
    color: var(--text);
    text-decoration: none;
    font-size: 1rem;
    font-weight: 500;
    transition: background 0.15s;
    -webkit-tap-highlight-color: transparent;
}
.mobile-menu-link:active { background: var(--bg-hover); }
.mobile-menu-link.active { color: var(--primary); }
.mobile-menu-sep { height: 1px; background: var(--border); margin: 8px 24px; }
.mobile-menu-logout { color: var(--text-muted); }

/* Mobile breakpoint */
@media (max-width: 768px) {
    .topbar-links { display: none; }
    .topbar-logout-desktop { display: none; }
    .hamburger { display: flex; }
    .mobile-menu { display: block; }
}

.container { margin-top: var(--topbar-h); }

/* Wizard */
.wizard {
    max-width: 600px;
    margin: 0 auto;
    /* La barre d'actions est le dernier enfant, et `sticky` la laisse dans le
       flux : sa propre boîte réserve déjà sa hauteur en fin de contenu. Il ne
       reste à poser ici que le blanc entre le dernier champ et elle. */
    padding-bottom: var(--sp-5);
    min-height: calc(100vh - var(--topbar-h));
}
@media (min-width: 900px) {
    .wizard { max-width: 700px; }
}

/* Step dots */
.steps-bar {
    display: flex;
    justify-content: center;
    gap: 8px;
    padding: 16px 16px 4px;
}
.step-dot {
    width: 32px; height: 32px;
    border-radius: 50%;
    border: 2px solid var(--border);
    background: none;
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s;
    display: flex;
    align-items: center;
    justify-content: center;
}
.step-dot.active { border-color: var(--primary); background: var(--primary); color: var(--primary-ink); }
.step-dot.done { border-color: var(--success); background: rgba(52,211,153,0.15); color: var(--success); }

.step-title {
    text-align: center;
    font-size: 0.85rem;
    color: var(--text-muted);
    padding: 4px 0 12px;
    text-transform: uppercase;
    letter-spacing: 1px;
}

/* Step panel */
.step-panel { padding: 0 16px; }

/* Forms */
.form-stack {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.form-stack label {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 0.85rem;
    color: var(--text-muted);
    font-weight: 500;
}
.form-row {
    display: flex;
    gap: 10px;
}
.flex-1 { flex: 1; }
.flex-2 { flex: 2; }

.input {
    background: var(--bg-input);
    border: 1px solid var(--border);
    color: var(--text);
    padding: 12px 14px;
    border-radius: var(--radius);
    font-size: 16px; /* prevents iOS zoom */
    outline: none;
    transition: border-color 0.15s;
    width: 100%;
    -webkit-appearance: none;
}
.input:focus { border-color: var(--primary); }
.input-error { border-color: var(--error, #ef4444) !important; background: rgba(239, 68, 68, 0.05); }
.textarea { resize: vertical; font-family: inherit; min-height: 60px; }
.checkbox-label {
    flex-direction: row !important;
    align-items: center;
    gap: 10px !important;
    cursor: pointer;
    font-size: 0.95rem !important;
    color: var(--text) !important;
}
.checkbox-label input[type="checkbox"] { width: 20px; height: 20px; }

.step-hint {
    color: var(--text-muted);
    font-size: 0.9rem;
    margin-bottom: 16px;
    line-height: 1.5;
}

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 12px 20px;
    border: none;
    /* Sans fond déclaré, un .btn sans variante prend celui du bouton natif du
       navigateur (#EFEFEF) : sur un thème sombre, l'encre claire y disparaît. */
    background: var(--bg-input);
    border-radius: var(--radius);
    cursor: pointer;
    font-size: 16px;
    font-weight: 600;
    transition: all 0.15s;
    text-decoration: none;
    color: var(--text);
    -webkit-tap-highlight-color: transparent;
}
/* Un geste indisponible reste LISIBLE : aplat neutre et encre secondaire.
   Une opacité efface le libellé en même temps que le fond. */
.btn:disabled {
    background: var(--bg-hover);
    border-color: var(--border);
    color: var(--text-muted);
    cursor: not-allowed;
}
.btn-primary { background: var(--primary); color: var(--primary-ink); }
.btn-primary:active:not(:disabled) { background: var(--primary-hover); transform: scale(0.98); }
.btn-secondary { background: var(--bg-input); border: 1px solid var(--border); }
.btn-secondary:active { background: var(--bg-hover); }
.btn-ghost { background: none; color: var(--text-muted); padding: 8px 12px; font-size: 14px; }
.btn-sm { padding: 8px 14px; font-size: 14px; }
.btn-lg { padding: 14px 24px; font-size: 17px; }
.btn-full { width: 100%; }
.btn-create { background: var(--success); color: #000; font-weight: 700; }
.btn-create:active:not(:disabled) { background: #2bb87f; transform: scale(0.98); }

/* Bottom nav */
.wizard-nav {
    position: fixed;
    bottom: 0; left: 0; right: 0;
    background: var(--bg-card);
    border-top: 1px solid var(--border);
    padding: 12px 16px;
    padding-bottom: max(12px, env(safe-area-inset-bottom));
    display: flex;
    gap: 10px;
    z-index: 100;
    max-width: 500px;
    margin: 0 auto;
}

/* Alerts */
.alert {
    padding: 10px 14px;
    border-radius: var(--radius);
    margin: 0 16px 12px;
    font-size: 0.9rem;
}
.alert-error { background: rgba(248,113,113,0.12); color: var(--error); border: 1px solid rgba(248,113,113,0.25); }
.alert-success { background: rgba(52,211,153,0.12); color: var(--success); border: 1px solid rgba(52,211,153,0.25); }

/* Warning banners (event_detail warnings) — dark-mode friendly */
.warning-banner-critical   { background: rgba(248,113,113,0.10); border-left: 4px solid var(--error);   color: var(--error); }
.warning-banner-warning    { background: rgba(245,158,11,0.10);  border-left: 4px solid var(--role-warn-ink); color: var(--role-warn-ink); }
.warning-banner-suggestion { background: rgba(79,140,255,0.10);  border-left: 4px solid var(--primary); color: var(--primary); }

/* Product search */
.product-search { position: relative; margin-bottom: 12px; margin-top: 16px; }
.input-search { padding-left: 14px; font-size: 16px; }
.dropdown {
    position: absolute;
    top: 100%;
    left: 0; right: 0;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    max-height: 50vh;
    overflow-y: auto;
    z-index: 110;
    box-shadow: 0 12px 40px rgba(0,0,0,0.5);
}
.dropdown-item {
    display: flex;
    flex-direction: column;
    width: 100%;
    padding: 12px 14px;
    border: none;
    background: none;
    color: var(--text);
    cursor: pointer;
    text-align: left;
    border-bottom: 1px solid var(--border);
    -webkit-tap-highlight-color: transparent;
}
.dropdown-item:last-child { border-bottom: none; }
.dropdown-item:active { background: var(--bg-hover); }
/* Entrée « créer » : proposée quand la recherche ne rend rien. Se distingue
   d'un résultat de catalogue sans crier — c'est une action, pas un produit. */
.dropdown-item-create { border-top: 1px solid var(--border); }
.dropdown-item-create .dd-name { color: var(--accent, #89b4fa); font-weight: 600; }
.dd-name { font-weight: 500; font-size: 0.95rem; }
.dd-meta { font-size: 0.8rem; color: var(--text-muted); margin-top: 2px; }

/* Product lines */
.lines-list { display: flex; flex-direction: column; gap: 8px; }
.line-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 10px 12px;
}
.line-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 8px;
}
.line-name { font-weight: 500; font-size: 0.9rem; flex: 1; padding-right: 8px; }
.btn-del {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 22px;
    cursor: pointer;
    padding: 0 4px;
    line-height: 1;
    -webkit-tap-highlight-color: transparent;
}
.btn-del:active { color: var(--error); }
.pack-badge {
    font-size: 0.7rem;
    color: var(--primary);
    background: rgba(79,140,255,0.1);
    padding: 1px 6px;
    border-radius: 10px;
    margin-left: 4px;
}
.btn-replace {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 16px;
    cursor: pointer;
    padding: 0 4px;
    -webkit-tap-highlight-color: transparent;
}
.btn-replace:active { color: var(--primary); }
.replace-search { margin-bottom: 6px; position: relative; }
.input-search-sm { padding: 8px 10px; font-size: 14px; }
.split-item { display: inline-flex; align-items: center; gap: 3px; margin-right: 8px; font-size: 0.85rem; }
.input-hyp-sm {
    width: 40px;
    text-align: center;
    padding: 3px 4px;
    font-size: 13px;
    border-radius: 4px;
    background: var(--bg);
    border: 1px solid rgba(79,140,255,0.3);
    color: var(--text);
}

.line-bottom {
    display: flex;
    align-items: center;
    gap: 8px;
}
/* Steppers quantité = pilule segmentée « ghost » (devis editor uniquement).
   Un seul bloc arrondi, nombre au centre, −/+ estompés qui s'allument au survol,
   halo de focus à l'édition, micro-scale au clic. */
.qty-ctrl, .qty-pers {
    display: inline-flex;
    align-items: center;
    gap: 0;
    height: 30px;
    border: 1px solid var(--border);
    border-radius: 9px;
    background: var(--bg-input);
    overflow: hidden;
    transition: border-color .15s, box-shadow .15s;
}
.qty-ctrl:focus-within, .qty-pers:focus-within {
    border-color: var(--primary);
    box-shadow: 0 0 0 2px rgba(79,140,255,0.18);
}
.qty-ctrl .btn-round, .qty-pers .btn-round {
    width: 26px; height: 100%;
    border: none; border-radius: 0; background: transparent;
    color: var(--text-muted); font-size: 16px;
    transition: background .12s, color .12s, transform .08s;
}
.qty-ctrl .btn-round:hover, .qty-pers .btn-round:hover { background: var(--bg-hover); color: var(--text); }
.qty-ctrl .btn-round:active, .qty-pers .btn-round:active { transform: scale(0.86); background: var(--bg-hover); }
.qty-ctrl .input-qty, .qty-pers .input-qty { border: none; background: transparent; width: 40px; }
.qty-pers .price-label { padding: 0 6px 0 2px; font-size: 0.68rem; color: var(--text-muted); white-space: nowrap; }
.btn-round {
    width: 36px; height: 36px;
    border-radius: 6px;
    border: 1px solid var(--border);
    background: var(--bg-input);
    color: var(--text);
    font-size: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.btn-round:active { background: var(--bg-hover); }
.input-qty {
    width: 50px;
    text-align: center;
    border: none;
    background: none;
    color: var(--text);
    font-size: 16px;
    font-weight: 600;
    padding: 4px;
    -moz-appearance: textfield;
}
.input-qty::-webkit-inner-spin-button,
.input-qty::-webkit-outer-spin-button { -webkit-appearance: none; }

.line-price {
    display: flex;
    align-items: center;
    gap: 2px;
}
/* .qty-pers : stylé avec .qty-ctrl ci-dessus (pilule segmentée). */
.input-price {
    width: 60px;
    text-align: right;
    padding: 6px 4px;
    font-size: 14px;
    border-radius: 6px;
}
.price-label { font-size: 0.75rem; color: var(--text-muted); }
.line-total {
    font-weight: 700;
    font-size: 0.95rem;
    margin-left: auto;
    white-space: nowrap;
}

.empty-msg { color: var(--text-muted); text-align: center; padding: 2rem 0; }

/* Floating totals */
.totals-floating {
    display: flex;
    justify-content: center;
    gap: 16px;
    padding: 6px 16px;
    font-size: 0.85rem;
    color: var(--text-muted);
    margin-bottom: 4px;
}
.totals-floating strong { color: var(--text); }

/* Section header */
.section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 0;
    font-size: 0.85rem;
    color: var(--text-muted);
    border-bottom: 1px solid var(--border);
    margin-bottom: 8px;
}
.section-total { font-weight: 600; color: var(--text); }

/* Info card */
.info-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 10px 14px;
    margin-bottom: 12px;
    font-size: 0.9rem;
}
.info-card p { margin-bottom: 2px; color: var(--text-muted); }
.info-card strong { color: var(--text); }

/* ACARIS detail */
.acaris-detail {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px;
    margin-top: 12px;
}
.acaris-detail h4 {
    font-size: 0.85rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-bottom: 8px;
}
.acaris-line {
    display: flex;
    justify-content: space-between;
    font-size: 0.8rem;
    padding: 2px 0;
    color: var(--text-muted);
}
.acaris-totals {
    border-top: 1px solid var(--border);
    margin-top: 8px;
    padding-top: 8px;
}
.acaris-row {
    font-size: 0.85rem;
    margin-bottom: 2px;
}
.acaris-marge { color: var(--primary); }
.acaris-line-edit {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 0;
    font-size: 0.8rem;
}
.acaris-name-wrap { flex: 1; min-width: 0; display: flex; align-items: center; gap: 4px; }
.acaris-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.acaris-cdt { font-size: 0.65rem; color: var(--primary); background: rgba(79,140,255,0.1); padding: 0 4px; border-radius: 6px; white-space: nowrap; flex-shrink: 0; }
.acaris-qty { display: flex; align-items: center; gap: 0; }
.acaris-price { font-weight: 600; white-space: nowrap; min-width: 55px; text-align: right; }
.btn-round-sm {
    width: 24px; height: 24px; border-radius: 6px;
    border: 1px solid var(--border); background: var(--bg-input);
    color: var(--text); font-size: 14px; display: flex;
    align-items: center; justify-content: center; cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.btn-round-sm:active { background: var(--bg-hover); }
.btn-del-sm {
    background: none; border: none; color: var(--text-muted);
    font-size: 16px; cursor: pointer; padding: 0 2px;
}
.btn-del-sm:active { color: var(--error); }

/* Subsection title */
.subsection-title {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin: 12px 0 6px;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--border);
}

/* Totals bar */
.totals-bar {
    display: flex;
    justify-content: space-around;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px;
    margin-top: 16px;
}
.total-item { text-align: center; }
.total-label { display: block; font-size: 0.75rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.5px; }
.total-val { font-weight: 700; font-size: 1rem; }
.total-big { font-size: 1.2rem; color: var(--success); }

/* Recap */
.recap-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px;
    margin-bottom: 10px;
}
.recap-card h3 {
    font-size: 0.8rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-bottom: 6px;
}
.recap-main { font-size: 1.1rem; font-weight: 600; }
.recap-card p { font-size: 0.9rem; color: var(--text); margin-bottom: 2px; }
.recap-line {
    display: flex;
    justify-content: space-between;
    font-size: 0.9rem;
    padding: 3px 0;
    border-bottom: 1px solid var(--border);
}
.recap-line:last-child { border-bottom: none; }
.recap-total .recap-line { font-weight: 600; }
.recap-success {
    background: rgba(52,211,153,0.1);
    border-color: rgba(52,211,153,0.3);
}
.recap-success h3 { color: var(--success); }

/* ── Panneau de fusion devis → fiche event ──
   Deux natures d'écart, séparées à l'écran : ce que l'utilisateur a saisi, et
   ce que l'ouverture a posé depuis la fiche société. Le groupe « carnet » est
   en retrait — liseré neutre, cases décochées — parce qu'il propose une
   écriture que personne n'a demandée. Les valeurs sont des pilules : l'ancienne
   se lit, la nouvelle s'affirme, sans le rouge barré qui criait à l'erreur
   alors qu'il n'y en a pas. */
.merge-popup { max-width: 540px; }
.merge-title { font-size: 1rem; font-weight: 700; margin: 0 0 4px; color: var(--text); }
.merge-desc { font-size: 0.78rem; color: var(--text-muted); margin: 0 0 14px; }

.merge-groupe { margin-bottom: 14px; }
.merge-groupe:last-of-type { margin-bottom: 0; }
.merge-groupe-titre {
    font-size: 0.7rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--text-muted); margin: 0 0 6px;
}
.merge-groupe.is-saisie .merge-groupe-titre { color: var(--primary); }
.merge-groupe-note {
    font-size: 0.73rem; color: var(--text-muted); margin: -2px 0 8px; line-height: 1.4;
}

.merge-row {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 4px 10px;
    align-items: start;
    padding: 9px 12px;
    margin-bottom: 6px;
    border: 1px solid var(--border);
    border-left: 3px solid var(--border);
    border-radius: 10px;
    background: var(--bg-input);
    font-size: 0.82rem;
    cursor: pointer;
    transition: border-color .13s, background .13s;
}
.merge-row:hover { background: var(--bg-hover); }
.merge-groupe.is-saisie .merge-row { border-left-color: var(--primary); }
.merge-row input[type=checkbox] { accent-color: var(--primary); margin: 3px 0 0; }
.merge-field { font-weight: 600; color: var(--text); }
.merge-values {
    grid-column: 2;
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
    line-height: 1.5;
}
.merge-old, .merge-new {
    display: inline-block; padding: 1px 9px; border-radius: 999px;
    font-size: 0.78rem; max-width: 100%; overflow-wrap: anywhere;
}
.merge-old { background: var(--bg-hover); color: var(--text-muted); }
.merge-new {
    background: color-mix(in srgb, var(--primary) 16%, transparent);
    color: var(--text); font-weight: 600;
}
.merge-arrow { color: var(--text-muted); font-size: 0.8rem; }

.merge-pied {
    display: flex; gap: 10px; margin-top: 18px;
    align-items: center; justify-content: flex-end;
}
.merge-cta {
    min-height: 34px; padding: 7px 20px; border-radius: 999px;
    font-family: inherit; font-size: 12.5px; font-weight: 600; line-height: 1.35;
    cursor: pointer; white-space: nowrap;
    background: var(--primary); border: 1px solid var(--primary); color: var(--primary-ink);
    transition: background .13s, border-color .13s;
}
.merge-cta:hover { background: var(--primary-hover); border-color: var(--primary-hover); }
.merge-cta:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.merge-lien {
    padding: 7px 6px; border: none; background: none; cursor: pointer;
    font-family: inherit; font-size: 12.5px; color: var(--text-muted);
    text-decoration: underline; text-underline-offset: 3px;
}
.merge-lien:hover { color: var(--text); }

/* Login page */
.login-page {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: 16px;
}
.login-card {
    background: var(--bg-card);
    padding: 2rem;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    width: 100%;
    max-width: 360px;
    text-align: center;
}
.login-logo { height: 30px; width: auto; margin-bottom: 4px; filter: brightness(0); opacity: 0.86; }
.login-subtitle { color: var(--text-muted); margin-bottom: 1.5rem; font-size: 0.9rem; }
.login-card form { display: flex; flex-direction: column; gap: 12px; }
.login-card .input { text-align: center; }

/* Home page */
.home {
    max-width: 600px;
    margin: 0 auto;
    padding: 16px;
    min-height: calc(100vh - var(--topbar-h));
}
.home-header { display: flex; justify-content: space-between; align-items: center; }
.btn-refresh { font-size: 1.3rem; padding: 4px 8px; transition: transform 0.3s; }
.btn-refresh.spinning { animation: spin 0.5s ease; }
@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
.spinning { animation: spin 0.5s ease; }
.home-title {
    font-size: 1.5rem;
    font-weight: 700;
    margin-bottom: 12px;
}
/* .home-title est partagé avec la boutique, l'espace équipe et l'espace
   employé, qui gardent leur identité : l'échelle ne vaut que dans l'admin. */
body.admin .home-title {
    font-family: var(--f-serif);
    font-size: var(--t-page);
    font-weight: var(--t-poids);
    letter-spacing: var(--t-ls);
    line-height: 1.12;
    text-wrap: balance;
}
.home-menu { padding-top: 8px; }

/* Resume card */
.resume-card {
    display: flex;
    align-items: center;
    gap: 0;
    background: var(--bg-card);
    border: 2px solid var(--primary);
    border-radius: var(--radius);
    margin-bottom: 20px;
    -webkit-tap-highlight-color: transparent;
    transition: background 0.15s;
    position: relative;
}
.resume-main {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 1;
    padding: 14px;
    cursor: pointer;
}
.resume-main:active { background: var(--bg-hover); border-radius: var(--radius) 0 0 var(--radius); }
.resume-delete {
    background: none;
    border: none;
    border-left: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 0.9rem;
    padding: 14px 12px;
    cursor: pointer;
    align-self: stretch;
    display: flex;
    align-items: center;
    opacity: 0.4;
    transition: opacity 0.15s, color 0.15s;
}
.resume-delete:hover, .resume-delete:active { opacity: 1; color: var(--error); }
.created-card { border-color: var(--success); }
.created-card .resume-icon { opacity: 0.7; }
.resume-icon { font-size: 1.5rem; }
.resume-info { flex: 1; }
.resume-name { font-weight: 600; font-size: 1rem; }
.resume-meta { font-size: 0.85rem; color: var(--text-muted); margin-top: 2px; }
.resume-arrow { font-size: 1.2rem; color: var(--primary); }

/* Section titles */
/* Admin nav sections */
.admin-nav { display: flex; flex-direction: column; gap: 20px; }
.admin-section {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}
.admin-section-label {
    font-size: 0.65rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
    padding: 10px 14px 6px;
}
.admin-row {
    display: flex;
    flex-wrap: wrap;
}
.admin-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 12px 14px;
    font-size: 0.95rem;
    font-weight: 500;
    color: var(--text);
    text-decoration: none;
    width: 50%;
    -webkit-tap-highlight-color: transparent;
    transition: background 0.15s;
}
.admin-item:hover, .admin-item:active { background: var(--bg-hover); }
@media (min-width: 481px) {
    .admin-item { width: auto; padding: 12px 18px; }
}

/* Keep old grid classes for other pages that may use them */
.home-section-title {
    font-size: 0.65rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--text-muted);
    margin: 16px 0 8px;
    padding-left: 4px;
}
.home-section-title:first-of-type { margin-top: 0; }
.home-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
}
.grid-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 12px 6px 10px;
    border-radius: 12px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    text-decoration: none;
    color: inherit;
    transition: background 0.15s, transform 0.1s, border-color 0.15s;
    -webkit-tap-highlight-color: transparent;
}
.grid-card:hover { background: var(--bg-hover); border-color: var(--primary); transform: translateY(-2px); }
.grid-card:active { transform: scale(0.96); border-color: var(--primary); }
.grid-icon { font-size: 1.6rem; line-height: 1; }
.grid-label { font-size: 0.65rem; font-weight: 600; text-align: center; color: var(--text-muted); }

/* Action cards */
.home-actions {
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.action-card {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px;
    cursor: pointer;
    text-align: left;
    color: var(--text);
    -webkit-tap-highlight-color: transparent;
    transition: background 0.15s;
    width: 100%;
}
.action-card:active { background: var(--bg-hover); }
.action-disabled { opacity: 0.4; cursor: not-allowed; pointer-events: none; }
.action-icon { font-size: 1.5rem; flex-shrink: 0; }
.action-text { flex: 1; display: flex; flex-direction: column; }
.action-label { font-weight: 600; font-size: 1rem; }
.action-desc { font-size: 0.8rem; color: var(--text-muted); }

/* Home panel (new/load) */
.home-panel { padding-top: 8px; }
.home-panel h2 { font-size: 1.3rem; font-weight: 700; margin-bottom: 16px; }
.back-btn { margin-bottom: 8px; padding-left: 0; }

/* Hypotheses bar */
.hyp-bar {
    background: rgba(79,140,255,0.08);
    border: 1px solid rgba(79,140,255,0.2);
    border-radius: var(--radius);
    padding: 10px 14px;
    margin-bottom: 12px;
    font-size: 0.85rem;
    color: var(--text-muted);
}
.hyp-bar strong { color: var(--text); }
.hyp-title { margin-bottom: 4px; }
.hyp-row { display: flex; align-items: center; gap: 6px; margin-top: 4px; flex-wrap: wrap; }
.hyp-details { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 4px; }
.hyp-sub { margin-top: 4px; font-size: 0.8rem; }
.hyp-note { font-size: 0.8rem; }
.hyp-alert { margin-top: 6px; padding: 6px 10px; background: rgba(248,113,113,0.12); border: 1px solid rgba(248,113,113,0.25); border-radius: var(--radius); color: var(--error); font-size: 0.85rem; }
.hyp-verif { font-size: 0.75rem; margin-left: 4px; }
.hyp-section { margin-top: 6px; }
.hyp-result { margin-top: 6px; font-size: 0.85rem; color: var(--text); }
.input-hyp-wide {
    width: 100px;
    text-align: center;
    padding: 4px 6px;
    font-size: 14px;
    border-radius: 6px;
    background: var(--bg);
    border: 1px solid rgba(79,140,255,0.3);
    color: var(--text);
}
.hyp-stepper { display: flex; align-items: center; gap: 0; }
.hyp-stepper-val-input {
    width: 50px; text-align: center; padding: 4px; font-size: 14px; font-weight: 700;
    background: var(--bg); border: 1px solid rgba(79,140,255,0.3); border-radius: 0;
    border-left: none; border-right: none; color: var(--text); outline: none;
}
.hyp-stepper-val-input:focus { background: var(--bg-input); }
.hyp-unit { font-size: 0.8rem; color: var(--text-muted); margin-left: 4px; }

/* ── Composeur boissons par item ── */
.boisson-composer { display: flex; flex-direction: column; gap: 14px; }
.boisson-cat {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
}
.boisson-cat-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    background: rgba(79,140,255,0.08);
    padding: 8px 12px;
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--text);
    border-bottom: 1px solid var(--border);
}
.boisson-cat-title { flex: 0 0 auto; }
.boisson-cat-meta {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--text-muted);
}
.boisson-cat-total { font-weight: 600; color: var(--text); }
.boisson-cat-split { display: inline-flex; flex-wrap: wrap; gap: 8px; }
.boisson-cat-split .split-item { white-space: nowrap; }

.boisson-row {
    display: grid;
    grid-template-columns:
        minmax(0, 1fr)      /* nom produit (rétrécit en premier, ellipsis) */
        minmax(110px, 130px) /* stepper cible v/p */
        minmax(45px, 60px)  /* qté */
        minmax(70px, 90px)  /* réel v/p */
        minmax(75px, 90px)  /* PU */
        minmax(70px, 90px)  /* total */
        28px;               /* ✕ — toujours visible */
    align-items: center;
    column-gap: 10px;
    padding: 6px 12px;
    border-bottom: 1px solid var(--border);
    font-size: 0.85rem;
}
.boisson-row:last-child { border-bottom: none; }
.boisson-row-name {
    grid-column: 1;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--text);
    font-weight: 500;
    min-width: 0;
}
.boisson-row-name > span:not(.pack-badge-mini):not(.boisson-row-arrow):not(.boisson-row-warn) {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.boisson-row-cible { grid-column: 2; justify-self: start; }
.boisson-row-qty   { grid-column: 3; }
.boisson-row-real  { grid-column: 4; }
.boisson-row-price { grid-column: 5; display: inline-flex; align-items: center; gap: 2px; }
.boisson-row-price-ro { grid-column: 5; text-align: right; }
.boisson-row-total { grid-column: 6; text-align: right; }
.boisson-row-del   { grid-column: 7; justify-self: end; }

.boisson-row-qty,
.boisson-row-real {
    font-size: 0.78rem;
    color: var(--text-muted);
    white-space: nowrap;
}
.boisson-row-qty strong { color: var(--text); font-weight: 700; }
.boisson-row-price-ro {
    font-size: 0.8rem;
    color: var(--text-muted);
}
.boisson-row-total {
    font-weight: 600;
    color: var(--text);
}

.boisson-row--cocktail-header {
    background: rgba(124,58,237,0.06);
}
.boisson-row--cocktail-header .boisson-row-name { font-weight: 600; }

.boisson-row--cocktail-child {
    background: var(--bg-card);
    font-size: 0.8rem;
    opacity: 0.85;
}
.boisson-row--cocktail-child .boisson-row-name {
    font-weight: 400;
    padding-left: 24px;
}
.boisson-row-arrow { color: var(--text-muted); }

.boisson-row--stale { opacity: 0.55; }

/* Badge « ⚠️ Recalculer N bacs » à côté du label Glaçons quand la qty
   diverge de la règle métier. Cliquable → applique l'attendu. */
.glacons-recalc-badge {
    display: inline-flex; align-items: center; gap: 4px;
    margin-left: 8px; padding: 2px 8px;
    background: rgba(251,146,60,0.18); color: #f59e0b;
    border: 1px solid rgba(251,146,60,0.35); border-radius: 10px;
    font-size: 0.72rem; font-weight: 500; cursor: pointer;
    transition: background 0.15s;
}
.glacons-recalc-badge:hover { background: rgba(251,146,60,0.28); }
.glacons-recalc-badge strong { font-weight: 700; }
.boisson-row-warn {
    font-size: 0.9rem;
    cursor: help;
}

.pack-badge-mini {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 0.85rem;
    color: var(--primary);
    line-height: 1;
    margin-left: 2px;
}
.input-hyp {
    width: 60px;
    text-align: center;
    padding: 4px 6px;
    font-size: 14px;
    border-radius: 6px;
    background: var(--bg);
    border: 1px solid rgba(79,140,255,0.3);
    color: var(--text);
}

/* Shippr grid */
.shippr-grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 6px;
    margin-bottom: 12px;
}
.shippr-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    background: var(--bg-input);
    border: 2px solid var(--border);
    border-radius: var(--radius);
    padding: 10px 4px;
    cursor: pointer;
    color: var(--text);
    -webkit-tap-highlight-color: transparent;
    transition: all 0.15s;
}
.shippr-btn:disabled { cursor: not-allowed; }
.shippr-btn:active:not(:disabled) { background: var(--bg-hover); }
.shippr-selected { border-color: var(--primary); background: rgba(79,140,255,0.1); }
.shippr-label { font-size: 0.75rem; font-weight: 600; text-transform: uppercase; }
.shippr-price { font-size: 1.1rem; font-weight: 700; }
.shippr-cost { font-size: 0.65rem; color: var(--text-muted); text-align: center; }
/* Une offre indisponible doit se LIRE, pas s'effacer : fond en retrait,
   encre secondaire PLEINE — une opacité emporte le motif avec le prix. */
.shippr-indispo { background: var(--bg); border-color: var(--border); color: var(--text-muted); }
.shippr-motif { font-size: 0.78rem; line-height: 1.3; color: var(--text-muted); text-align: center; }
/* Des offres nommées en toutes lettres (« [VELO CARGO] Livraison programmée
   1h ») ne tiennent pas dans une colonne de cinquième. */
.shippr-grid.is-wide { grid-template-columns: repeat(auto-fit, minmax(168px, 1fr)); }

/* Prix du transport : la marge se lit contre le champ, pas dans une carte. */
.prix-ligne { display: flex; align-items: center; gap: 10px; }
.prix-ligne .input { flex: 1; min-width: 0; }
.prix-marge {
    flex: none;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--role-ok);
    white-space: nowrap;
}
.prix-marge.is-negative { color: var(--role-danger); }

/* Transporteurs alignés (devis) : Shippr + Uber + Autre sur une seule ligne,
   même gabarit, pour comparer véhicule et prix côte à côte. */
.shippr-grid.is-inline { grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); }
.shippr-provider {
    font-size: 0.6rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-muted);
}

@media (max-width: 400px) {
    .shippr-grid { grid-template-columns: repeat(3, 1fr); }
}

/* Typeform list */
.tf-list { display: flex; flex-direction: column; gap: 6px; }
.tf-card { display: flex; align-items: center; }
.tf-card .action-text { flex: 1; }
.tf-card .resume-arrow { flex-shrink: 0; color: var(--primary); font-size: 1.1rem; }
.tf-manual { }

/* Budget diff */
.budget-diff { font-weight: 700; font-size: 0.85rem; }
.budget-over { color: var(--error); }
.budget-under { color: var(--success); }

/* ═══ RÉCAP PAGE (Step 9) ═══ */
.recap-page { font-size: 0.85rem; }
.recap-title { font-weight: 700; font-size: 1rem; color: var(--text); padding: 10px 0; border-bottom: 2px solid var(--primary); margin-bottom: 12px; }

.recap-block { margin-bottom: 10px; padding-bottom: 8px; border-bottom: 1px solid var(--border); }
.recap-info-label { font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted); margin-bottom: 2px; }
.recap-info-val { font-weight: 600; font-size: 0.9rem; color: var(--text); }
.recap-info-sub { font-size: 0.75rem; color: var(--text-muted); line-height: 1.4; }

.recap-section { margin-bottom: 8px; }
.recap-section-header { display: flex; justify-content: space-between; align-items: center; padding: 6px 8px; background: rgba(79,140,255,0.06); border-left: 3px solid var(--primary); border-radius: 0 var(--radius) var(--radius) 0; margin-bottom: 2px; }
.recap-section-title { font-weight: 700; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.3px; color: var(--primary); }
.recap-section-total { font-weight: 700; font-size: 0.85rem; color: var(--text); }

.recap-table-head { display: flex; padding: 3px 4px; font-size: 0.6rem; text-transform: uppercase; letter-spacing: 0; color: var(--text-muted); border-bottom: 1px solid var(--border); gap: 8px; }
.recap-table-row { display: flex; padding: 2px 4px; font-size: 0.8rem; border-bottom: 1px solid rgba(42,45,58,0.5); gap: 8px; }
.recap-table-row:last-child { border-bottom: none; }
.recap-col-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; position: relative; }
.recap-col-qty { width: 46px; text-align: right; color: var(--text-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.recap-col-pu { width: 74px; text-align: right; color: var(--text-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.recap-col-disc { width: 34px; text-align: right; color: var(--text-muted); font-size: 0.75rem; white-space: nowrap; overflow: hidden; }
.recap-col-vat { width: 38px; text-align: right; color: var(--text-muted); font-size: 0.75rem; white-space: nowrap; overflow: hidden; }
.recap-col-vat select { font-size: 0.75rem; padding: 1px 2px; }

/* Remises : le detail par article et la remise globale vivent dans leur
   section de l'Overview, ce qui libere la colonne « Rem. » du recap. */
.remise-bascule { display: flex; gap: 6px; margin: 6px 0 8px; }
.remise-row { display: flex; align-items: center; gap: 8px; padding: 3px 4px; font-size: 0.8rem; border-bottom: 1px solid var(--border); }
.remise-row:last-child { border-bottom: none; }
.remise-col-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.remise-col-brut { width: 78px; text-align: right; color: var(--text-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.remise-col-pct { width: 68px; text-align: right; font-variant-numeric: tabular-nums; }
.remise-col-taux { width: 68px; text-align: right; color: var(--text-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.remise-col-eur { width: 84px; text-align: right; font-weight: 500; white-space: nowrap; font-variant-numeric: tabular-nums; }
.remise-vide { font-size: 0.78rem; color: var(--text-muted); font-style: italic; padding: 2px 4px 6px; }
.remise-saisie { display: flex; gap: 6px; align-items: center; margin: 8px 0; flex-wrap: wrap; }
.remise-input { width: 108px; }
.remise-unite { width: 68px; }
.remise-avert { margin-top: 8px; }
.recap-vat-missing { color: var(--error, #ef4444); font-weight: 700; }
.recap-col-total { width: 72px; text-align: right; font-weight: 500; white-space: nowrap; overflow: hidden; }

/* Cocktail séparateur + enfants indentés dans le Récap boissons */
.recap-cocktail-header {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 4px 8px;
    background: rgba(124,58,237,0.08);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text);
}
.recap-cocktail-count { font-weight: 400; color: var(--text-muted); }
.recap-table-row--cocktail-child {
    padding-left: 20px;
    background: var(--bg-card);
    font-size: 0.78rem;
    opacity: 0.9;
}
.recap-cocktail-arrow { color: var(--text-muted); margin-right: 2px; }

/* Catalog name matching */
.recap-name-missing { color: var(--error, #ef4444); }
.recap-name-warn { cursor: pointer; margin-left: 4px; font-size: 0.7rem; background: var(--error, #ef4444); color: white; border: none; border-radius: 4px; padding: 1px 6px; }
.recap-suggestions { position: absolute; left: 0; top: 100%; z-index: 20; background: var(--bg-card, #1a1a2e); border: 1px solid var(--border, #333); border-radius: 6px; padding: 4px; max-height: 250px; overflow-y: auto; min-width: 280px; box-shadow: 0 4px 12px rgba(0,0,0,0.3); }
.recap-suggestion { display: flex; justify-content: space-between; align-items: center; width: 100%; padding: 5px 8px; border: none; background: none; color: var(--text); cursor: pointer; font-size: 0.8rem; text-align: left; border-radius: 4px; }
.recap-suggestion:hover { background: var(--primary, #6c5ce7); color: white; }
.recap-suggestion-score { font-size: 0.65rem; color: var(--text-muted); margin-left: 8px; white-space: nowrap; }
.recap-suggestion:hover .recap-suggestion-score { color: rgba(255,255,255,0.7); }
.recap-suggestion-empty { padding: 8px; font-size: 0.8rem; color: var(--text-muted); font-style: italic; }
.recap-col-name { position: relative; }

.recap-line-detail { font-size: 0.55rem; color: var(--text-muted); padding: 0 8px 1px; font-style: italic; opacity: 0.7; }
.mdh-line-detail { font-size: 0.65rem; color: var(--text-muted); font-style: italic; opacity: 0.7; padding: 0 4px 4px; }
/* Le prix d'un maître d'hôtel se corrige sur la ligne. Jamais refusé : un
   tarif négocié est une décision, pas une erreur — seulement signalé. */
.mdh-pu {
    width: 72px; text-align: right; font-variant-numeric: tabular-nums;
    font-size: 0.85rem; padding: 2px 6px; border-radius: 5px;
    border: 1px solid var(--border); background: var(--bg-input); color: var(--text);
}
.mdh-pu:focus { outline: 2px solid var(--primary); outline-offset: 1px; }
.mdh-resp {
    display: flex; align-items: center; gap: 7px;
    margin: 8px 4px 0; padding: 7px 11px;
    background: var(--bg-input); border: 1px solid var(--border); border-radius: 8px;
}
.mdh-resp-n {
    min-width: 20px; text-align: center; font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.mdh-sous-tarif {
    font-size: 0.68rem; font-weight: 600; color: var(--role-warn-ink);
    background: var(--role-warn-bg, rgba(245,158,11,.12));
    border-radius: 99px; padding: 1px 8px; white-space: nowrap;
}
.recap-mdh-detail { font-size: 0.7rem; color: var(--text-muted); padding: 2px 8px; font-style: italic; }

.recap-totals { border-top: 2px solid var(--border); margin-top: 12px; padding-top: 8px; }
.recap-total-row { display: flex; justify-content: space-between; padding: 3px 0; font-size: 0.85rem; color: var(--text-muted); }
.recap-total-val { font-weight: 600; color: var(--text); }
.recap-total-big { font-size: 1.1rem; font-weight: 700; padding: 6px 0; border-top: 1px solid var(--border); margin-top: 4px; }
.recap-total-big .recap-total-val { color: var(--primary); }
.recap-budget { font-size: 0.8rem; margin-top: 6px; padding: 6px 8px; border-radius: var(--radius); }
.recap-over { background: rgba(248,113,113,0.08); color: var(--error); }
.recap-over .recap-total-val { color: var(--error); }
.recap-under { background: rgba(52,211,153,0.08); color: var(--text-muted); }
.recap-under .recap-total-val { color: var(--text-muted); }

/* Inline editing */
.recap-editable { cursor: pointer; border-bottom: 1px dashed transparent; transition: border-color 0.15s; }
.recap-editable:hover { border-bottom-color: var(--primary); }
.recap-edit-input { background: var(--bg-input); border: 1px solid var(--primary); border-radius: 4px; color: var(--text); padding: 2px 6px; font-size: inherit; width: 100%; outline: none; }
.recap-edit-title { font-size: 1rem; font-weight: 700; }
.recap-edit-row { display: flex; gap: 4px; }
.recap-edit-sm { flex: 1; }
.recap-edit-xs { width: 70px; flex-shrink: 0; }
.recap-edit-cell { width: 55px; text-align: right; padding: 1px 4px; font-size: 0.8rem; }

/* Swipe to delete (iOS) */
.swipe-wrapper { position: relative; overflow: hidden; border-radius: var(--radius); }
.swipe-wrapper .line-card { transition: transform 0.2s ease; }
.swipe-delete { position: absolute; right: 0; top: 0; bottom: 0; width: 80px; background: var(--error); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 0.8rem; font-weight: 600; cursor: pointer; border-radius: 0 var(--radius) var(--radius) 0; }

.hyp-time-input { background: var(--bg-input); border: 1px solid var(--border); border-radius: 4px; color: var(--text); padding: 2px 6px; font-size: 0.85rem; width: 80px; }

/* Overview button */

/* Modifications log */
.mods-log { margin-top: 16px; padding: 8px 10px; background: rgba(79,140,255,0.04); border: 1px solid rgba(79,140,255,0.15); border-radius: var(--radius); }
.mods-log-title { font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted); margin-bottom: 4px; }
.mods-log-section { font-size: 0.65rem; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted);
                    opacity: 0.75; margin: 8px 0 2px; }
/* Créneau de livraison : on saisit le début, la fin se lit à côté. */
.creneau-saisie { display: flex; align-items: center; gap: 8px; }
.creneau-fin { color: var(--text-muted); font-size: 0.85rem; white-space: nowrap; }
.creneau-sous { display: block; margin-top: 4px; }
.alerte-livraison { margin: 4px 0 0; font-size: 0.78rem; color: var(--warn); }
.mods-log-bloc { font-size: 0.72rem; font-weight: 600; color: var(--text); margin: 6px 0 2px; }
.mods-log-item { font-size: 0.75rem; padding: 2px 0; color: var(--text-muted); display: flex; align-items: center; gap: 6px; }
.mods-log-item > span { flex: 1; }
/* Ligne « Total HT » : récap final séparé du reste (trait + espace, en gras). */
.mods-log-total { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--border); font-weight: 600; color: var(--text); }
.mods-revert { background: none; border: none; color: var(--error); cursor: pointer; font-size: 0.7rem; padding: 2px 4px; border-radius: 4px; opacity: 0.5; flex-shrink: 0; }
.mods-revert:hover { opacity: 1; background: rgba(248,113,113,0.1); }
.mods-from { text-decoration: line-through; opacity: 0.6; }
.mods-to { color: var(--primary); font-weight: 500; }
.mods-added { color: var(--success); }
.mods-removed { color: var(--error); }
.mods-warning { color: var(--role-warn-ink); }

/* Alerte de l'éditeur de devis */
.editor-alert { padding: 10px 12px; background: var(--warn-soft); border: 1px solid color-mix(in srgb, var(--warn) 34%, transparent); border-radius: var(--radius); margin-bottom: 10px; }
.editor-alert-title { font-size: 0.85rem; font-weight: 600; color: var(--warn); }
.editor-alert-reason { font-size: 0.75rem; color: var(--warn); opacity: 0.8; padding-left: 4px; }
/* Diluer l'encre vers un aplat clair lui coûte trop : le motif tombe à 3,6:1.
   Sur fond sombre le même voile ne coûte rien, il y reste. */
:root[data-theme="jour"] .editor-alert-reason,
:root[data-theme="joy"] .editor-alert-reason,
:root[data-theme="opale"] .editor-alert-reason { opacity: 1; }

/* Écart de facturation : à distinguer d'un avis de service. L'aplat porte,
   le filet gauche signe, l'encre reste en --text pour rester lisible dessus. */
.divergence-banner {
    display: flex; align-items: center; flex-wrap: wrap; gap: 6px 12px;
    padding: 10px 14px; margin-bottom: 12px;
    background: var(--warn-fill);
    border: 1px solid var(--warn);
    border-left: 4px solid var(--warn);
    border-radius: var(--radius);
    color: var(--text);
}
.divergence-banner-txt { flex: 1 1 320px; min-width: 0; font-size: 0.82rem; }
.divergence-banner-txt strong { font-weight: 600; }

/* Edit mode banner */
.edit-mode-banner {
    background: var(--bg-hover);
    border: 1px solid var(--primary);
    border-radius: var(--radius);
    padding: 8px 14px;
    margin-bottom: 12px;
    font-size: 0.9rem;
    text-align: center;
}

/* ═══ TOAST NOTIFICATIONS ═══ */
.toast-container {
    position: fixed;
    bottom: calc(var(--plk-bar-socle) + var(--sp-4));
    left: 50%;
    transform: translateX(-50%);
    z-index: 9999;
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: none;
    max-width: 400px;
    width: calc(100% - 32px);
}
.toast {
    padding: 10px 16px;
    border-radius: var(--radius);
    font-size: 0.85rem;
    font-weight: 500;
    pointer-events: auto;
    animation: toastIn 0.25s ease;
    display: flex;
    align-items: center;
    gap: 8px;
    backdrop-filter: blur(12px);
    box-shadow: var(--elev-2);
    /* Le message porte l'encre et le fond de carte du thème : c'est la seule
       paire dont le rapport est garanti partout. La teinte de rôle passe sur
       le filet, où elle signale sans avoir à porter du texte. */
    background: var(--bg-card);
    color: var(--text);
    border-left: 3px solid var(--border);
}
.toast-info { border-left-color: var(--role-info); }
.toast-success { border-left-color: var(--role-ok); }
.toast-error { border-left-color: var(--role-danger); }
.toast-warning { border-left-color: var(--role-warn); }
.toast-out { animation: toastOut 0.2s ease forwards; }
@keyframes toastIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
@keyframes toastOut { to { opacity: 0; transform: translateY(-10px); } }

/* ═══ TAB BAR ═══ */
.tab-bar {
    display: flex;
    gap: 0;
    overflow-x: auto;
    scrollbar-width: none;
    border-bottom: 1px solid var(--border);
    margin-bottom: 12px;
    position: sticky;
    top: var(--topbar-h);
    background: var(--bg);
    z-index: 50;
    -webkit-overflow-scrolling: touch;
}
.tab-bar::-webkit-scrollbar { display: none; }
.tab-btn {
    padding: 10px 16px;
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--text-muted);
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    cursor: pointer;
    white-space: nowrap;
    transition: all 0.15s;
    -webkit-tap-highlight-color: transparent;
}
.tab-btn:active { background: var(--bg-hover); }
.tab-active { color: var(--primary); border-bottom-color: var(--primary); }

/* ═══ SKELETON LOADING ═══ */
.skeleton {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    position: relative;
    overflow: hidden;
}
.skeleton::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.04) 50%, transparent 100%);
    animation: shimmer 1.5s infinite;
}
@keyframes shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
.skel-card { height: 72px; margin-bottom: 8px; }
.skel-bar { height: 12px; border-radius: 6px; margin-bottom: 6px; }
.skel-bar-sm { width: 60%; }
.skel-bar-md { width: 40%; }

/* ═══ AVATAR (initials) ═══ */
.avatar {
    width: 36px; height: 36px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    font-weight: 700;
    color: #fff;
    flex-shrink: 0;
    text-transform: uppercase;
}

/* ═══ BADGES ═══ */
.badge {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 20px;
    font-size: 0.7rem;
    font-weight: 600;
    white-space: nowrap;
}
.badge-primary { background: rgba(79,140,255,0.15); color: var(--primary); }
.badge-success { background: rgba(52,211,153,0.15); color: var(--success); }
.badge-error { background: rgba(248,113,113,0.15); color: var(--error); }
.badge-warning { background: rgba(245,158,11,0.15); color: #f59e0b; }
.badge-muted { background: rgba(107,112,137,0.15); color: var(--text-muted); }
.badge-pulse { animation: pulse 2s infinite; }
.badge-auto {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: 0.72rem;
    font-weight: 600;
    background: rgba(99,102,241,0.12);
    color: var(--primary);
    border: 1px solid rgba(99,102,241,0.3);
    cursor: help;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }

/* ═══ ACTUEL — la marque de l'élément qui fait foi ═══
   Dans une liste d'états successifs du même objet (versions d'un devis,
   factures d'un événement), un seul fait foi. Il porte la bordure colorée,
   le fond teinté et le badge — ici, et nulle part ailleurs.
   La spécificité est doublée volontairement : la marque se pose sur des
   cartes dont la peau (`.card`, `.pj-card`, `.mdv-picker`) est déclarée dans
   une feuille chargée après celle-ci, qui reprendrait sinon la main. */
.plk-actuel.plk-actuel {
    border-color: var(--primary);
    /* La teinte se POSE sur le fond de la surface au lieu de le remplacer :
       substituée sur une carte déjà bleutée, elle retombe à deux points de la
       couleur d'origine et ne se voit plus. */
    background-image: linear-gradient(var(--accent-soft), var(--accent-soft));
}
/* Le mot qui dit l'état de la pièce : l'actuelle à l'encre principale, celle
   qu'elle remplace à l'encre discrète. Même géométrie, pour qu'un coup d'œil
   les compare au lieu de les déchiffrer. */
.plk-actuel-tag, .plk-ecarte-tag {
    display: inline-block;
    flex: 0 0 auto;
    padding: 1px 6px;
    border-radius: 9px;
    font-size: 0.62rem;
    font-weight: 400;
    line-height: 1.6;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    white-space: nowrap;
    background: transparent;
    border: 1px solid;
}
.plk-actuel-tag { color: var(--primary); border-color: var(--primary); }
/* `--border` est repeint par la peau du composeur : le filet du jeton se
   déduit donc de son encre, pour que le même mot se lise pareil partout. */
.plk-ecarte-tag { color: var(--text-muted);
    border-color: color-mix(in srgb, var(--text-muted) 42%, transparent); }

/* ═══ PROGRESS SEGMENTED BAR ═══ */
.progress-seg {
    display: flex;
    height: 4px;
    border-radius: 2px;
    overflow: hidden;
    gap: 2px;
}
.progress-seg-item {
    flex: 1;
    border-radius: 2px;
    background: var(--border);
    transition: background 0.3s;
}
.progress-seg-done { background: var(--success); }
.progress-seg-current { background: var(--primary); }
.progress-seg-warn { background: #f59e0b; }

/* ═══ FUNNEL ═══ */
.funnel { display: flex; align-items: center; gap: 0; overflow-x: auto; padding: 8px 0; }
.funnel-step {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
    min-width: 60px;
}
.funnel-val { font-size: 1.1rem; font-weight: 700; color: var(--text); }
.funnel-label { font-size: 0.6rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.3px; text-align: center; }
.funnel-pct { font-size: 0.65rem; color: var(--primary); }
.funnel-arrow { color: var(--text-muted); font-size: 0.8rem; flex-shrink: 0; margin: 0 2px; }

/* ═══ MINI BAR CHART ═══ */
.bar-chart { display: flex; align-items: flex-end; gap: 3px; height: 80px; padding: 0 4px; }
.bar-col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 0; }
.bar { border-radius: 3px 3px 0 0; min-height: 2px; width: 100%; transition: height 0.3s; }
.bar-current { background: var(--primary); }
.bar-prev { background: rgba(79,140,255,0.25); }
.bar-label { font-size: 0.55rem; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.bar-value { font-size: 0.6rem; color: var(--text); font-weight: 600; white-space: nowrap; }

/* ═══ TIMELINE ═══ */
.timeline { position: relative; padding-left: 24px; }
.timeline::before { content: ''; position: absolute; left: 8px; top: 0; bottom: 0; width: 2px; background: var(--border); }
.timeline-item { position: relative; padding-bottom: 16px; }
.timeline-dot { position: absolute; left: -20px; top: 2px; width: 12px; height: 12px; border-radius: 50%; border: 2px solid var(--border); background: var(--bg); }
.timeline-dot-done { border-color: var(--success); background: var(--success); }
.timeline-dot-action { border-color: var(--primary); background: var(--primary); }
.timeline-dot-warn { border-color: #f59e0b; background: #f59e0b; }
.timeline-date { font-size: 0.7rem; color: var(--text-muted); }
.timeline-text { font-size: 0.85rem; color: var(--text); }
.timeline-actor { font-size: 0.7rem; color: var(--text-muted); font-style: italic; }

/* ═══ SIDE PANEL (desktop) ═══ */
@media (min-width: 900px) {
    .with-side-panel { display: flex; gap: 20px; max-width: 780px; margin: 0 auto; }
    .with-side-panel .wizard { flex: 1; max-width: 500px; }
    .side-panel {
        width: 240px;
        position: sticky;
        top: calc(var(--topbar-h) + 12px);
        height: fit-content;
        background: var(--bg-card);
        border: 1px solid var(--border);
        border-radius: var(--radius);
        padding: 14px;
        font-size: 0.8rem;
    }
    .side-panel h3 { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted); margin-bottom: 8px; }
    .side-panel-row { display: flex; justify-content: space-between; padding: 3px 0; }
    .side-panel-val { font-weight: 600; color: var(--text); }
    .side-panel-big { font-size: 1.1rem; font-weight: 700; color: var(--primary); padding: 6px 0; border-top: 1px solid var(--border); margin-top: 4px; }
}

/* ═══ CATEGORY COLORS (line cards) ═══ */
.cat-sale { border-left: 3px solid rgba(255,180,100,0.5); }
.cat-sucre { border-left: 3px solid rgba(255,130,160,0.5); }
.cat-boissons { border-left: 3px solid rgba(100,160,255,0.5); }
.cat-vaisselle { border-left: 3px solid rgba(180,180,180,0.5); }
.cat-mdh { border-left: 3px solid rgba(100,220,160,0.5); }
.cat-sceno { border-left: 3px solid rgba(180,130,255,0.5); }
.cat-transport { border-left: 3px solid rgba(255,160,80,0.5); }

/* ═══ KANBAN ═══ */
.kanban {
    display: flex;
    gap: 12px;
    overflow-x: auto;
    padding: 8px 0;
    -webkit-overflow-scrolling: touch;
    min-height: 300px;
}
.kanban-col {
    min-width: 200px;
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.kanban-header {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted);
    padding: 6px 8px;
    border-bottom: 2px solid var(--border);
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.kanban-count { background: var(--bg-hover); padding: 1px 6px; border-radius: 10px; font-size: 0.65rem; }
.kanban-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 8px 10px;
    font-size: 0.8rem;
    cursor: pointer;
    transition: background 0.15s;
}
.kanban-card:active { background: var(--bg-hover); }
.kanban-card-client { font-weight: 600; }
.kanban-card-meta { font-size: 0.7rem; color: var(--text-muted); margin-top: 2px; }

/* ═══ EMPTY STATE ═══ */
.empty-state {
    text-align: center;
    padding: 2rem 1rem;
    color: var(--text-muted);
}
.empty-icon { font-size: 2rem; margin-bottom: 8px; opacity: 0.5; }
.empty-text { font-size: 0.85rem; margin-bottom: 12px; }
.empty-cta { color: var(--primary); cursor: pointer; font-weight: 500; }

/* ═══ HEATMAP DATE ═══ */
.heatmap-hint {
    font-size: 0.75rem;
    margin-top: 4px;
    padding: 4px 8px;
    border-radius: 4px;
}
.heatmap-warn { background: rgba(245,158,11,0.1); color: #f59e0b; }
.heatmap-ok { background: rgba(52,211,153,0.1); color: var(--success); }

/* Desktop tweaks */
@media (min-width: 600px) {
    .wizard { padding-top: 8px; }
    .wizard-nav {
        position: sticky;
        max-width: 700px;
    }
}

/* ═══ TRANSPORT DASHBOARD ═══ */

/* ═══ TRANSPORT DASHBOARD ═══ */

/* Summary bar */
.tpt-summary {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    align-items: center;
    font-size: 0.9rem;
    color: var(--text);
    padding: 14px 18px;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: 20px;
}
.tpt-summary strong { color: var(--text); font-size: 1.1rem; }
.tpt-sep { color: var(--text-muted); margin: 0 2px; }

/* Chips */
.chip {
    display: inline-flex;
    align-items: center;
    padding: 8px 16px;
    border: 1px solid var(--border);
    border-radius: 8px;
    cursor: pointer;
    background: var(--bg-card);
    color: var(--text);
    font-size: 0.85rem;
    font-weight: 500;
    transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
}
.chip:hover { border-color: var(--primary); background: rgba(99,102,241,0.08); }
/* Le survol ne doit pas reprendre la main sur la puce choisie : `.chip:hover`
   pèse plus lourd que `.chip-active`, et son fond clair rendait le libellé
   blanc illisible sous le curseur qui venait de le choisir. */
.chip-active, .chip-active:hover {
    border-color: var(--primary);
    background: var(--primary);
    color: #fff;
    font-weight: 600;
    box-shadow: 0 0 0 2px rgba(99,102,241,0.25);
}

/* Order panel */
.tpt-order-panel {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 20px;
    box-shadow: 0 1px 3px rgba(10, 12, 16, 0.10);
}
.tpt-order-panel h3 { font-size: 1rem; color: var(--text); }
.tpt-order-msg {
    display: inline-block;
    margin-left: 12px;
    font-size: 0.85rem;
    color: var(--success);
    font-weight: 600;
}
.tpt-order-err { color: var(--error); }

/* Table wrapper */
.tpt-table-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* Day card — each day is a card */
.tpt-day-card {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: 16px;
    overflow: hidden;
}
.tpt-day-card-today {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--accent-soft, rgba(79,140,255,0.12));
}

/* Day group header — inside card */
.tpt-day-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    font-size: 0.82rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text);
    background: var(--bg-hover);
    border-bottom: 1px solid var(--border);
}
.tpt-day-today .tpt-day-header,
.tpt-day-card-today .tpt-day-header {
    color: var(--primary);
    background: var(--accent-soft, rgba(79,140,255,0.10));
}
.tpt-day-count {
    font-weight: 500;
    font-size: 0.72rem;
    color: var(--text-muted);
    background: var(--bg-hover);
    border: 1px solid var(--border);
    padding: 2px 8px;
    border-radius: 10px;
}

/* Table */
.tpt-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
    /* Layout fixe : chaque jour est un <table> distinct — sans largeurs
       imposées, les colonnes se dimensionnent indépendamment et ne
       s'alignent pas d'un jour à l'autre. */
    table-layout: fixed;
    /* Plancher = largeur naturelle des 11 colonnes. En dessous, le wrapper
       défile horizontalement au lieu de comprimer les colonnes sous leur
       contenu. */
    min-width: var(--tpt-table-min, 1160px);
}
.tpt-table th {
    text-align: left;
    padding: 8px 10px;
    color: var(--text-muted);
    font-weight: 600;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    /* Un cran plus clair que l'en-tête de jour : sinon les deux bandes
       fusionnent en un seul pavé gris au-dessus de chaque tableau. */
    background: color-mix(in srgb, var(--text) 7%, var(--bg-card));
    white-space: nowrap;
}
.tpt-table td {
    padding: 10px 10px;
    border-top: 1px solid var(--border);
    white-space: nowrap;
    color: var(--text);
}
/* Largeurs de colonnes partagées par tous les tableaux-jour → 11 colonnes :
   Transporteur / Chauffeur / Heure / Trajet / Taille / Statut / Event /
   Coût / Appeler / Suivre / action(✕). Somme = 100%.
   Les parts suivent la largeur réellement demandée par chaque colonne à
   `--tpt-table-min` près ; Trajet est la colonne élastique qui encaisse le
   reste (elle tronque en « … »). */
.tpt-table th:nth-child(1),  .tpt-table td:nth-child(1)  { width: 11.4%; }
.tpt-table th:nth-child(2),  .tpt-table td:nth-child(2)  { width: 8.6%; }
.tpt-table th:nth-child(3),  .tpt-table td:nth-child(3)  { width: 5.8%; }
.tpt-table th:nth-child(4),  .tpt-table td:nth-child(4)  { width: 16.9%; }
.tpt-table th:nth-child(5),  .tpt-table td:nth-child(5)  { width: 6.6%; }
.tpt-table th:nth-child(6),  .tpt-table td:nth-child(6)  { width: 10%; }
.tpt-table th:nth-child(7),  .tpt-table td:nth-child(7)  { width: 11%; }
.tpt-table th:nth-child(8),  .tpt-table td:nth-child(8)  { width: 5.8%; }
.tpt-table th:nth-child(9),  .tpt-table td:nth-child(9)  { width: 10%; }
.tpt-table th:nth-child(10), .tpt-table td:nth-child(10) { width: 9.7%; }
.tpt-table th:nth-child(11), .tpt-table td:nth-child(11) { width: 4.2%; }
/* Troncature « … » sur TOUTES les cellules : en `table-layout: fixed` +
   `white-space: nowrap`, ce qui dépasse ne pousse pas la colonne voisine —
   il se superpose à elle. Sans clip, « TRANSPORTEUR » recouvrait
   « CHAUFFEUR » et la taille du colis recouvrait le badge de statut. */
.tpt-table th, .tpt-table td {
    overflow: hidden;
    text-overflow: ellipsis;
}
/* ── Vue brigade (shop, iPad) : version allégée ──────────────────────────────
   Le viewer retire BO + la colonne action → 9 colonnes (Transporteur /
   Chauffeur / Heure / Trajet / Taille / Statut / Event / Coût / Client).
   Police + paddings réduits pour la largeur iPad, et clip « … » sur TOUTES les
   cellules (pas seulement Trajet/Event) pour qu'aucun texte ne déborde sur la
   colonne voisine. Scopé au viewer : l'admin desktop garde la densité d'origine. */
.tpt-table--viewer { font-size: 0.72rem; --tpt-table-min: 920px; }
.tpt-table--viewer th { font-size: 0.6rem; padding: 5px 6px; }
.tpt-table--viewer td { padding: 6px 6px; }
.tpt-table--viewer th, .tpt-table--viewer td {
    overflow: hidden;
    text-overflow: ellipsis;
}
.tpt-table--viewer th:nth-child(1), .tpt-table--viewer td:nth-child(1) { width: 10.6%; }
.tpt-table--viewer th:nth-child(2), .tpt-table--viewer td:nth-child(2) { width: 11%; }
.tpt-table--viewer th:nth-child(3), .tpt-table--viewer td:nth-child(3) { width: 8%; }
.tpt-table--viewer th:nth-child(4), .tpt-table--viewer td:nth-child(4) { width: 16.4%; }
.tpt-table--viewer th:nth-child(5), .tpt-table--viewer td:nth-child(5) { width: 7%; }
.tpt-table--viewer th:nth-child(6), .tpt-table--viewer td:nth-child(6) { width: 11%; }
.tpt-table--viewer th:nth-child(7), .tpt-table--viewer td:nth-child(7) { width: 14%; }
.tpt-table--viewer th:nth-child(8), .tpt-table--viewer td:nth-child(8) { width: 8%; }
.tpt-table--viewer th:nth-child(9), .tpt-table--viewer td:nth-child(9) { width: 14%; }

/* La ligne de détail dépliée occupe toute la largeur (colspan=11) — ses
   propres colonnes ne suivent pas les grilles ci-dessus. Le sélecteur doit
   être au moins aussi spécifique que `.tpt-table td:nth-child(n)` et placé
   après les deux grilles, sinon la largeur de la 1re colonne s'applique : en
   `display: block` (mobile) elle réduit le bloc déplié à 11,4% de la carte. */
.tpt-table .tpt-detail-row td { width: auto; }

/* ── Mobile (iPhone) : tableau → cartes empilées ─────────────────────────────
   Sous 640px le tableau fixe à 11 colonnes ne tient pas : on bascule chaque
   course en carte verticale label:valeur, sans scroll horizontal. Le libellé
   vient du `data-label` de chaque <td> (::before). Breakpoint 640px volontaire :
   l'iPad viewer (≥768px) garde le tableau dense. */
@media (max-width: 640px) {
    .tpt-table { table-layout: auto; min-width: 0; }
    .tpt-table thead { display: none; }
    .tpt-table tbody { display: block; border-top: 1px solid var(--border); }
    .tpt-table tbody:first-of-type { border-top: none; }
    /* Carte = flex-wrap : la 1re ligne combine logo (col1) + heure (col3),
       les autres champs passent en pleine largeur dessous. */
    .tpt-table .tpt-row { display: flex; flex-wrap: wrap; align-items: center; padding: 10px 14px 12px; cursor: pointer; }
    .tpt-table .tpt-row td {
        flex: 0 0 100%;          /* chaque champ = 1 ligne pleine largeur par défaut */
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 12px;
        width: auto;
        padding: 3px 0;
        border-top: none;
        white-space: normal;
        overflow: visible;       /* annule l'ellipsis desktop (Trajet/Event) */
        text-overflow: clip;
    }
    /* Libellé de champ à gauche, valeur à droite */
    .tpt-table .tpt-row td::before {
        content: attr(data-label);
        flex: 0 0 auto;
        color: var(--text-muted);
        font-size: 0.66rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.5px;
    }
    /* En-tête de carte : logo (col1) à gauche + heure (col3) à droite, même ligne */
    .tpt-table .tpt-row td:first-child {
        order: -2;
        flex: 0 0 auto;
    }
    .tpt-table .tpt-row td:first-child::before { content: none; }
    .tpt-table .tpt-row td:nth-child(3) {     /* Heure */
        order: -1;
        flex: 1 1 auto;
        justify-content: flex-end;
        font-weight: 700;
        color: var(--text);
    }
    .tpt-table .tpt-row td:nth-child(3)::before { content: none; }
    /* Séparateur pleine largeur sous l'en-tête (porté par la 1re ligne de champ) */
    .tpt-table .tpt-row td:nth-child(2) {     /* Chauffeur = 1er champ sous l'en-tête */
        border-top: 1px solid var(--border);
        padding-top: 8px;
        margin-top: 6px;
    }
    /* Valeur Trajet : laissée wrapper en entier sur mobile (plus d'ellipsis) */
    .tpt-table .tpt-row .tpt-route { white-space: normal; text-align: right; }
    /* Cellule action (✕ annuler) : pas de libellé, bouton aligné à droite */
    .tpt-table .tpt-row td.tpt-td-action { justify-content: flex-end; padding-top: 6px; }
    .tpt-table .tpt-row td.tpt-td-action::before { content: none; }
    /* Liseré transit : bordure gauche sur la carte entière plutôt que 1 cellule */
    .tpt-row-transit td:first-child { border-left: none; padding-left: 0; }
    .tpt-table .tpt-row.tpt-row-transit { border-left: 4px solid #4a90e2; padding-left: 10px; }
    /* Ligne de détail dépliée : pleine largeur, pas de label:valeur */
    .tpt-table .tpt-detail-row { display: block; }
    .tpt-table .tpt-detail-row td { display: block; padding: 12px; }
    .tpt-table .tpt-detail-row td::before { content: none; }
}

.tpt-row { transition: background 0.1s; }
/* Survol et zébrage : teintes tirées de l'encre du thème plutôt que
   `--bg-hover`, qui vaut le gris des pastilles neutres — une ligne survolée
   faisait disparaître le badge de site posé dessus. */
.tpt-row:hover { background: color-mix(in srgb, var(--text) 8%, var(--bg-card)); }
.tpt-row-alt { background: color-mix(in srgb, var(--text) 4%, var(--bg-card)); }

/* Transits & courses sans event rattaché (event_id IS NULL) : liseré
   gauche bleu pour les distinguer visuellement des courses event clients.
   Critère élargi (P1.3 review C1+C2+C3, 2026-05-06) : `!d.event_id` seul,
   capture aussi les transits legacy à reference NULL ou format différent.
   Appliqué sur la première td car border-left sur <tr> n'est pas rendu
   de façon fiable dans toutes les tables non-collapsed. */
.tpt-row-transit td:first-child {
    border-left: 4px solid #4a90e2;
    padding-left: 12px;
}

/* Route truncation */
.tpt-route {
    display: inline-block;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: middle;
    color: var(--text);
}

/* Provider — le nom du transporteur, pour l'identifier en un coup d'œil quand
   il n'a pas de logo. La couleur vient du registre (`transporteurs.couleur`),
   posée en marque latérale : en fond, elle ne garantirait aucun contraste avec
   le texte — un transporteur ajouté à l'écran choisit sa couleur librement. */
.tpt-provider {
    display: inline-block;
    font-weight: 800;
    font-size: 0.72rem;
    letter-spacing: 0.02em;
    padding: 3px 10px;
    border-radius: 999px;
    line-height: 1.4;
    background: var(--bg-input);
    color: var(--text);
    box-shadow: inset 3px 0 0 var(--prov-couleur, var(--border));
}

/* Logo officiel du transporteur — icône de marque carrée, une par ligne. */
.tpt-logo {
    width: 26px;
    height: 26px;
    border-radius: 6px;
    object-fit: cover;
    vertical-align: middle;
    display: inline-block;
}
.tpt-logo-petit {
    width: 16px;
    height: 16px;
    border-radius: 4px;
    flex: none;
}

/* Bouton d'annulation de course (✕). */
.tpt-cancel-btn {
    color: var(--error);
    padding: 4px 8px;
}
.tpt-cancel-btn:hover { background: rgba(239,68,68,0.12); }

/* Status badges for transport */
.tpt-table .badge {
    padding: 4px 12px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.3px;
    border-radius: 4px;
    display: inline-block;
}
/* Pastilles opaques (encre foncée sur aplat pâle) plutôt que translucides :
   le fond de la pastille ne dépend plus de celui de la page, donc le même
   couple tient sur les six thèmes, clairs comme sombres. */
.tpt-st-created   { background: #e2e5eb; color: #363c49; }
.tpt-st-pending   { background: #fde68a; color: #78350f; }
.tpt-st-assigned  { background: #fed7aa; color: #7c2d12; }
.tpt-st-progress  { background: #bfdbfe; color: #1e3a8a; }
.tpt-st-delivered { background: #bbf7d0; color: #14532d; }
.tpt-st-cancelled { background: #fecaca; color: #7f1d1d; text-decoration: line-through; }

/* Event link in table */
.tpt-event-link {
    color: var(--primary);
    text-decoration: none;
    font-size: 0.82rem;
    font-weight: 500;
}
.tpt-event-link:hover { text-decoration: underline; }

/* Liens d'action dans le tableau (BO, Client, Appeler, Copier) — couleur
   d'accent du thème, fixée y compris :visited pour éviter le violet du lien
   « visité » par défaut du navigateur. */
.tpt-table .tpt-link,
.tpt-table .tpt-link:visited { color: var(--primary); text-decoration: none; font-weight: 500; }
.tpt-table .tpt-link:hover { text-decoration: underline; }

/* Detail row (expanded) */
.tpt-detail-row td {
    background: var(--bg-hover);
    padding: 16px 20px;
    border-top: 1px solid var(--border);
}
.tpt-detail {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
}
@media (max-width: 768px) {
    .tpt-detail { grid-template-columns: 1fr; }
}
.tpt-detail-col {
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 12px;
}
.tpt-detail-col h4 {
    color: var(--text-muted);
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-bottom: 8px;
    padding-bottom: 4px;
    border-bottom: 1px solid var(--border);
}
.tpt-detail-col p {
    font-size: 0.82rem;
    margin-bottom: 4px;
    color: var(--text);
}
.tpt-detail-col a { color: var(--primary); text-decoration: none; font-weight: 500; }
.tpt-detail-col a:hover { text-decoration: underline; }
.tpt-detail-muted { color: var(--text-muted); }

/* ── Prochaines actions (event_detail) ──────────────────────────────── */
.next-actions {
    margin-bottom: 1rem;
    overflow: hidden;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-radius: 10px;
}
.next-actions-title {
    padding: 9px 14px 8px;
    color: var(--text-muted);
    background: color-mix(in srgb, var(--primary) 3%, transparent);
    font-size: 0.68rem;
    font-weight: 750;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.next-actions-list { display: flex; flex-direction: column; }
.next-action-row {
    width: 100%;
    min-height: 46px;
    display: grid;
    grid-template-columns: 32px minmax(0, 1fr) auto auto;
    gap: 10px;
    align-items: center;
    padding: 7px 14px;
    color: var(--text);
    background: transparent;
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0;
    font: inherit;
    text-align: left;
}
button.next-action-row { cursor: pointer; transition: background 0.15s; }
button.next-action-row:hover { background: color-mix(in srgb, var(--primary) 5%, transparent); }
.next-action-label { min-width: 0; font-size: 0.875rem; font-weight: 650; }
.next-action-meta {
    color: var(--text-muted);
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.next-action-chevron { color: var(--text-muted); font-size: 1.15rem; line-height: 1; }
.next-action-dot {
    width: 9px;
    height: 9px;
    margin-left: 10px;
    border: 2px solid var(--primary);
    border-radius: 50%;
}
.next-action-response.is-vert .next-action-meta { color: var(--role-ok-ink); }
.next-action-response.is-orange .next-action-meta { color: var(--role-warn-ink); }
.next-action-response.is-rouge .next-action-meta { color: var(--role-danger-ink); font-weight: 700; }
.next-action-response.is-nuit .next-action-meta { color: var(--text-muted); }
.next-action-proposed,
.next-action-suggested { cursor: default; }
.next-action-proposed .next-action-dot,
.next-action-suggested .next-action-dot {
    border-color: var(--chat-propose-ink);
    border-style: dashed;
}
.next-action-suggested { color: var(--text-muted); }
.next-action-warning .next-action-dot {
    border: 0;
    background: var(--role-info);
}
.next-action-warning.is-warning .next-action-dot { background: var(--role-warn); }
.next-action-warning.is-critical .next-action-dot { background: var(--role-danger); }
.next-action-controls { display: inline-flex; align-items: center; gap: 4px; }
.next-action-controls button {
    width: 26px;
    height: 26px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    font-size: 0.85rem;
    line-height: 1;
    cursor: pointer;
}
.next-action-controls button:hover { background: color-mix(in srgb, currentColor 10%, transparent); }
.next-action-controls .next-action-treat {
    width: auto;
    padding: 0 8px;
    color: var(--primary);
    border: 1px solid currentColor;
    border-radius: 6px;
    font-size: 0.72rem;
}
.next-action-controls .todo-ok { color: var(--role-ok-ink); }
.next-action-controls .todo-no { color: var(--role-danger-ink); }

.flash-highlight { animation: flashHighlight 2s ease; }
@keyframes flashHighlight {
    0%, 100% { background-color: transparent; }
    25%      { background-color: rgba(245, 158, 11, 0.3); }
}

/* ═══════════════════════════════════════════════════════════════════════
   Cockpit admin (préfixe .ck-) — la barre de nav vit dans css/plk_sidebar.css
   Classes préfixées, sans reset global. Source des liens : web/nav.py.
   ═══════════════════════════════════════════════════════════════════════ */

@font-face {
    font-family: 'IBM Plex Sans';
    font-weight: 400; font-style: normal; font-display: swap;
    src: url('/static/fonts/IBMPlexSans-Regular.woff2') format('woff2');
}
@font-face {
    font-family: 'IBM Plex Sans';
    font-weight: 500; font-style: normal; font-display: swap;
    src: url('/static/fonts/IBMPlexSans-Medium.woff2') format('woff2');
}
@font-face {
    font-family: 'IBM Plex Sans';
    font-weight: 600; font-style: normal; font-display: swap;
    src: url('/static/fonts/IBMPlexSans-SemiBold.woff2') format('woff2');
}
/* Le serif des titres : compagnon dessiné du sans ci-dessus, mêmes proportions.
   `block` et non `swap` — un titre qui change de police après coup se voit. */
@font-face {
    font-family: 'IBM Plex Serif';
    font-weight: 400; font-style: normal; font-display: block;
    src: url('/static/fonts/IBMPlexSerif-Regular.woff2') format('woff2');
}

/* ── Échelle typographique ────────────────────────────────────────────────
   Une tête de page se pose par sa TAILLE, pas par sa graisse : 30 px en 400
   structure là où 19 px en 750 ne fait que souligner. Les titres passent au
   serif, l'interface reste au sans. À réserver aux titres et aux grands
   nombres — dans un tableau dense, le serif élargit les chasses et casse
   l'alignement des colonnes chiffrées. */
:root {
    --f-serif: 'IBM Plex Serif', Georgia, serif;
    --t-page: clamp(24px, 2.6vw, 32px);   /* tête de page */
    --t-sect: 21px;                       /* titre de section */
    --t-sous: 16px;                       /* sous-section */
    --t-poids: 400;
    --t-ls: -0.018em;
}
.plk-titre {
    font-family: var(--f-serif);
    font-size: var(--t-page);
    font-weight: var(--t-poids);
    letter-spacing: var(--t-ls);
    line-height: 1.12;
    text-wrap: balance;
}

/* ── Marge de page ────────────────────────────────────────────────────────
   Une seule gouttière pour toutes les pages admin. Chaque page se donnait la
   sienne — de 10 à 32 px — et les titres partaient de 236 à 284 px selon
   l'écran ouvert. Le conteneur la porte désormais ; les pages ne remettent
   pas de padding horizontal par-dessus. */
:root { --page-x: 20px; --page-y: 14px; }
.admin-main { padding: var(--page-y) var(--page-x) 0; }

:root {
    --accent: #3d7bff;
    --accent-soft: rgba(61, 123, 255, 0.12);
    --hair: rgba(255, 255, 255, 0.07);
    --sb-bg: #0d0f14;
}

body.dark {
    font-family: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    letter-spacing: 0.005em;
}

.tnum { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

/* ── Topbar + wordmark ────────────────────────────────────────────────── */
.topbar { border-bottom: 1px solid var(--hair); }
.topbar-brand { display: flex; align-items: center; gap: 5px; text-decoration: none; }
.wm-name {
    font-size: 16px; font-weight: 600; color: var(--text);
    letter-spacing: -0.01em;
}
.wm-os {
    font-size: 9px; font-weight: 600; letter-spacing: 0.06em;
    color: var(--accent); background: var(--accent-soft);
    padding: 2px 4px; border-radius: 4px; line-height: 1;
}
.hamburger { display: flex; }
@media (min-width: 1024px) { .hamburger { display: none; } }
@media (min-width: 1024px) {
    .admin-main {
        margin-left: var(--sb-w);
        max-width: calc(var(--sb-w) + 1320px);
        margin-right: 0;
    }
}

/* ── Cockpit (/admin) — page de pilotage ──────────────────────────────── */
.ck { padding: 28px 32px 64px; max-width: 1160px; margin: 0 auto; }
[x-cloak] { display: none !important; }

.ck-hello { margin-bottom: 26px; }
.ck-hello-date {
    font-size: 19px; font-weight: 620; color: var(--text);
    letter-spacing: -0.01em; margin-bottom: 3px;
}
/* Le résumé énumère ce qui attend : utile, mais il ne commande rien. Il passe
   sous la date, en sourdine — « À faire maintenant » est le seul impératif. */
.ck-hello-line { font-size: 13px; color: var(--text-muted); line-height: 1.45; }

/* Section : accent par --sec, apparition douce en cascade */
.ck-sec {
    margin-bottom: 36px;
    opacity: 0; transform: translateY(6px);
    animation: ckIn 0.4s ease forwards;
    animation-delay: calc(var(--i, 0) * 70ms);
}
@keyframes ckIn { to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
    .ck-sec { animation: none; opacity: 1; transform: none; }
}
.ck-sec-head { display: flex; align-items: center; gap: 9px; margin-bottom: 13px; }
.ck-sec-dot {
    width: 9px; height: 9px; border-radius: 3px; flex-shrink: 0;
    background: var(--sec, var(--accent));
    box-shadow: 0 0 12px color-mix(in srgb, var(--sec, var(--accent)) 50%, transparent);
}
.ck-sec-title {
    font-size: 11px; font-weight: 600; margin: 0;
    letter-spacing: 0.1em; text-transform: uppercase;
    color: var(--text-muted);
}
.ck-sec-link { margin-left: auto; font-size: 12px; color: var(--text-muted); text-decoration: none; }
.ck-sec-link:hover { color: var(--sec, var(--accent)); }
.ck-empty { padding: 16px 14px; font-size: 13px; color: var(--text-muted); }

/* Ventes du jour : un chiffre qu'on lit d'un coup d'œil, son repère en
   dessous. Pas de couleur de verdict — un CA n'est ni bon ni mauvais à midi. */
.ck-ventes { margin-bottom: 30px; }
.vt-line { display: flex; align-items: baseline; gap: 20px; flex-wrap: wrap; }
.vt-total {
    font-size: 30px; font-weight: 600; color: var(--text);
    letter-spacing: -0.02em; line-height: 1.1;
}
.vt-shops { display: flex; gap: 18px; flex-wrap: wrap; }
.vt-shop { font-size: 13px; color: var(--text); }
.vt-shop em { font-style: normal; color: var(--text-muted); margin-right: 6px; }
.vt-ref { margin-top: 6px; font-size: 12px; color: var(--text-muted); opacity: 0.85; }
.vt-ref b { font-weight: 600; color: var(--text-muted); }

/* Les ventes : trois chiffres nommés, aucune courbe — un graphique de deux
   semaines ne se lit pas d'un coup d'œil et n'aide pas à décider. */
.vt-quand { font-size: 13px; color: var(--text-muted); }
.vt-quand em { font-style: normal; display: block; font-size: 12px; opacity: .8; }
.vt-gliss { display: flex; flex-wrap: wrap; gap: 22px; margin-top: 9px; }
.vt-g { font-size: 13px; color: var(--text); }
.vt-g em { font-style: normal; color: var(--text-muted); margin-right: 7px;
           font-size: 11px; letter-spacing: .07em; text-transform: uppercase;
           font-weight: 600; }
.vt-g b { font-weight: 650; margin-left: 6px; }
.vt-g b.up { color: var(--role-ok-ink, #14603a); }
.vt-g b.down { color: var(--role-danger-ink, #972b24); }
.vt-vs { font-size: 11px; color: var(--text-muted); margin-left: 3px; }

/* Blocs Équipe et Réglementation : une famille d'anomalies par carte, et
   DANS la carte, qui est concerné. C'est le nom qui rend la ligne actionnable
   — « 3 titres de séjour » n'apprend rien, « BA Moussa » se traite. */
.fam-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
            gap: 10px; }
.fam {
    display: block; text-decoration: none; padding: 13px 15px 14px; border-radius: 13px;
    background: var(--bg-card); border-left: 3px solid var(--fam, var(--border));
    box-shadow: 0 1px 2px rgba(23, 28, 60, .05), 0 10px 24px -20px rgba(23, 28, 60, .45);
    transition: background .15s ease;
}
.fam:hover { background: var(--bg-hover); }
.fam-danger { --fam: var(--role-danger); }
.fam-warn { --fam: var(--role-warn); }
.fam-tete { display: flex; align-items: baseline; gap: 10px; margin-bottom: 9px; }
.fam-t { font-size: 13.5px; font-weight: 620; color: var(--text); }
.fam-k { margin-left: auto; font-size: 13px; font-weight: 700;
         color: var(--fam, var(--text-muted)); font-variant-numeric: tabular-nums; }
.fam-qui { display: flex; flex-wrap: wrap; gap: 5px; }
.fam-chip {
    font-size: 11.5px; line-height: 1.35; color: var(--text-muted);
    background: var(--bg-hover); border-radius: 7px; padding: 3px 8px;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.fam-act { display: inline-block; margin-top: 10px; font-size: 12.5px; font-weight: 620;
           color: var(--fam, var(--text-muted)); }

/* Les prochaines courses, sous le bloc Transport. Une ligne par course :
   qui, dans quel sens, à quelle heure, et si un coursier est affecté. */
.crs { margin-top: 10px; border-top: 1px solid var(--hair); }
.crs-l { display: flex; align-items: baseline; gap: 11px; padding: 8px 2px;
         text-decoration: none; border-bottom: 1px solid var(--hair); font-size: 13px; }
.crs-l:last-child { border-bottom: 0; }
.crs-l:hover .crs-qui { text-decoration: underline; }
.crs-pt { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0;
          transform: translateY(-1px); }
.crs-pt.ok { background: var(--role-ok, #1f8a52); }
.crs-pt.att { background: var(--role-warn, #8a6410); }
.crs-qui { color: var(--text); font-weight: 600; }
.crs-sens, .crs-quand { color: var(--text-muted); font-size: 12px; }
.crs-etat { margin-left: auto; font-size: 11.5px; color: var(--text-muted); }

/* Le pouls : une pastille par section. Nom, chiffre, couleur — rien d'autre.
   Le détail vit dans le bloc que la pastille désigne, une seule fois. */
.ck-pouls {
    display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 30px;
    opacity: 0; transform: translateY(6px);
    animation: ckIn 0.4s ease forwards; animation-delay: calc(var(--i, 0) * 70ms);
}
@media (prefers-reduced-motion: reduce) { .ck-pouls { animation: none; opacity: 1; transform: none; } }
.pl {
    display: inline-flex; align-items: baseline; gap: 9px;
    padding: 8px 14px; border-radius: 11px; text-decoration: none;
    background: var(--bg-card); border: 1px solid var(--border);
    transition: transform .15s ease, box-shadow .15s ease;
}
.pl:hover { transform: translateY(-1px); box-shadow: 0 6px 16px -8px rgba(23, 28, 60, .4); }
.pl-nom { font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; }
.pl-k { font-size: 16px; font-weight: 700; letter-spacing: -.02em;
        font-variant-numeric: tabular-nums; }
.pl-danger { background: var(--role-danger-bg); border-color: transparent; color: var(--role-danger-ink); }
.pl-warn { background: var(--role-warn-bg); border-color: transparent; color: var(--role-warn-ink); }
.pl-info { background: var(--role-info-bg); border-color: transparent; color: var(--role-info-ink); }
.pl-ok { background: var(--role-ok-bg); border-color: transparent; color: var(--role-ok-ink); }

/* Une ancre ne doit pas coller le bloc au bord haut de la fenêtre. */
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
.ck-sec[id] { scroll-margin-top: 18px; }

/* « À regarder » : une carte par file d'anomalies qui bouge. Rien d'alarmant —
   un point de couleur tenue, un chiffre en sourdine, et de l'air. Le total ne
   prend jamais le dessus sur ce qui vient d'entrer. */
.sig-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 8px 20px; }
/* Le domaine ne fait pas colonne : son nom barre la grille et ses cartes s'y
   rangent. Sinon un seul domaine étire ses cartes sur toute la largeur. */
.sig-dom { display: contents; }
.sig-dom-nom {
    grid-column: 1 / -1; margin: 15px 0 3px;
    font-size: 10.5px; font-weight: 500; color: var(--text-muted); opacity: 0.7;
    letter-spacing: 0.09em; text-transform: uppercase;
}
.sig-dom-nom:first-child { margin-top: 0; }
.sig-card {
    display: block; text-decoration: none; min-width: 0;
    padding: 13px 16px 14px; border-radius: 14px;
    background: var(--bg-card);
    transition: background 0.18s ease, transform 0.18s ease;
}
.sig-card:hover { background: var(--bg-hover); transform: translateY(-1px); }
.sig-line { display: flex; align-items: baseline; gap: 9px; }
.sig-dot {
    width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0;
    transform: translateY(-1px);
    background: var(--sig, var(--text-muted)); opacity: 0.8;
}
.sig-titre {
    font-size: 13.5px; font-weight: 550; color: var(--text);
    line-height: 1.35; min-width: 0;
}
.sig-ou {
    margin-left: auto; flex-shrink: 0; padding-left: 10px;
    font-size: 10px; font-weight: 500; letter-spacing: 0.07em;
    text-transform: uppercase; color: var(--text-muted); opacity: 0.6;
}
.sig-n { color: var(--sig, var(--text-muted)); font-weight: 600; }
.sig-sub {
    margin: 5px 0 0 15px; font-size: 11.5px; line-height: 1.5;
    color: var(--text-muted); opacity: 0.85;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
    overflow: hidden;
}
/* Teintes tenues : sable pour ce qui vient d'arriver, terre pour ce qui traîne. */
.sig-orange { --sig: #d8b779; }
.sig-rouge { --sig: #c98b7a; }

/* Grille 2×2 : emails importants / emails catering / caterings J-J+1 /
   actions urgentes. En dessous : commandes, comptabilité (pleine largeur).
   minmax(0,1fr) + min-width:0 : sans ça, les textes nowrap des cartes forcent
   les colonnes au-delà de 1fr (grid blowout) et la page déborde à droite. */
.ck-grid2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 6px 30px; align-items: start; }
@media (max-width: 980px) { .ck-grid2 { grid-template-columns: minmax(0, 1fr); } }
.ck-grid2 > .ck-sec { min-width: 0; }
.ck-grid2 .notif-card { min-width: 0; }
.ck-grid2 .notif-left { min-width: 0; }
.ck-grid2 .notif-left > div { min-width: 0; }
.ck-grid2 .notif-issue, .ck-grid2 .notif-client {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    display: block; max-width: 100%;
}

/* Groupes jour (caterings J/J+1) — empilés dans leur cellule */
.ck-days { display: flex; flex-direction: column; gap: 4px; }

/* État « rien à faire » : positif, jamais vide-anxiogène */
.ck-zen {
    padding: 14px 16px; font-size: 13px; color: #5aa87a;
    background: rgba(90, 168, 122, 0.07);
    border: 1px dashed rgba(90, 168, 122, 0.3); border-radius: 10px;
}
.ck-zen.soft {
    color: var(--text-muted); background: none;
    border-color: var(--hair); text-align: center;
}

/* ── VIP : emails à répondre en priorité ── */
.ck-vips {
    background: var(--bg-card); border: 1px solid var(--hair);
    border-radius: 12px; overflow: hidden;
}
.ck-vip {
    display: flex; align-items: center; gap: 13px;
    padding: 13px 16px; text-decoration: none;
    border-bottom: 1px solid var(--hair);
    transition: background 0.12s;
}
.ck-vip:last-child { border-bottom: none; }
.ck-vip:hover { background: var(--bg-hover); }
.ck-ava {
    position: relative; flex-shrink: 0;
    width: 36px; height: 36px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 13px; font-weight: 700; letter-spacing: 0.02em;
    color: var(--sec, var(--accent));
    background: color-mix(in srgb, var(--sec, var(--accent)) 16%, transparent);
}
.ck-ava-dot {
    position: absolute; top: -1px; right: -1px;
    width: 9px; height: 9px; border-radius: 50%;
    background: var(--sec, var(--accent));
    border: 2px solid var(--bg-card);
}
.ck-vip-main { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ck-vip-name { font-size: 14px; font-weight: 600; color: var(--text); }
.ck-vip-co { font-weight: 400; color: var(--text-muted); font-size: 13px; }
.ck-vip-subj {
    font-size: 12.5px; color: var(--text-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ck-vip-ago { margin-left: auto; flex-shrink: 0; font-size: 12px; color: var(--text-muted); }
/* Le compte à rebours de première réponse : il prend la place de l'âge du
   fil, parce qu'un délai qu'on subit vaut moins qu'un délai qu'on tient. */
.ck-chrono-wrap { margin-left: auto; flex-shrink: 0; display: flex; align-items: center; }
.ck-retard { flex-shrink: 0; font-size: 11.5px; font-weight: 700; text-decoration: none;
    color: #8f3729; background: rgba(143,55,41,.12); border: 1px solid rgba(143,55,41,.30);
    border-radius: 999px; padding: 2px 10px; }
.ck-retard:hover { background: rgba(143,55,41,.20); }
/* L'anneau du compte à rebours : le chiffre vit dedans, la couleur porte
   l'urgence, et la nuit se dit en pointillés — le compteur ne tourne pas. */
.plk-chrono { position: relative; display: inline-grid; place-items: center;
    flex: 0 0 auto; line-height: 0; }
.plk-chrono svg { display: block; }
.plk-chrono .sur { stroke: #6d2519; }
.plk-chrono b { position: absolute; font-size: 9px; font-weight: 800;
    letter-spacing: -.02em; font-variant-numeric: tabular-nums; line-height: 1; }
.plk-chrono.vert   { color: #1c5138; }
.plk-chrono.orange { color: #8a5b00; }
.plk-chrono.rouge  { color: #8f3729; }
.ck-vip-go {
    flex-shrink: 0; font-size: 12px; font-weight: 600;
    color: var(--sec, var(--accent));
    padding: 5px 11px; border-radius: 999px;
    background: color-mix(in srgb, var(--sec, var(--accent)) 12%, transparent);
    transition: background 0.12s;
}
.ck-vip:hover .ck-vip-go { background: color-mix(in srgb, var(--sec, var(--accent)) 22%, transparent); }

/* Feed générique (emails catering à répondre) */
.ck-feed {
    background: var(--bg-card); border: 1px solid var(--hair);
    border-radius: 12px; overflow: hidden;
}
.ck-row {
    display: flex; align-items: baseline; gap: 10px;
    padding: 12px 14px; text-decoration: none;
    border-bottom: 1px solid var(--hair);
    transition: background 0.12s;
}
.ck-row:last-child { border-bottom: none; }
.ck-row:hover { background: var(--bg-hover); }
.ck-row-main {
    font-size: 13px; font-weight: 500; color: var(--text);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    flex-shrink: 0; max-width: 55%;
}
.ck-row-sub {
    margin-left: auto; font-size: 12px; color: var(--text-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── Commandes du jour : lignes dépliables ── */
.ck-ords {
    background: var(--bg-card); border: 1px solid var(--hair);
    border-radius: 12px; overflow: hidden;
}
.ck-ordrow { border-bottom: 1px solid var(--hair); }
.ck-ordrow:last-child { border-bottom: none; }
.ck-ordrow.go { background: color-mix(in srgb, var(--sec, var(--accent)) 6%, transparent); }
.ck-ordrow-head {
    display: flex; align-items: center; gap: 13px; width: 100%;
    padding: 12px 16px; background: none; border: none; cursor: pointer;
    text-align: left; font: inherit; color: inherit;
    transition: background 0.12s;
}
.ck-ordrow-head:hover { background: var(--bg-hover); }
.ck-ord-ico {
    flex-shrink: 0; width: 32px; height: 32px; border-radius: 9px;
    display: flex; align-items: center; justify-content: center;
    font-size: 13px; font-weight: 700;
    color: var(--sec, var(--accent));
    background: color-mix(in srgb, var(--sec, var(--accent)) 15%, transparent);
}
.ck-ord-main { min-width: 0; display: flex; flex-direction: column; gap: 1px; flex: 1; }
.ck-ord-label { font-size: 13.5px; font-weight: 600; color: var(--text); }
.ck-ord-sub {
    font-size: 12px; color: var(--text-muted);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ck-pill {
    flex-shrink: 0; font-size: 11.5px; font-weight: 600;
    padding: 4px 10px; border-radius: 999px;
}
.ck-pill.sent { color: #5aa87a; background: rgba(90, 168, 122, 0.13); }
.ck-pill.pending { color: #8fb4e3; background: rgba(122, 162, 214, 0.14); }
.ck-pill.wait { color: var(--text-muted); background: var(--bg-hover); }
.ck-pill.go { color: #0e0f14; background: var(--sec, var(--accent)); }
.ck-ordrow-caret { flex-shrink: 0; font-size: 12px; color: var(--text-muted); width: 12px; }
.ck-ordrow-body { padding: 4px 16px 14px 61px; }
.ck-ordrow-items {
    margin: 0 0 12px; padding: 0; list-style: none;
    columns: 2; column-gap: 28px;
    font-size: 12.5px; color: var(--text-muted); line-height: 1.75;
}
@media (max-width: 720px) { .ck-ordrow-items { columns: 1; } }
.ck-ordrow-actions { display: flex; gap: 9px; flex-wrap: wrap; }
.ck-btn {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 12.5px; font-weight: 600; cursor: pointer;
    padding: 7px 13px; border-radius: 999px; border: 1px solid var(--hair);
    background: var(--bg-input); color: var(--text); text-decoration: none;
    transition: background 0.12s, border-color 0.12s;
}
.ck-btn:hover { background: var(--bg-hover); }
.ck-btn.primary {
    background: var(--sec, var(--accent)); color: #0e0f14; border-color: transparent;
}
.ck-btn.primary:hover { opacity: 0.88; }
.ck-btn.danger { color: #c47b7b; }
.ck-btn.danger:hover { border-color: #c47b7b; }

/* ── Comptabilité : carte unique ── */
.ck-paycard {
    display: flex; align-items: center; gap: 22px; flex-wrap: wrap;
    background: var(--bg-card); border: 1px solid var(--hair);
    border-radius: 14px; padding: 18px 22px;
    text-decoration: none;
    transition: border-color 0.13s, background 0.12s;
}
.ck-paycard:hover {
    background: var(--bg-hover);
    border-color: color-mix(in srgb, var(--sec, var(--accent)) 45%, var(--hair));
}
.ck-pay-total { display: flex; flex-direction: column; gap: 2px; flex-shrink: 0; }
.ck-pay-amount {
    font-size: 28px; font-weight: 700; color: var(--text);
    letter-spacing: -0.01em; line-height: 1.1;
}
.ck-pay-count { font-size: 12px; color: var(--text-muted); }
.ck-pay-chips { display: flex; flex-wrap: wrap; gap: 7px; flex: 1; min-width: 200px; }
.ck-chip {
    font-size: 11px; font-weight: 500; padding: 2.5px 9px; border-radius: 999px;
    color: #d8bd8a; background: rgba(203, 171, 110, 0.13);
}
.ck-chip.pay {
    color: var(--text); background: var(--bg-hover);
    font-size: 12px; padding: 5px 12px;
    display: inline-flex; align-items: center; gap: 4px;
}
.ck-chip.pay b { font-weight: 600; }
.ck-chip-mode { font-size: 10.5px; color: var(--text-muted); margin-left: 3px; }
.ck-pay-go {
    flex-shrink: 0; font-size: 12.5px; font-weight: 600;
    color: var(--sec, var(--accent));
}

/* ── En-tête event (fiche + inbox) : complétion façon carte pipeline ──
   Remplace l'ancien bloc .evt-reste (matrice sections × étapes, retiré le
   2026-07-10 — trop anxiogène, doublon de l'onglet Pipeline). */
.evt-progress {
    display: flex; align-items: center; gap: 10px;
    margin-top: 10px;
}
.evt-progress-track {
    flex: 1; height: 5px; border-radius: 999px;
    background: var(--bg-hover); overflow: hidden;
}
.evt-progress-bar { display: block; height: 100%; border-radius: 999px; }
.evt-progress-pct {
    flex-shrink: 0; font-size: 12.5px; font-weight: 700;
    font-variant-numeric: tabular-nums;
}
.evt-progress-done { flex-shrink: 0; font-size: 12px; font-weight: 600; color: #5aa87a; }

/* ── Réglages (/admin/settings) ── */
.st { padding: 28px 32px 64px; max-width: 860px; margin: 0 auto; }
.st-title { font-size: 21px; font-weight: 650; color: var(--text); margin-bottom: 26px; }
.st-sec-title {
    font-size: 11px; font-weight: 600; margin: 0 0 4px;
    letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-muted);
}
.st-hint { font-size: 12.5px; color: var(--text-muted); margin-bottom: 14px; }
.st-themes { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 14px; }
.st-theme {
    display: flex; flex-direction: column; gap: 4px; text-align: left;
    padding: 10px; border-radius: 14px; cursor: pointer; font: inherit;
    background: var(--bg-card); border: 2px solid var(--hair); color: var(--text);
    transition: border-color 0.13s, transform 0.13s, box-shadow 0.13s;
}
.st-theme:hover { transform: translateY(-2px); box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12); }
.st-theme.on { border-color: var(--accent); }
.st-prev {
    display: flex; flex-direction: column; gap: 7px; justify-content: center;
    height: 96px; border-radius: 9px; padding: 10px 12px; margin-bottom: 6px;
    overflow: hidden; position: relative;
}
.st-prev-top {
    position: absolute; top: 0; left: 0; right: 0; height: 12px;
}
.st-prev-bar {
    display: flex; align-items: center; gap: 7px;
    height: 24px; border-radius: 6px; padding: 0 9px;
}
.st-prev-bar i { width: 11px; height: 11px; border-radius: 50%; flex-shrink: 0; }
.st-prev-bar b { display: block; height: 5px; border-radius: 999px; width: 46%; }
.st-theme-name { font-size: 14.5px; font-weight: 650; display: flex; align-items: center; gap: 8px; }
.st-badge {
    font-size: 10.5px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
    color: var(--accent); background: var(--accent-soft);
    padding: 2px 8px; border-radius: 999px;
}
.st-theme-desc { font-size: 12.5px; color: var(--text-muted); line-height: 1.4; }
.st-sec + .st-sec { margin-top: 34px; }
.st-form { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; }
.st-champ { display: flex; flex-direction: column; gap: 4px; max-width: 520px; }
.st-champ-nom { font-size: 13.5px; font-weight: 600; color: var(--text); }
.st-champ input, .st-champ select {
    font: inherit; font-size: 14px; width: 120px; padding: 7px 10px;
    border-radius: 9px; border: 1px solid var(--hair);
    background: var(--bg-input); color: var(--text);
}
.st-champ select { width: 200px; }
.st-champ input:focus-visible,
.st-champ select:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.st-champ-aide { font-size: 12.5px; color: var(--text-muted); line-height: 1.4; }
.st-save {
    font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
    padding: 8px 16px; border-radius: 9px; border: 1px solid var(--primary);
    background: var(--primary); color: var(--primary-ink);
}
.st-save:hover { background: var(--accent); }
.st-save:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Raccourcis */
.ck-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; }
.ck-tile {
    display: flex; align-items: center; gap: 9px;
    padding: 12px 14px; border-radius: 9px;
    background: var(--bg-card); border: 1px solid var(--hair);
    color: var(--text); text-decoration: none;
    font-size: 13px; font-weight: 500;
    transition: border-color 0.13s, background 0.13s;
}
.ck-tile:hover { border-color: var(--accent); background: var(--bg-hover); }
.ck-tile .nav-ico { flex-shrink: 0; color: var(--text-muted); }
.ck-tile:hover .nav-ico { color: var(--accent); }

/* ══════════════════════════════════════════════════════════════════════
   COUCHE COMMUNE — jetons + composants (21/07/2026)
   ══════════════════════════════════════════════════════════════════════
   Née du constat de Dimitri : « tes schémas sont plus beaux que mon site ».
   Le diagnostic n'était pas le goût mais la SÉDIMENTATION — chaque douleur
   passée a déposé son `style="margin-left:10px"` et son `#a6adc8` en dur, si
   bien que deux éléments voisins ne partagent plus ni gamme d'espacement, ni
   échelle de taille, ni sens des couleurs.

   Cette couche donne les briques manquantes. Règle d'usage : toute nouvelle
   UI puise ICI plutôt que d'inventer un style inline ; chaque douleur traitée
   fait converger une zone de plus. Purement ADDITIF — aucun sélecteur
   existant n'est touché, les noms sont préfixés `plk-` (convention déjà
   posée par plk_tabs.css).

   ── 1. RÔLES DE COULEUR ──
   Une couleur = UN métier, sinon plus aucune ne parle. info = identifiant ou
   action, ok = état sain, warn = attention, danger = destructif, presta =
   fournisseur (posé le 21/07 sur la page Emails). Ces rôles sont DISTINCTS
   de --primary (l'accent de marque, qui change selon le thème).
   Valeurs reprises de celles déjà en circulation dans l'app, pour que la
   couche se fonde dans l'existant au lieu de le contredire. */

:root {
    --role-info: #89b4fa;   --role-info-bg: rgba(137, 180, 250, .12);
    --role-ok: #5bc488;     --role-ok-bg: rgba(91, 196, 136, .12);
    --role-warn: #d9ac4f;   --role-warn-bg: rgba(217, 172, 79, .12);
    --role-danger: #e2827a; --role-danger-bg: rgba(226, 130, 122, .12);
    --role-presta: #a78bdb; --role-presta-bg: rgba(167, 139, 219, .12);
    /* Encre à poser SUR une teinte de rôle — `--role-X-bg` ou tout aplat de la
       même famille. Sur fond sombre un aplat teinté reste noir et la teinte du
       rôle s'y lit ; sur fond clair il vire au pastel et il faut une encre
       franchement plus foncée. Pas d'équivalent `presta` : aucune surface ne
       pose l'encre presta sur une teinte presta. */
    --role-info-ink: #4f8cff;
    --role-ok-ink: #4ade80;
    --role-warn-ink: #f59e0b;
    --role-danger-ink: #f87171;
    /* Les trois états d'une chose à faire — proposée (l'onde), à faire, faite.
       Définis ici parce que DEUX surfaces les portent (la rangée de l'inbox et
       celle de la fiche event) et qu'elles doivent rester identiques : chacune
       avait sa propre copie d'hexadécimaux, et elles avaient divergé. */
    --chip-todo-bg: rgba(137, 180, 250, .16);
    --chip-todo-border: #89b4fa;
    --chip-todo-ink: #89b4fa;
    --chip-todo-bg-hover: rgba(137, 180, 250, .26);
    --chip-done-bg: rgba(166, 227, 161, .16);
    --chip-done-border: rgba(166, 227, 161, .45);
    --chip-done-ink: #a6e3a1;
    --chip-btn-ok: var(--role-ok);
    --chip-btn-no: var(--role-danger);
    /* `--warning` est l'ancien nom du rôle « attention », encore porté par de
       nombreux composants. Alias unique : il suit le rôle de chaque thème.
       `.rh` garde son override local. */
    --warning: var(--role-warn);
}

/* ── Onde violette — le signal « proposé par la machine » ──
   Un seul dégradé pour tous les objets qui portent une suggestion IA. Il
   vivait dans le widget assistant ; il en sort pour que les chips puissent
   s'en servir sans dépendre d'un partial voisin. Coupé si l'utilisateur a
   demandé moins d'animation. */
@keyframes plkOnde { to { background-position: 300% 0 } }
/* Les formes qui la portent déclarent leur propre fond (`.plk-pill`,
   `.plk-btn`) : l'onde doit gagner sur elles, d'où les sélecteurs composés —
   une seule règle, pas un dégradé recopié. */
.plk-onde, .plk-pill.plk-onde, .plk-btn.plk-onde {
    color: #fff;
    background: linear-gradient(90deg, #7c3aed, #db2777, #0891b2, #7c3aed);
    background-size: 320% 100%;
    animation: plkOnde 7s linear infinite;
}
@media (prefers-reduced-motion: reduce) { .plk-onde { animation: none } }

:root {
    /* ── 2. GAMME D'ESPACEMENT ──
       Quatre pas, pas un de plus. Les distances riment ou l'œil décroche. */
    --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 24px;
}

/* Thèmes clairs : mêmes rôles, valeurs assombries pour rester lisibles sur
   fond pâle (un #5bc488 sur blanc tombe sous 3:1). */
:root[data-theme="jour"] {
    --role-info: #2f5ed4;   --role-info-bg: rgba(47, 94, 212, .10);
    --role-ok: #1f8a52;     --role-ok-bg: rgba(31, 138, 82, .10);
    --role-warn: #8a6410;   --role-warn-bg: rgba(138, 100, 16, .10);
    --role-danger: #b8352c; --role-danger-bg: rgba(184, 53, 44, .10);
    --role-presta: #6d4fa8; --role-presta-bg: rgba(109, 79, 168, .10);
}
:root[data-theme="joy"] {
    --role-info: #2f5ed4;   --role-info-bg: rgba(47, 94, 212, .10);
    --role-ok: #1f8a52;     --role-ok-bg: rgba(31, 138, 82, .10);
    --role-warn: #96590c;   --role-warn-bg: rgba(150, 89, 12, .11);
    --role-danger: #c0392f; --role-danger-bg: rgba(192, 57, 47, .10);
    --role-presta: #7a4fa0; --role-presta-bg: rgba(122, 79, 160, .10);
}
:root[data-theme="opale"] {
    --role-info: #2f5ed4;   --role-info-bg: rgba(47, 94, 212, .10);
    --role-ok: #1f8a52;     --role-ok-bg: rgba(31, 138, 82, .10);
    --role-warn: #8a6410;   --role-warn-bg: rgba(138, 100, 16, .10);
    --role-danger: #b8352c; --role-danger-bg: rgba(184, 53, 44, .10);
    --role-presta: #6d4fa8; --role-presta-bg: rgba(109, 79, 168, .10);
}
/* Une seule encre de rôle pour les trois thèmes clairs : calibrée sur la
   surface la plus sombre où elle peut se poser (une pastille d'état sur une
   ligne de pipeline validée, au survol), elle tient donc partout ailleurs. */
:root[data-theme="jour"], :root[data-theme="joy"], :root[data-theme="opale"] {
    --role-info-ink: #254db2;
    --role-ok-ink: #14603a;
    --role-warn-ink: #7a5410;
    --role-danger-ink: #972b24;
    /* Sur fond clair la chose à faire se voit : teinte franche et contour
       plein. Le « fait » reste en retrait — la hiérarchie tient en trois
       temps, l'onde appelle, le bleu attend, le vert s'efface. */
    --chip-todo-bg: #d7e3f8;
    --chip-todo-border: #2f5ed4;
    --chip-todo-ink: #1b3f8c;
    --chip-todo-bg-hover: #c8d8f4;
    --chip-done-bg: rgba(31, 138, 82, .10);
    --chip-done-border: rgba(31, 138, 82, .35);
    --chip-done-ink: #14603a;
    --chip-btn-ok: #14603a;
    --chip-btn-no: #972b24;
}

/* ── Roue dentée d'attente ──
   Une action qui part sans rien montrer laisse croire au clic manqué : on
   reclique, et certaines créent deux fois. La roue vit ici et pas dans une
   feuille de page : n'importe quel bouton de l'app peut la porter. */
.plk-rouage { display: inline-block; animation: plkRouage 1.1s linear infinite;
    transform-origin: 50% 50%; }
@keyframes plkRouage { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .plk-rouage { animation: none; } }

/* ── 3. PILULE (.plk-pill) ──
   L'action. Forme unique, hiérarchie par le remplissage et non par la taille :
   `is-primary` = l'action attendue, nu = alternative, `is-ghost` = discret,
   `is-danger` = ça détache/supprime. Un `<a>` et un `<button>` doivent rendre
   pareil, d'où la remise à plat des styles hérités. */
.plk-pill {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 6px 14px; border-radius: 999px;
    font-size: 12.5px; font-weight: 500; line-height: 1.35;
    font-family: inherit; white-space: nowrap; text-decoration: none;
    color: var(--text); background: var(--bg-input);
    border: 1px solid var(--border); cursor: pointer;
    transition: background .13s, border-color .13s, color .13s;
}
.plk-pill:hover { background: var(--bg-hover); border-color: var(--text-muted); }
.plk-pill:focus-visible { outline: 2px solid var(--role-info); outline-offset: 2px; }
.plk-pill:disabled, .plk-pill[aria-disabled="true"] { opacity: .5; cursor: default; }
.plk-pill.is-primary {
    background: var(--primary); border-color: var(--primary);
    /* L'encre d'un aplat primaire est celle du THÈME, jamais du blanc en dur :
       sur le verre (--primary #eaf4ff) le blanc tombait à 1,11:1. */
    color: var(--primary-ink);
}
.plk-pill.is-primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); }
.plk-pill.is-ghost { background: none; color: var(--text-muted); }
.plk-pill.is-ghost:hover { color: var(--text); background: var(--bg-hover); }
.plk-pill.is-danger { background: none; color: var(--role-danger); border-color: var(--role-danger); }
.plk-pill.is-danger:hover { background: var(--role-danger-bg); }
.plk-pill.is-warn { background: none; color: var(--role-warn-ink); border-color: var(--role-warn); }
.plk-pill.is-ok { background: none; color: var(--role-ok-ink); border-color: var(--role-ok); }
.plk-pill.is-ok:hover { background: var(--role-ok-bg); }
.plk-pill.is-warn:hover { background: var(--role-warn-bg); }
.plk-pill.is-sm { padding: 4px 10px; font-size: 11.5px; }

/* ── 4. ÉTIQUETTE (.plk-tag) ──
   L'état, encodé dans la FORME pour se scanner sans lecture (SIÈGE /
   SECONDAIRE / À CRÉER / ACARIS). Ce n'est pas cliquable — jamais de
   `cursor:pointer` ici, sinon la pilule ne veut plus rien dire. */
.plk-tag {
    display: inline-block; padding: 2px 8px; border-radius: 999px;
    font-size: 10px; font-weight: 700; letter-spacing: .05em;
    text-transform: uppercase; white-space: nowrap; vertical-align: baseline;
    color: var(--text-muted); border: 1px solid var(--border);
}
.plk-tag.is-info { color: var(--role-info); border-color: var(--role-info); }
.plk-tag.is-ok { color: var(--role-ok); border-color: var(--role-ok); }
.plk-tag.is-warn { color: var(--role-warn); border-color: var(--role-warn); }
.plk-tag.is-danger { color: var(--role-danger); border-color: var(--role-danger); }
.plk-tag.is-presta { color: var(--role-presta); border-color: var(--role-presta); }

/* ── 5. BANDEAU (.plk-banner) ──
   L'état d'un bloc, en une ligne, avant son détail. */
.plk-banner {
    display: flex; align-items: baseline; gap: var(--sp-2); flex-wrap: wrap;
    padding: 7px 12px; border-radius: 8px; font-size: 13px;
    border: 1px solid var(--border); color: var(--text);
}
.plk-banner.is-ok { border-color: var(--role-ok); background: var(--role-ok-bg); }
.plk-banner.is-warn { border-color: var(--role-warn); background: var(--role-warn-bg); }
.plk-banner.is-danger { border-color: var(--role-danger); background: var(--role-danger-bg); }
.plk-banner.is-info { border-color: var(--role-info); background: var(--role-info-bg); }

/* ── 6. LIGNE LIBELLÉ / VALEUR (.plk-row) ──
   Colonne de libellés à largeur FIXE : c'est ce qui fait que les valeurs
   s'alignent verticalement au lieu de commencer chacune où le libellé la
   laisse. Les identifiants (SIREN, SIRET) passent en `.plk-mono`, chiffres
   tabulaires pour que les colonnes de nombres s'empilent droit. */
.plk-rows { display: flex; flex-direction: column; gap: var(--sp-1); }
.plk-row { display: flex; align-items: baseline; gap: var(--sp-2); font-size: 13.5px; }
.plk-row > .plk-lbl { flex: none; width: 96px; color: var(--text-muted); font-size: 13px; }
.plk-row > .plk-val { min-width: 0; }
.plk-row .plk-src { color: var(--text-muted); font-size: 11.5px; }
.plk-mono {
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-variant-numeric: tabular-nums; color: var(--role-info);
}
/* Rangée d'actions : les pilules d'un bloc vivent dans un conteneur qui
   porte l'espacement (gap), jamais dans des margins posées une par une. */
.plk-actions { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.plk-actions.is-tight { gap: 6px; }

/* ── 7. GRAMMAIRE DE CHAMP (.plk-fs / .plk-grid / .plk-f) ──
   Un groupe de champs est un `fieldset` légendé — jamais une carte pour un
   champ isolé, jamais un libellé en ligne au milieu de libellés au-dessus.
   Dans le groupe, une grille de 12 colonnes : deux rangées voisines s'alignent
   verticalement parce qu'elles comptent dans le même pas. */
.plk-fs {
    min-width: 0; margin: 0 0 var(--sp-3); padding: 8px 14px 14px;
    background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px;
}
.plk-fs > legend {
    padding: 0 7px; font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 10px; letter-spacing: .13em; text-transform: uppercase;
    color: var(--accent-ink);
}
.plk-grid { display: grid; grid-template-columns: repeat(12, 1fr); gap: var(--sp-2) var(--sp-3); }
.plk-grid > .c2 { grid-column: span 2; }
.plk-grid > .c3 { grid-column: span 3; }
.plk-grid > .c4 { grid-column: span 4; }
.plk-grid > .c5 { grid-column: span 5; }
.plk-grid > .c6 { grid-column: span 6; }
.plk-grid > .c7 { grid-column: span 7; }
.plk-grid > .c8 { grid-column: span 8; }
.plk-grid > .c9 { grid-column: span 9; }
.plk-grid > .c12 { grid-column: 1 / -1; }
@media (max-width: 720px) { .plk-grid > * { grid-column: 1 / -1; } }

/* Le champ : étiquette au-dessus en petites capitales réduites, contrôle de
   32 px occupant toute la largeur de sa colonne. */
.plk-f { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.plk-f > label {
    font-size: 10px; font-weight: 700; letter-spacing: .09em; line-height: 1.5;
    text-transform: uppercase; color: var(--text-muted);
}
.plk-f input:not([type="checkbox"]):not([type="radio"]),
.plk-f select, .plk-f textarea {
    width: 100%; min-width: 0; box-sizing: border-box; height: 32px;
    padding: 6px 9px; font: inherit; font-size: 13px; line-height: 1.35;
    color: var(--text); background: var(--bg-input);
    border: 1px solid var(--border); border-radius: 7px;
}
.plk-f textarea { height: auto; min-height: 58px; resize: vertical; }
.plk-f input:focus, .plk-f select:focus, .plk-f textarea:focus {
    outline: none; border-color: var(--primary); box-shadow: 0 0 0 2px var(--accent-soft);
}
.plk-f input::placeholder, .plk-f textarea::placeholder { color: var(--text-muted); }
.plk-f-row { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; min-width: 0; }
.plk-f-row > * { min-width: 0; }
.plk-check {
    display: inline-flex; align-items: center; gap: 8px;
    font-size: 13px; color: var(--text); cursor: pointer;
}
.plk-check input { width: 16px; height: 16px; accent-color: var(--primary); }

/* ── 8. ACTION (.plk-btn) ──
   Rectangle arrondi, hiérarchie par le remplissage : `is-primary` = l'action
   attendue, une seule par écran ; nu = alternative ; `is-danger` = un lien
   rouge souligné, tenu à l'écart des autres. */
.plk-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    min-height: 32px; padding: 6px 15px; border-radius: 8px;
    font-family: inherit; font-size: 12.5px; font-weight: 600; line-height: 1.35;
    white-space: nowrap; text-decoration: none; cursor: pointer;
    color: var(--text); background: var(--bg-input); border: 1px solid var(--border);
    transition: background .13s, border-color .13s, color .13s;
}
.plk-btn:hover { background: var(--bg-hover); }
.plk-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.plk-btn:disabled, .plk-btn[aria-disabled="true"] { opacity: .5; cursor: default; }
.plk-btn.is-primary {
    background: var(--primary); border-color: var(--primary); color: var(--primary-ink);
}
.plk-btn.is-primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); }
.plk-btn.is-danger {
    padding-left: 6px; padding-right: 6px; background: none; border-color: transparent;
    color: var(--role-danger-ink); text-decoration: underline;
}
.plk-btn.is-danger:hover { background: none; color: var(--error); }
.plk-btn.is-sm { min-height: 26px; padding: 3px 10px; font-size: 11.5px; }
/* Une action nommée par son seul symbole : carrée, pour rendre la largeur au
   reste de la barre. Le nom vit dans `title` et `aria-label`. */
.plk-btn.is-icone { width: 32px; padding-left: 0; padding-right: 0; gap: 0; font-size: 15px; }
.plk-btn.is-danger.is-icone { width: 32px; text-decoration: none; }
/* Détruire et enregistrer ne se touchent pas : un cran d'écart contre le clic
   de travers, maintenant que ni l'un ni l'autre ne porte son mot. */
.plk-bar-end > .plk-btn.is-danger.is-icone { margin-right: var(--sp-2); }

/* ── 9. BARRE D'ACTIONS ANCRÉE (.plk-bar) ──
   Filet supérieur à l'accent : la barre se signale sans se répéter. Elle reste
   au bas de l'écran pendant tout le défilement, donc le primaire — poussé à
   droite par `.plk-bar-end` — habite toujours le même pixel. */
.plk-bar {
    position: sticky; bottom: 0; z-index: 100;
    display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2); row-gap: 6px;
    padding: 8px 14px; padding-bottom: max(8px, env(safe-area-inset-bottom));
    background: var(--bg-card); border-top: 2px solid var(--primary);
}
.plk-bar-end { margin-left: auto; display: flex; align-items: center; gap: var(--sp-2); }
/* La barre couvre le bas de la fenêtre : tout défilement décidé par le
   navigateur — focus au clavier, ancre, `scrollIntoView` — doit s'arrêter
   au-dessus d'elle, sinon il y parque le champ qu'il était censé montrer.
   C'est le socle qu'il faut dégager, pas la seule hauteur : en bout de course
   la barre s'est décollée du bas du blanc gardé sous elle. */
html { scroll-padding-bottom: var(--plk-bar-socle); }

/* ── 10. RANGÉES ZÉBRÉES (.plk-zebra) ──
   Une liste de lignes à comparer, pas une pile de cartes : un seul cadre, des
   rangées alternées, et les colonnes chiffrées alignées à droite. */
.plk-zebra {
    display: flex; flex-direction: column; gap: 0;
    border: 1px solid var(--border); border-radius: 10px; overflow: hidden;
}
.plk-zebra > * { background: var(--bg-card); border-bottom: 1px solid var(--hair); }
.plk-zebra > *:nth-child(even) { background: color-mix(in srgb, var(--text) 4%, var(--bg-card)); }
.plk-zebra > *:last-child { border-bottom: none; }

/* ── 11. BANDEAU « CE GESTE SE FAIT AILLEURS » (.plk-demenage) ──
   En tête d'une page qui a cédé une partie de son travail : il nomme ce qui
   est parti, où, et ce qui reste ici. Discret — il informe, il n'alerte pas. */
.plk-demenage {
    display: flex; flex-direction: column; gap: 3px;
    background: var(--bg-card); border: 1px solid var(--border);
    border-left: 3px solid var(--primary); border-radius: 10px;
    padding: 9px 14px; margin: 0 0 14px;
    font-size: 12.5px; line-height: 1.45; color: var(--text-muted);
}
.plk-demenage p { margin: 0; }
.plk-demenage b { color: var(--text); font-weight: 650; }
.plk-demenage a { color: var(--primary); font-weight: 650; text-decoration: none; }
.plk-demenage a:hover { text-decoration: underline; }

/* Sur ordinateur, la barre du haut n'a plus de contenu propre : la marque est
   dans « Aujourd'hui », le reste au pied de la nav. Elle survit sous 1024 px,
   où son hamburger reste l'unique accès à la barre latérale. */
@media (min-width: 1024px) {
    .topbar { display: none; }
    .admin-main { padding-top: 14px; }
}
/* Permanent safety boundary for the local, frozen-data review environment. */
.preproduction-banner {
  position: sticky;
  top: 0;
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: .45rem 1rem;
  min-height: 42px;
  box-sizing: border-box;
  padding: .55rem 1rem;
  border-bottom: 1px solid #d69a26;
  background: #fff0cf;
  color: #633900;
  font-size: .82rem;
  font-weight: 650;
  line-height: 1.25;
}
.preproduction-banner__label {
  padding: .2rem .55rem;
  border-radius: 999px;
  background: #633900;
  color: #fff8ea;
  font-size: .72rem;
  font-weight: 850;
  letter-spacing: .06em;
}
.preproduction-banner__safety { font-weight: 800; }
@media (max-width: 560px) {
  .preproduction-banner { justify-content: flex-start; gap: .35rem .55rem; }
  .preproduction-banner__safety { flex-basis: 100%; }
}
