/* =============================================================================
   LVSTORE — Design system (refonte v1)
   Pro & sobre, type SaaS. Thème clair + sombre via [data-theme].
   Orange #F2A435 en signature. Mêmes noms de classes que l'existant.
   ============================================================================= */

/* ----------------------------------------------------------------------------
   1. TOKENS
   ---------------------------------------------------------------------------- */
:root {
    /* Couleur signature */
    --brand:        #F2A435;
    --brand-600:    #e08f1e;
    --brand-700:    #b9750f;
    --brand-soft:   #fdedd6;
    --brand-contrast: #2a2113;

    /* Accents fonctionnels */
    --blue:   #2563eb;
    --green:  #16a34a;
    --red:    #dc2626;
    --amber:  #d97706;
    --grey:   #64748b;

    /* Neutres (clair) */
    --bg:           #f6f7f9;   /* fond appli */
    --surface:      #ffffff;   /* cartes, panneaux */
    --surface-2:    #f1f3f5;   /* zones secondaires */
    --border:       #e2e6ea;
    --border-strong:#cdd4da;
    --text:         #1f2733;
    --text-soft:    #5a6573;
    --text-faint:   #8a94a2;

    /* Sidebar (sombre même en thème clair, signature SaaS) */
    --side-bg:      #1d2330;
    --side-bg-2:    #232a3a;
    --side-text:    #c3cad6;
    --side-text-faint: #8b95a7;
    --side-active:  var(--brand);
    --side-active-bg: rgba(242,164,53,0.14);

    /* Typo */
    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --fs-xs: .75rem;
    --fs-sm: .85rem;
    --fs-base: .95rem;
    --fs-lg: 1.1rem;
    --fs-xl: 1.4rem;

    /* Rayons */
    --r-sm: 6px;
    --r:    10px;
    --r-lg: 14px;
    --r-full: 999px;

    /* Ombres */
    --shadow-sm: 0 1px 2px rgba(16,24,40,.06), 0 1px 3px rgba(16,24,40,.08);
    --shadow:    0 2px 8px rgba(16,24,40,.08), 0 1px 3px rgba(16,24,40,.06);
    --shadow-lg: 0 12px 32px rgba(16,24,40,.16);

    /* Espacements (rythme 4/8) */
    --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
    --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; --sp-10: 40px;

    /* Layout */
    --side-w: 248px;
    --topbar-h: 60px;

    --trans: 150ms ease;
}

[data-theme="dark"] {
    --bg:           #0f1420;
    --surface:      #171d2b;
    --surface-2:    #1e2536;
    --border:       #2a3346;
    --border-strong:#3a4459;
    --text:         #e7ebf2;
    --text-soft:    #a3adbd;
    --text-faint:   #6f7b8d;

    --side-bg:      #11151f;
    --side-bg-2:    #171d2b;
    --side-text:    #c3cad6;
    --side-text-faint: #79839a;

    --brand-soft:   rgba(242,164,53,0.16);
    --brand-contrast: #1a1408;

    --shadow-sm: 0 1px 2px rgba(0,0,0,.4);
    --shadow:    0 2px 10px rgba(0,0,0,.45);
    --shadow-lg: 0 14px 40px rgba(0,0,0,.6);
}

/* ----------------------------------------------------------------------------
   2. RESET / BASE
   ---------------------------------------------------------------------------- */
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
    margin: 0;
    font-family: var(--font);
    font-size: var(--fs-base);
    line-height: 1.55;
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
}
a { color: var(--blue); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3, h4 { color: var(--text); line-height: 1.25; }
img { max-width: 100%; }

::selection { background: var(--brand-soft); }

*:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
    border-radius: 4px;
}

/* ----------------------------------------------------------------------------
   3. LAYOUT (sidebar + contenu)
   ---------------------------------------------------------------------------- */
.app-shell {
    display: grid;
    grid-template-columns: var(--side-w) 1fr;
    min-height: 100vh;
}

/* --- Sidebar --- */
.app-side {
    background: var(--side-bg);
    color: var(--side-text);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
}
.side-brand {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-5) var(--sp-5) var(--sp-4);
}
.side-brand img { height: 38px; object-fit: contain; }
.side-brand .side-env {
    font-size: var(--fs-xs);
    font-weight: 700;
    padding: 2px 7px;
    border-radius: var(--r-full);
    background: var(--brand);
    color: var(--brand-contrast);
}
.side-nav { list-style: none; margin: 0; padding: var(--sp-2) var(--sp-3); flex: 1; }
.side-nav li { margin: 2px 0; }
.side-nav a {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: 10px 12px;
    border-radius: var(--r-sm);
    color: var(--side-text);
    font-size: var(--fs-sm);
    font-weight: 500;
    text-decoration: none;
    transition: background var(--trans), color var(--trans);
}
.side-nav a:hover { background: var(--side-bg-2); color: #fff; text-decoration: none; }
.side-nav a.active {
    background: var(--side-active-bg);
    color: #fff;
    box-shadow: inset 3px 0 0 var(--side-active);
}
.side-nav a .ico { flex: none; opacity: .9; display: inline-flex; }
.side-section {
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--side-text-faint);
    padding: var(--sp-4) var(--sp-3) var(--sp-1);
    font-weight: 700;
}
.side-foot {
    border-top: 1px solid rgba(255,255,255,.07);
    padding: var(--sp-3);
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.side-foot a {
    color: var(--side-text);
    font-size: var(--fs-sm);
    padding: 7px 12px;
    border-radius: var(--r-sm);
    display: flex;
    align-items: center;
    gap: var(--sp-2);
}
.side-foot a:hover { background: var(--side-bg-2); color: #fff; text-decoration: none; }
.side-foot .side-user { color: var(--side-text-faint); font-size: var(--fs-xs); padding: 4px 12px; }

/* --- Zone principale --- */
.app-main { display: flex; flex-direction: column; min-width: 0; }

.app-topbar {
    height: var(--topbar-h);
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: 0 var(--sp-6);
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    z-index: 20;
}
.topbar-title { font-size: var(--fs-lg); font-weight: 700; margin: 0; }
.topbar-spacer { flex: 1; }

.app-content { padding: var(--sp-6); max-width: 1280px; width: 100%; margin: 0 auto; }

/* bouton scan dans la topbar */
.nav-scan-btn {
    display: inline-flex; align-items: center; gap: 6px;
    background: var(--brand); color: var(--brand-contrast);
    padding: 8px 14px; border-radius: var(--r-sm);
    font-weight: 600; font-size: var(--fs-sm); text-decoration: none;
    transition: background var(--trans);
}
.nav-scan-btn:hover { background: var(--brand-600); text-decoration: none; }

/* bascule thème */
.theme-toggle {
    width: 40px; height: 40px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text-soft);
    border-radius: var(--r-sm);
    cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    transition: background var(--trans), color var(--trans);
}
.theme-toggle:hover { background: var(--surface-2); color: var(--text); }

/* hamburger (mobile) */
.menu-toggle {
    display: none;
    width: 40px; height: 40px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    border-radius: var(--r-sm);
    font-size: 1.2rem; cursor: pointer;
}
.side-backdrop { display: none; }

/* ----------------------------------------------------------------------------
   4. COMPOSANTS
   ---------------------------------------------------------------------------- */

/* --- Cartes --- */
.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: var(--sp-5);
    box-shadow: var(--shadow-sm);
    margin-bottom: var(--sp-5);
}

/* --- Titres de page --- */
.page-title {
    font-size: var(--fs-xl);
    font-weight: 700;
    margin: 0 0 var(--sp-5);
    letter-spacing: -.01em;
}

/* --- Grilles utilitaires --- */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-4); }

/* --- Boutons --- */
.btn, .btn-ico {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 10px 16px;
    border: 1px solid transparent;
    border-radius: var(--r-sm);
    font-family: inherit;
    font-size: var(--fs-sm);
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    text-decoration: none;
    transition: background var(--trans), border-color var(--trans), transform var(--trans), opacity var(--trans);
    white-space: nowrap;
}
.btn:hover, .btn-ico:hover { text-decoration: none; transform: translateY(-1px); }
.btn:active, .btn-ico:active { transform: translateY(0); }
.btn:disabled, .btn[disabled] { opacity: .5; cursor: not-allowed; transform: none; }

.btn-sm { padding: 6px 11px; font-size: var(--fs-xs); }
.btn-block { width: 100%; }

/* Variante par défaut : neutre (contour) */
.btn {
    background: var(--surface);
    color: var(--text);
    border-color: var(--border-strong);
}
.btn:hover { background: var(--surface-2); }

.btn-orange  { background: var(--brand);  color: var(--brand-contrast); border-color: var(--brand); }
.btn-orange:hover  { background: var(--brand-600); }
.btn-blue    { background: var(--blue);   color: #fff; border-color: var(--blue); }
.btn-blue:hover { background: #1d4ed8; }
.btn-green   { background: var(--green);  color: #fff; border-color: var(--green); }
.btn-green:hover { background: #15803d; }
.btn-red, .btn-danger { background: var(--red); color: #fff; border-color: var(--red); }
.btn-red:hover, .btn-danger:hover { background: #b91c1c; }
.btn-grey    { background: var(--surface-2); color: var(--text-soft); border-color: var(--border-strong); }
.btn-grey:hover { background: var(--border); color: var(--text); }

/* --- Formulaires --- */
.form-group { margin-bottom: var(--sp-4); }
.form-group label {
    display: block;
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--text-soft);
    margin-bottom: 6px;
}
.form-group input,
.form-group select,
.form-group textarea,
input[type="text"], input[type="number"], input[type="date"],
input[type="email"], input[type="password"], input[type="search"],
select, textarea {
    width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--border-strong);
    border-radius: var(--r-sm);
    background: var(--surface);
    color: var(--text);
    font-family: inherit;
    font-size: var(--fs-sm);
    transition: border-color var(--trans), box-shadow var(--trans);
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus,
input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--brand);
    box-shadow: 0 0 0 3px var(--brand-soft);
}
.form-group input[readonly], input[readonly] { background: var(--surface-2); color: var(--text-soft); }
.form-group small { color: var(--text-faint); font-size: var(--fs-xs); }

/* --- Tableaux --- */
table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-sm);
    background: var(--surface);
    border-radius: var(--r);
    overflow: hidden;
}
table th {
    text-align: left;
    padding: 11px 14px;
    background: var(--surface-2);
    color: var(--text-soft);
    font-weight: 700;
    font-size: var(--fs-xs);
    text-transform: uppercase;
    letter-spacing: .03em;
    border-bottom: 1px solid var(--border);
}
table td {
    padding: 11px 14px;
    border-bottom: 1px solid var(--border);
    color: var(--text);
}
table tbody tr:last-child td { border-bottom: none; }
table tbody tr { transition: background var(--trans); }
table tbody tr:hover { background: var(--brand-soft); }
table tfoot td { font-weight: 700; background: var(--surface-2); }
.table-compact th, .table-compact td { padding: 7px 10px; }

/* --- Badges --- */
.badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 10px;
    border-radius: var(--r-full);
    font-size: var(--fs-xs);
    font-weight: 600;
    line-height: 1.4;
}
.badge-inactif, .badge-brouillon { background: var(--surface-2); color: var(--text-soft); }
.badge-envoye, .badge-envoyé     { background: #dbeafe; color: #1e40af; }
.badge-decoupe                   { background: var(--brand-soft); color: var(--brand-700); }
.badge-actif, .badge-accepte, .badge-accepté, .badge-admin, .badge-realise { background: #dcfce7; color: #166534; }
.badge-refuse, .badge-refusé     { background: #fee2e2; color: #991b1b; }
.badge-user                      { background: var(--surface-2); color: var(--text-soft); }
.badge-nonrealise                { background: #fef3c7; color: #92400e; }

[data-theme="dark"] .badge-envoye, [data-theme="dark"] .badge-envoyé { background: rgba(37,99,235,.22); color: #93c5fd; }
[data-theme="dark"] .badge-actif, [data-theme="dark"] .badge-accepte,
[data-theme="dark"] .badge-accepté, [data-theme="dark"] .badge-admin,
[data-theme="dark"] .badge-realise { background: rgba(22,163,74,.22); color: #86efac; }
[data-theme="dark"] .badge-refuse, [data-theme="dark"] .badge-refusé { background: rgba(220,38,38,.22); color: #fca5a5; }
[data-theme="dark"] .badge-nonrealise { background: rgba(217,119,6,.22); color: #fcd34d; }

/* --- Alertes --- */
.alert {
    padding: 12px 16px;
    border-radius: var(--r);
    margin-bottom: var(--sp-4);
    font-size: var(--fs-sm);
    border: 1px solid transparent;
}
.alert-success { background: #dcfce7; color: #166534; border-color: #bbf7d0; }
.alert-danger, .alert-error { background: #fee2e2; color: #991b1b; border-color: #fecaca; }
.alert-warning { background: #fef3c7; color: #92400e; border-color: #fde68a; }
.alert-info    { background: #dbeafe; color: #1e40af; border-color: #bfdbfe; }
[data-theme="dark"] .alert-success { background: rgba(22,163,74,.16); color: #86efac; border-color: rgba(22,163,74,.3); }
[data-theme="dark"] .alert-danger, [data-theme="dark"] .alert-error { background: rgba(220,38,38,.16); color: #fca5a5; border-color: rgba(220,38,38,.3); }
[data-theme="dark"] .alert-warning { background: rgba(217,119,6,.16); color: #fcd34d; border-color: rgba(217,119,6,.3); }
[data-theme="dark"] .alert-info { background: rgba(37,99,235,.16); color: #93c5fd; border-color: rgba(37,99,235,.3); }

/* --- Modals --- */
.modal-overlay {
    position: fixed; inset: 0;
    background: rgba(15,20,32,.55);
    display: flex; align-items: center; justify-content: center;
    z-index: 100; padding: var(--sp-4);
}
.modal-box {
    background: var(--surface);
    border-radius: var(--r-lg);
    box-shadow: var(--shadow-lg);
    width: 100%; max-width: 520px;
    max-height: 90vh; overflow-y: auto;
    border: 1px solid var(--border);
}
.modal-header {
    display: flex; align-items: center; justify-content: space-between;
    padding: var(--sp-4) var(--sp-5);
    border-bottom: 1px solid var(--border);
}
.modal-header h2 { font-size: var(--fs-lg); margin: 0; }
.modal-body { padding: var(--sp-5); }
.modal-close {
    background: none; border: none; cursor: pointer;
    color: var(--text-faint); display: inline-flex; padding: 4px; border-radius: var(--r-sm);
}
.modal-close:hover { background: var(--surface-2); color: var(--text); }

/* --- Pagination --- */
.pagination { display: flex; gap: 6px; justify-content: center; flex-wrap: wrap; margin-top: var(--sp-5); }
.pg-item {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 36px; height: 36px; padding: 0 10px;
    border: 1px solid var(--border-strong); border-radius: var(--r-sm);
    background: var(--surface); color: var(--text); font-size: var(--fs-sm);
    text-decoration: none; transition: background var(--trans);
}
.pg-item:hover { background: var(--surface-2); text-decoration: none; }
.pg-item.active { background: var(--brand); color: var(--brand-contrast); border-color: var(--brand); font-weight: 700; }
.pg-item.disabled { opacity: .45; pointer-events: none; }

/* --- Statut inline (badge cliquable avec select) --- */
.statut-badge-select { position: relative; display: inline-flex; align-items: center; padding-right: 4px; cursor: pointer; }
.statut-badge-select select {
    appearance: none; -webkit-appearance: none;
    background: transparent; border: none; color: inherit;
    font: inherit; font-weight: 600; font-size: var(--fs-xs);
    padding: 0 18px 0 2px; cursor: pointer; width: auto;
}
.statut-badge-select select:focus { outline: none; box-shadow: none; }
.statut-badge-select::after {
    content: ""; position: absolute; right: 6px; top: 50%;
    width: 6px; height: 6px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
    transform: translateY(-65%) rotate(45deg); pointer-events: none; opacity: .7;
}
.statut-inline-form { margin: 0; }

/* --- Login --- */
.login-logo { text-align: center; margin-bottom: var(--sp-5); }
.login-box {
    max-width: 400px; margin: 8vh auto; background: var(--surface);
    border: 1px solid var(--border); border-radius: var(--r-lg);
    padding: var(--sp-8); box-shadow: var(--shadow);
}
.login-box p.subtitle { color: var(--text-soft); text-align: center; margin-top: -8px; }

/* --- Liens PDF, divers --- */
.odf-pdf-link { display: inline-flex; align-items: center; gap: 6px; color: var(--red); font-size: var(--fs-sm); font-weight: 600; }

/* --- Helpers --- */
.text-soft { color: var(--text-soft); }
.text-faint { color: var(--text-faint); }
.error { color: var(--red); font-size: var(--fs-sm); }

/* ----------------------------------------------------------------------------
   5. RESPONSIVE
   ---------------------------------------------------------------------------- */
@media (max-width: 900px) {
    .app-shell { grid-template-columns: 1fr; }
    .app-side {
        position: fixed; top: 0; left: 0; bottom: 0;
        width: 82%; max-width: 300px; z-index: 60;
        transform: translateX(-100%); transition: transform 220ms ease;
    }
    .app-shell.nav-open .app-side { transform: translateX(0); }
    .app-shell.nav-open .side-backdrop {
        display: block; position: fixed; inset: 0;
        background: rgba(0,0,0,.5); z-index: 50;
    }
    .menu-toggle { display: inline-flex; align-items: center; justify-content: center; }
    .app-content { padding: var(--sp-4); }
    .grid-2, .grid-3 { grid-template-columns: 1fr; }

    /* Tables -> cartes empilées */
    table thead { display: none; }
    table, table tbody, table tr, table td { display: block; width: 100%; }
    table tr {
        border: 1px solid var(--border); border-radius: var(--r);
        margin-bottom: var(--sp-3); padding: var(--sp-2); background: var(--surface);
    }
    table td { border: none; padding: 7px 10px; display: flex; justify-content: space-between; gap: var(--sp-3); }
    table td::before {
        content: attr(data-label);
        font-weight: 700; color: var(--text-soft); font-size: var(--fs-xs);
        text-transform: uppercase; letter-spacing: .03em;
    }
    table tbody tr:hover { background: var(--surface); }
}

@media (min-width: 901px) {
    .menu-toggle { display: none; }
}

/* ----------------------------------------------------------------------------
   6. IMPRESSION
   ---------------------------------------------------------------------------- */
@media print {
    .app-side, .app-topbar, .no-print { display: none !important; }
    .app-shell { display: block; }
    .app-content { padding: 0; max-width: none; }
    .card { box-shadow: none; border: 1px solid #ddd; }
    body { background: #fff; }
}
/* =============================================================================
   LVSTORE — Refonte v2 : tableau de bord + ordres
   (à concaténer une seule fois à styles.css)
   ============================================================================= */

/* --- KPI du tableau de bord --- */
.kpi-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: var(--sp-4);
    margin-bottom: var(--sp-6);
}
.kpi-card {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: var(--sp-4) var(--sp-5);
    box-shadow: var(--shadow-sm);
}
.kpi-ico {
    width: 44px; height: 44px;
    border-radius: var(--r);
    display: flex; align-items: center; justify-content: center;
    flex: none;
}
.kpi-val { font-size: 1.6rem; font-weight: 800; line-height: 1; letter-spacing: -.02em; }
.kpi-label { font-size: var(--fs-sm); color: var(--text-soft); margin-top: 3px; }

.kpi-brand .kpi-ico { background: var(--brand-soft);  color: var(--brand-700); }
.kpi-amber .kpi-ico { background: #fef3c7; color: #92400e; }
.kpi-blue  .kpi-ico { background: #dbeafe; color: #1e40af; }
.kpi-green .kpi-ico { background: #dcfce7; color: #166534; }
.kpi-slate .kpi-ico { background: var(--surface-2); color: var(--text-soft); }
[data-theme="dark"] .kpi-amber .kpi-ico { background: rgba(217,119,6,.2); color: #fcd34d; }
[data-theme="dark"] .kpi-blue  .kpi-ico { background: rgba(37,99,235,.2); color: #93c5fd; }
[data-theme="dark"] .kpi-green .kpi-ico { background: rgba(22,163,74,.2); color: #86efac; }

/* --- Barre de filtres (liste ordres) --- */
.filters-bar {
    display: flex;
    align-items: flex-end;
    gap: var(--sp-3);
    flex-wrap: wrap;
    margin-bottom: var(--sp-5);
}
.filters-bar .form-group { margin: 0; min-width: 160px; }
.filters-bar .grow { flex: 1; min-width: 220px; }

/* --- En-tête de page avec action --- */
.page-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--sp-3); flex-wrap: wrap; margin-bottom: var(--sp-5);
}
.page-head .page-title { margin: 0; }

/* --- Détail ordre : en-tête en 4 colonnes --- */
.odf-head-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--sp-3);
}
@media (max-width: 720px) {
    .odf-head-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 460px) {
    .odf-head-grid { grid-template-columns: 1fr; }
}

/* Ligne d'actions du détail ordre */
.odf-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; align-items: center; margin-top: var(--sp-3); }
/* =============================================================================
   LVSTORE — Refonte v4
   Sidebar orange (signature) + découpe flottante + finitions paramètres/auth.
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

/* ----------------------------------------------------------------------------
   1. SIDEBAR EN ORANGE (override des variables --side-*)
   L'orange #F2A435 est clair : on utilise un texte foncé pour le contraste.
   ---------------------------------------------------------------------------- */
:root {
    --side-bg:         #F2A435;            /* fond orange signature */
    --side-bg-2:       #e2901f;            /* hover : orange un peu plus soutenu */
    --side-text:       #3a2c12;            /* texte foncé lisible sur orange */
    --side-text-faint: #7a5e22;            /* texte secondaire */
    --side-active:     #3a2c12;            /* liseré actif foncé */
    --side-active-bg:  rgba(255,255,255,.35); /* fond actif : voile blanc */
}
[data-theme="dark"] {
    /* En sombre, on garde l'orange mais un peu plus profond pour ménager les yeux */
    --side-bg:         #d98e1e;
    --side-bg-2:       #c47d12;
    --side-text:       #2a2008;
    --side-text-faint: #5c4715;
    --side-active:     #2a2008;
    --side-active-bg:  rgba(255,255,255,.30);
}

/* Le texte/hover/actif passent en foncé (les règles du CSS de base utilisaient #fff) */
.side-nav a:hover { color: #1f1707 !important; }
.side-nav a.active { color: #1f1707 !important; font-weight: 700; }
.side-foot a:hover { color: #1f1707 !important; }
.side-foot { border-top-color: rgba(0,0,0,.12); }
.app-side { box-shadow: inset -1px 0 0 rgba(0,0,0,.08); }

/* Le badge "DEV" devient foncé pour ressortir sur l'orange */
.side-brand .side-env { background: #3a2c12; color: #F2A435; }

/* ----------------------------------------------------------------------------
   2. POSTE DE DÉCOUPE — légende latérale flottante (réintégrée)
   (oubliée lors de la refonte du CSS ; on tient compte de la topbar de 60px)
   ---------------------------------------------------------------------------- */
.decoupe-layout {
    display: grid;
    grid-template-columns: 290px 1fr;
    gap: var(--sp-5);
    align-items: start;
}
.decoupe-legende {
    position: sticky;
    top: calc(var(--topbar-h) + var(--sp-4));
    max-height: calc(100vh - var(--topbar-h) - var(--sp-6));
    overflow-y: auto;
}
.decoupe-plan { min-width: 0; }

@media (max-width: 900px) {
    .decoupe-layout { grid-template-columns: 1fr; }
    .decoupe-legende { position: static; max-height: none; margin-bottom: var(--sp-4); }
}
@media print {
    .decoupe-layout { grid-template-columns: 1fr; }
    .decoupe-legende { position: static; max-height: none; }
}

/* ----------------------------------------------------------------------------
   3. PARAMÈTRES — sous-navigation latérale
   ---------------------------------------------------------------------------- */
.settings-layout {
    display: grid;
    grid-template-columns: 240px 1fr;
    gap: var(--sp-5);
    align-items: start;
}
.settings-nav {
    display: flex;
    flex-direction: column;
    gap: 2px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: var(--sp-2);
    box-shadow: var(--shadow-sm);
    position: sticky;
    top: calc(var(--topbar-h) + var(--sp-4));
}
.settings-nav a {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: 9px 12px;
    border-radius: var(--r-sm);
    color: var(--text-soft);
    font-size: var(--fs-sm);
    font-weight: 500;
    text-decoration: none;
    transition: background var(--trans), color var(--trans);
}
.settings-nav a:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.settings-nav a.active {
    background: var(--brand-soft);
    color: var(--brand-700);
    font-weight: 700;
}
.settings-content { min-width: 0; }
@media (max-width: 820px) {
    .settings-layout { grid-template-columns: 1fr; }
    .settings-nav { position: static; flex-direction: row; flex-wrap: wrap; }
}

/* Cartes cliquables du hub paramètres */
.settings-hub {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: var(--sp-4);
}
.settings-hub-card {
    display: flex;
    gap: var(--sp-3);
    align-items: flex-start;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: var(--sp-5);
    box-shadow: var(--shadow-sm);
    text-decoration: none;
    color: var(--text);
    transition: border-color var(--trans), transform var(--trans), box-shadow var(--trans);
}
.settings-hub-card:hover {
    border-color: var(--brand);
    transform: translateY(-2px);
    box-shadow: var(--shadow);
    text-decoration: none;
}
.settings-hub-card .ico {
    width: 40px; height: 40px; flex: none;
    border-radius: var(--r);
    background: var(--brand-soft); color: var(--brand-700);
    display: flex; align-items: center; justify-content: center;
}
.settings-hub-card h3 { margin: 0 0 3px; font-size: var(--fs-base); }
.settings-hub-card p { margin: 0; font-size: var(--fs-sm); color: var(--text-soft); }

/* ----------------------------------------------------------------------------
   4. CONNEXION / 2FA
   ---------------------------------------------------------------------------- */
.auth-wrap {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--sp-5);
    background:
        radial-gradient(1200px 600px at 50% -10%, var(--brand-soft), transparent 60%),
        var(--bg);
}
.auth-card {
    width: 100%;
    max-width: 400px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: var(--sp-8);
    box-shadow: var(--shadow-lg);
}
.auth-logo { text-align: center; margin-bottom: var(--sp-5); }
.auth-logo img { height: 56px; object-fit: contain; }
.auth-card h1 { font-size: var(--fs-xl); text-align: center; margin: 0 0 var(--sp-2); }
.auth-card .subtitle { color: var(--text-soft); text-align: center; margin: 0 0 var(--sp-6); font-size: var(--fs-sm); }

/* ----------------------------------------------------------------------------
   5. LISTE ORDRES — barre d'outils (actions à gauche, recherche à droite)
   ---------------------------------------------------------------------------- */
.odf-toolbar {
    display: flex;
    align-items: center;
    gap: var(--sp-4);
    flex-wrap: wrap;
}
.odf-toolbar-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.odf-toolbar-search {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    margin-left: auto;       /* pousse la recherche à droite */
    flex-wrap: wrap;
}
.odf-toolbar-search input[type="text"] { width: 260px; max-width: 100%; }
.odf-toolbar-search select { width: auto; }
.odf-toolbar-search .btn { padding: 9px 12px; }

@media (max-width: 760px) {
    .odf-toolbar-search { margin-left: 0; width: 100%; }
    .odf-toolbar-search input[type="text"] { flex: 1; width: auto; }
}
/* =============================================================================
   LVSTORE — Refonte v5 : corrections
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

/* ----------------------------------------------------------------------------
   1. SIDEBAR — sombre en thème sombre (override de l'orange du v4)
   En clair : orange signature. En sombre : ardoise foncée, plus reposante.
   ---------------------------------------------------------------------------- */
[data-theme="dark"] {
    --side-bg:         #11151f;
    --side-bg-2:       #1b2230;
    --side-text:       #c3cad6;
    --side-text-faint: #79839a;
    --side-active:     var(--brand);
    --side-active-bg:  rgba(242,164,53,0.16);
}
/* En sombre, le texte/hover/actif redeviennent clairs (le v4 les forçait en foncé) */
[data-theme="dark"] .side-nav a:hover { color: #fff !important; }
[data-theme="dark"] .side-nav a.active { color: #fff !important; }
[data-theme="dark"] .side-foot a:hover { color: #fff !important; }
[data-theme="dark"] .side-brand .side-env { background: var(--brand); color: var(--brand-contrast); }

/* ----------------------------------------------------------------------------
   2. CHAMP QUANTITÉ D'ÉTIQUETTES — badge compact à droite (ne prend plus toute la largeur)
   ---------------------------------------------------------------------------- */
.label-qty-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex: none;
    background: var(--brand-soft);
    color: var(--brand-700);
    border: 1px solid var(--brand);
    border-radius: var(--r-full);
    padding: 4px 12px;
    font-size: var(--fs-sm);
    font-weight: 600;
    white-space: nowrap;
}
.label-qty-badge input.ligne-qte {
    width: 46px;          /* compact, ne s'étire pas */
    flex: none;
    padding: 3px 6px;
    border: 1px solid var(--brand);
    border-radius: var(--r-sm);
    background: var(--surface);
    color: var(--text);
    font-size: var(--fs-sm);
    font-weight: 700;
    text-align: center;
}
.label-qty-badge input.ligne-qte:focus {
    outline: none;
    box-shadow: 0 0 0 3px var(--brand-soft);
}

/* ----------------------------------------------------------------------------
   3. SIDEBAR EN MODE "RAIL" (desktop) : réduite en icônes, s'ouvre au survol
   ---------------------------------------------------------------------------- */
@media (min-width: 901px) {
    /* La grille réserve la largeur du rail réduit ; l'ouverture se fait en overlay
       pour ne pas décaler le contenu. */
    .app-shell.rail { grid-template-columns: var(--rail-w, 64px) 1fr; }

    .app-shell.rail .app-side {
        width: var(--rail-w, 64px);
        overflow: hidden;
        transition: width 180ms ease;
        z-index: 40;
    }
    .app-shell.rail.rail-open .app-side {
        width: var(--side-w);
        box-shadow: var(--shadow-lg);
    }

    /* Libellés masqués en rail, réapparaissent à l'ouverture */
    .app-shell.rail .side-label {
        opacity: 0;
        white-space: nowrap;
        transition: opacity 120ms ease;
        pointer-events: none;
    }
    .app-shell.rail.rail-open .side-label {
        opacity: 1;
        pointer-events: auto;
    }

    /* Icônes centrées en rail */
    .app-shell.rail .side-nav a,
    .app-shell.rail .side-foot a {
        gap: 0;
    }
    .app-shell.rail .side-ico {
        display: inline-flex;
        width: 22px;
        justify-content: center;
        flex: none;
    }
    .app-shell.rail.rail-open .side-nav a,
    .app-shell.rail.rail-open .side-foot a { gap: var(--sp-3); }

    /* En rail fermé : la section "Administration" et le nom d'utilisateur disparaissent */
    .app-shell.rail:not(.rail-open) .side-section { height: 8px; overflow: hidden; }
    .app-shell.rail:not(.rail-open) .side-user { display: none; }

    /* Logo : on réduit un peu pour tenir dans le rail */
    .app-shell.rail:not(.rail-open) .side-brand { padding: var(--sp-4) 0; justify-content: center; }
    .app-shell.rail:not(.rail-open) .side-brand img { height: 30px; }
    .app-shell.rail:not(.rail-open) .side-env { display: none; }
}
/* =============================================================================
   LVSTORE — Patch mobile (lisibilité téléphone)
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

@media (max-width: 900px) {
    /* Les petits tableaux internes (fiche ordre : composants, mesures) NE passent
       PAS en cartes empilées : ils restent compacts, avec défilement horizontal
       si nécessaire. Plus lisible que des cartes pour ces mini-tables. */
    .table-inner, .table-inner thead, .table-inner tbody,
    .table-inner tr, .table-inner td, .table-inner th { display: revert; }
    .table-inner { display: table; width: 100%; }
    .table-inner thead { display: table-header-group; }
    .table-inner tr { display: table-row; border: none; margin: 0; padding: 0; background: transparent; }
    .table-inner td, .table-inner th { display: table-cell; }
    .table-inner td::before { content: none; }

    /* Enveloppe scrollable pour tout tableau interne qui dépasserait */
    .view-composants, .view-mesures { overflow-x: auto; }

    /* QR de la page 2FA : ne pas dépasser la largeur de l'écran */
    .auth-card img[style*="220px"],
    img[alt*="QR"], .qr-2fa img { max-width: 70vw !important; height: auto !important; }

    /* Formulaire de détail d'ordre : ne pas forcer une largeur mini trop grande */
    .odf-head-grid + * [style*="min-width:280px"] { min-width: 0 !important; }
}

/* Très petits écrans : réduit un peu les paddings de cartes pour gagner de la place */
@media (max-width: 420px) {
    .card { padding: var(--sp-4); }
    .page-title { font-size: 1.25rem; }
    .kpi-val { font-size: 1.4rem; }
}
/* =============================================================================
   LVSTORE — Lot UX (mode client, toolbar inversée, divers)
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

/* 1. Mode client : masque tous les prix (éléments marqués .price) */
body.client-mode .price {
    display: none !important;
}

/* 2. Barre d'outils de la liste des ordres :
      recherche à GAUCHE, boutons d'action poussés à DROITE.
      (On annule l'ancien margin-left:auto de la recherche et on le met sur les actions.) */
.odf-toolbar-search { margin-left: 0 !important; }
.odf-toolbar-actions { margin-left: auto; }

@media (max-width: 760px) {
    .odf-toolbar-actions { margin-left: 0; width: 100%; }
    .odf-toolbar-search { width: 100%; }
    .odf-toolbar-search input[type="text"] { flex: 1; width: auto; }
}
/* =============================================================================
   LVSTORE — Lot final : ajustements boutons + hauteurs
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

/* 1. Barre de recherche des ordres : input, select et boutons à la MÊME hauteur.
      On aligne tout sur 40px et on centre verticalement. */
.odf-toolbar-search {
    align-items: stretch;
}
.odf-toolbar-search input[type="text"],
.odf-toolbar-search select,
.odf-toolbar-search .btn {
    height: 40px;
    box-sizing: border-box;
}
.odf-toolbar-search .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding-top: 0;
    padding-bottom: 0;
}

/* 2. Cohérence : les boutons d'action de la toolbar ordres à la même hauteur */
.odf-toolbar-actions .btn { height: 40px; display: inline-flex; align-items: center; justify-content: center; }

/* 3. Le sélecteur de statut coloré dans le détail : garde l'apparence d'un badge */
.statut-badge-select select { cursor: pointer; }
/* =============================================================================
   LVSTORE — Lot fix : bouton Excel, champ quantité étiquettes, cartes mobiles
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

/* 1. Bouton vert "Excel" pour l'import d'articles */
.btn-excel {
    background: #1D6F42;
    color: #fff;
    border: 1px solid #1D6F42;
}
.btn-excel:hover { background: #15592f; border-color: #15592f; color: #fff; }

/* 2. Champ quantité d'étiquettes : alléger (plus de double bordure) et fixer à droite.
      Le conteneur perd sa bordure ; seul l'input garde un trait fin. */
.label-qty-badge {
    border: none !important;
    background: transparent !important;
    padding: 0 !important;
    margin-left: auto;            /* pousse le champ à droite, ligne par ligne */
}
.label-qty-badge input.ligne-qte {
    width: 56px;
    border: 1px solid var(--border) !important;
    border-radius: var(--r-sm);
    padding: 4px 6px;
    font-weight: 600;
}
.label-pick-row { display: flex; align-items: center; gap: 10px; }
.label-pick-main { flex: 1; }
/* Badge "N étiq." de la page d'impression : poussé à droite, allégé */
.label-count-badge { margin-left: auto; }

/* 3. ORDRES sur mobile : le detail d'un volet passe en pile verticale,
      avec un apercu (SVG) reduit pour ne pas deborder l'ecran.
      (Sur PC, la grille 230px + details reste inchangee.) */
@media (max-width: 760px) {
    .volet-card-grid {
        grid-template-columns: 1fr !important;
        gap: 12px !important;
    }
    .volet-svg-wrap {
        max-width: 160px;
        margin: 0 auto;
    }
    .volet-svg-wrap svg {
        max-width: 100% !important;
        height: auto !important;
    }
    .volet-card table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .volet-card, .odf-detail { max-width: 100%; overflow-x: hidden; }
}
/* =============================================================================
   LVSTORE — Lot fix : bouton Excel, champ quantité étiquettes, cartes mobiles
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

/* 1. Bouton vert "Excel" pour l'import d'articles */
.btn-excel {
    background: #1D6F42;
    color: #fff;
    border: 1px solid #1D6F42;
}
.btn-excel:hover { background: #15592f; border-color: #15592f; color: #fff; }

/* 2. Champ quantité d'étiquettes : alléger (plus de double bordure) et fixer à droite.
      Le conteneur perd sa bordure ; seul l'input garde un trait fin. */
.label-qty-badge {
    border: none !important;
    background: transparent !important;
    padding: 0 !important;
    margin-left: auto;            /* pousse le champ à droite, ligne par ligne */
}
.label-qty-badge input.ligne-qte {
    width: 56px;
    border: 1px solid var(--border) !important;
    border-radius: var(--r-sm);
    padding: 4px 6px;
    font-weight: 600;
}
.label-pick-row { display: flex; align-items: center; gap: 10px; }
.label-pick-main { flex: 1; }
/* Badge "N étiq." de la page d'impression : poussé à droite, allégé */
.label-count-badge { margin-left: auto; }

/* 3. ORDRES sur mobile : le detail d'un volet passe en pile verticale,
      avec un apercu (SVG) reduit pour ne pas deborder l'ecran.
      (Sur PC, la grille 230px + details reste inchangee.) */
@media (max-width: 760px) {
    .volet-card-grid {
        grid-template-columns: 1fr !important;
        gap: 12px !important;
    }
    .volet-svg-wrap {
        max-width: 160px;
        margin: 0 auto;
    }
    .volet-svg-wrap svg {
        max-width: 100% !important;
        height: auto !important;
    }
    .volet-card table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .volet-card, .odf-detail { max-width: 100%; overflow-x: hidden; }
}
/* =============================================================================
   LVSTORE — Lot 7 : largeur volets mobile, burger, admin en bas, panier
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

/* 1. APERÇU VOLET trop large sur mobile.
   Correctif clé : min-width:0 permet à la colonne 1fr de rétrécir sous la largeur
   de son contenu (sinon la grille déborde). On réduit aussi le schéma. */
.volet-card-grid { min-width: 0; }
.volet-card-grid > * { min-width: 0; }     /* indispensable pour autoriser le rétrécissement */

@media (max-width: 900px) {
    .volet-card-grid {
        grid-template-columns: 1fr !important;  /* schéma au-dessus, détails dessous */
        gap: 12px !important;
    }
    .volet-card-grid svg {
        max-width: 150px !important;
        width: 100% !important;
        height: auto !important;
    }
    /* Les tableaux internes (composants, mesures) défilent au lieu de déborder */
    .volet-card table { display: block; width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
    .volet-card, .volet-card-grid { max-width: 100%; overflow-x: hidden; }
}

/* 2. BURGER et bouton SCAN à la même hauteur dans la topbar */
.app-topbar .menu-toggle,
.app-topbar .nav-scan-btn {
    height: 40px;
    min-width: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    padding: 0 10px;
}
.app-topbar .menu-toggle { font-size: 1.25rem; line-height: 1; }

/* 3. Bloc ADMINISTRATION déplacé en bas : on le sort du flux nav et on le pose
   juste au-dessus du pied (nom utilisateur). Voir aussi le HTML de main.php. */
.side-admin-bottom { margin-top: auto; }
.side-admin-bottom .side-section { margin-top: 10px; }
/* =============================================================================
   LVSTORE — Lot 8 : burger PC, actions articles, sélecteurs Commandes
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

/* 1. BURGER : ne doit JAMAIS s'afficher sur PC. (Le lot précédent le forçait à
   tort via .app-topbar .menu-toggle sans media query, écrasant le display:none.)
   On masque en desktop, on aligne la hauteur en mobile. */
@media (min-width: 901px) {
    .app-topbar .menu-toggle { display: none !important; }
}
@media (max-width: 900px) {
    .app-topbar .menu-toggle {
        display: inline-flex; align-items: center; justify-content: center;
        height: 40px; min-width: 40px; box-sizing: border-box; padding: 0 10px;
        font-size: 1.25rem; line-height: 1;
    }
    .app-topbar .nav-scan-btn {
        height: 40px; min-width: 40px; box-sizing: border-box;
        display: inline-flex; align-items: center; justify-content: center; padding: 0 10px;
    }
}

/* 2. ARTICLES : les actions (icônes) doivent être alignées verticalement avec la ligne. */
.articles-table td,
table td .actions-cell { vertical-align: middle; }
td[data-label="Actions"] {
    vertical-align: middle !important;
}
td[data-label="Actions"] > a,
td[data-label="Actions"] > form,
td[data-label="Actions"] > button {
    vertical-align: middle;
}

/* 3. COMMANDES : sélecteur de quantité trop gros + "pièce" qui passe à la ligne. */
.cmd-qte-input {
    width: 64px;
    text-align: right;
    padding: 4px 6px;
}
.cmd-qte-unit {
    white-space: nowrap;     /* empêche "pièce" de revenir à la ligne */
    font-size: .75rem;
    color: var(--text-faint);
}
.cmd-qte-cell { white-space: nowrap; }

/* 4. COMMANDES : le sélecteur de statut a une double bordure (badge + select).
   On retire la bordure du select à l'intérieur du badge. */
.statut-badge-select select,
.cmd-statut-badge select {
    border: none !important;
    background: transparent !important;
    outline: none;
    font: inherit;
    color: inherit;
    padding: 0 2px;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}
.cmd-statut-badge { display: inline-flex; align-items: center; }
/* =============================================================================
   LVSTORE — Lot 9 : chevrons statut, largeur input quantité, ajout panier
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

/* 1. CHEVRON du sélecteur de statut.
   Le lot précédent avait retiré le padding-droit du select, si bien que le chevron
   se superposait au texte (ordres) ou disparaissait (commandes).
   On rétablit l'espace à droite + on dessine le chevron pour les deux contextes. */
.statut-badge-select,
.cmd-statut-badge {
    position: relative;
    display: inline-flex;
    align-items: center;
    padding-right: 6px;
}
.statut-badge-select select,
.cmd-statut-badge select {
    border: none !important;
    background: transparent !important;
    outline: none;
    font: inherit;
    color: inherit;
    cursor: pointer;
    width: auto;
    -webkit-appearance: none;
    appearance: none;
    padding: 0 18px 0 2px !important;   /* place pour le chevron à droite */
}
.statut-badge-select select:focus,
.cmd-statut-badge select:focus { outline: none; box-shadow: none; }
.statut-badge-select::after,
.cmd-statut-badge::after {
    content: "";
    position: absolute;
    right: 7px;
    top: 50%;
    width: 6px;
    height: 6px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: translateY(-65%) rotate(45deg);
    pointer-events: none;
    opacity: .7;
}

/* 2. Largeur de l'input quantité : nettement réduite (commandes + stocks). */
.cmd-qte-input,
.stock-cart-form input[type="number"] {
    width: 52px !important;
    text-align: right;
    padding: 4px 6px;
    box-sizing: border-box;
}

/* 3. STOCKS : l'input quantité n'apparaît qu'après clic sur le bouton chariot. */
.stock-cart-form .stock-cart-qty { display: none; }
.stock-cart-form.open .stock-cart-qty { display: inline-block; }
/* =============================================================================
   LVSTORE — Bouton de rafraîchissement sandbox (violet) dans la topbar
   À concaténer UNE SEULE FOIS à styles.css.
   N'apparaît que dans la sandbox (le HTML est conditionné par $isSandbox).
   ============================================================================= */

.nav-sandbox-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: #8e44ad;            /* violet */
    color: #fff;
    padding: 8px 14px;
    border-radius: var(--r-sm);
    font-weight: 600;
    font-size: var(--fs-sm);
    text-decoration: none;
    margin-right: 10px;             /* espace avant le bouton scan, à sa gauche */
    transition: background var(--trans);
}
.nav-sandbox-btn:hover { background: #7d3c98; text-decoration: none; color: #fff; }

/* Bouton violet réutilisé dans la page de confirmation */
.btn-violet { background: #8e44ad; color: #fff; border: 1px solid #8e44ad; }
.btn-violet:hover { background: #7d3c98; border-color: #7d3c98; color: #fff; }
.btn-violet:disabled { opacity: .6; cursor: not-allowed; }
/* =============================================================================
   LVSTORE — Volet d'aperçu PDF (test lecture PDF + détail des ordres)
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

/* --- Page de test : résultats à gauche, PDF à droite --- */
.pdftest-split {
    display: flex;
    gap: 18px;
    align-items: flex-start;
}
.pdftest-results { flex: 1 1 50%; min-width: 0; }
.pdftest-preview { flex: 1 1 50%; min-width: 0; }

.pdftest-preview-inner {
    position: sticky;
    top: 16px;
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    overflow: hidden;
    background: var(--surface-2);
}
.pdftest-preview-label {
    padding: 8px 12px;
    font-weight: 600;
    font-size: var(--fs-sm);
    border-bottom: 1px solid var(--border);
    background: var(--surface);
}
.pdftest-frame {
    width: 100%;
    height: 78vh;
    border: 0;
    display: block;
}

/* Sur petit écran : le PDF passe EN DESSOUS des résultats */
@media (max-width: 900px) {
    .pdftest-split { flex-direction: column; }
    .pdftest-results, .pdftest-preview { flex: 1 1 100%; width: 100%; }
    .pdftest-preview-inner { position: static; }
    .pdftest-frame { height: 60vh; }
}

/* --- Volet latéral PDF pour le détail des ordres --- */
/* Panneau coulissant depuis la droite, ouvert par le bouton "Voir le PDF". */
.odf-pdf-drawer {
    position: fixed;
    top: var(--topbar-h, 60px);
    right: 0;
    width: min(55vw, 1000px);
    height: calc(100vh - var(--topbar-h, 60px));
    background: var(--surface);
    border-left: 1px solid var(--border);
    box-shadow: -8px 0 24px rgba(0,0,0,.18);
    z-index: 1000;
    display: flex;
    flex-direction: column;
    transform: translateX(100%);
    transition: transform .25s ease;
}
.odf-pdf-drawer.open { transform: translateX(0); }
.odf-pdf-drawer-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
    border-bottom: 1px solid var(--border);
    font-weight: 600;
}
.odf-pdf-drawer-close {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 1.4rem;
    line-height: 1;
    color: var(--text-soft);
    padding: 0 4px;
}
.odf-pdf-drawer iframe {
    flex: 1 1 auto;
    width: 100%;
    border: 0;
}
/* Voile sombre derrière le volet */
.odf-pdf-overlay {
    position: fixed;
    top: var(--topbar-h, 60px);
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0,0,0,.35);
    z-index: 999;
    opacity: 0;
    pointer-events: none;
    transition: opacity .25s ease;
}
.odf-pdf-overlay.open { opacity: 1; pointer-events: auto; }

/* Sur petit écran : le volet occupe presque tout l'écran */
@media (max-width: 900px) {
    .odf-pdf-drawer { width: 100vw; }
}
/* =============================================================================
   LVSTORE — Tableau de bord : statistiques de production
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

/* --- Compteurs principaux (KPI) --- */
.stats-kpis {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 14px;
    margin-bottom: 18px;
}
.stats-kpi { text-align: center; padding: 18px 14px; }
.stats-kpi-value {
    font-size: 2rem;
    font-weight: 700;
    color: var(--brand);
    line-height: 1.1;
}
.stats-kpi-label {
    margin-top: 6px;
    color: var(--text-soft);
    font-size: var(--fs-sm);
}

/* --- Cartes de stats --- */
.stats-card { margin-bottom: 18px; }
.stats-card-title {
    margin: 0 0 14px;
    font-size: 1rem;
    color: var(--text);
}
.stats-empty, .stats-hint {
    color: var(--text-faint);
    font-size: var(--fs-sm);
    margin: 4px 0 0;
}
.stats-hint { margin-top: 10px; }

/* --- Grille des répartitions (2 colonnes sur PC) --- */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
}

/* --- Barres horizontales de répartition --- */
.stats-bars { display: flex; flex-direction: column; gap: 9px; }
.stats-bar-row {
    display: grid;
    grid-template-columns: 130px 1fr 42px;
    align-items: center;
    gap: 10px;
}
.stats-bar-label {
    font-size: var(--fs-sm);
    color: var(--text-soft);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.stats-bar-track {
    background: var(--surface-2);
    border-radius: var(--r-sm);
    height: 16px;
    overflow: hidden;
}
.stats-bar-fill {
    display: block;
    height: 100%;
    background: var(--brand);
    border-radius: var(--r-sm);
    min-width: 2px;
    transition: width .4s ease;
}
.stats-bar-value {
    font-size: var(--fs-sm);
    font-weight: 600;
    text-align: right;
    color: var(--text);
}

/* --- Graphique mensuel (colonnes verticales) --- */
.stats-month-chart {
    display: flex;
    align-items: flex-end;
    gap: 6px;
    height: 200px;
    padding-top: 10px;
}
.stats-month-col {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    height: 100%;
    min-width: 0;
}
.stats-month-bar {
    display: block;
    width: 70%;
    max-width: 32px;
    background: var(--brand);
    border-radius: var(--r-sm) var(--r-sm) 0 0;
    transition: height .4s ease;
}
.stats-month-bar-value {
    font-size: .7rem;
    color: var(--text-soft);
    margin-bottom: 3px;
}
.stats-month-label {
    font-size: .7rem;
    color: var(--text-faint);
    margin-top: 5px;
    white-space: nowrap;
}

/* --- Responsive : tout en une colonne sur petit écran --- */
@media (max-width: 760px) {
    .stats-kpis { grid-template-columns: 1fr; }
    .stats-grid { grid-template-columns: 1fr; }
    .stats-bar-row { grid-template-columns: 100px 1fr 36px; }
    .stats-month-label { font-size: .6rem; }
}
/* =============================================================================
   LVSTORE — Planning de fabrication (vue par échéance)
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

.plan-group {
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 4px solid var(--border);
    border-radius: var(--r-lg);
    padding: 14px 16px;
    margin-bottom: 16px;
}
.plan-group-title {
    margin: 0 0 12px;
    font-size: 1rem;
    display: flex;
    align-items: center;
    gap: 10px;
}
.plan-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 22px;
    padding: 0 7px;
    border-radius: 11px;
    background: var(--surface-2);
    color: var(--text-soft);
    font-size: .8rem;
    font-weight: 600;
}

/* Couleurs de bord gauche par urgence */
.plan-retard   { border-left-color: var(--red); }
.plan-today    { border-left-color: var(--brand); }
.plan-semaine  { border-left-color: #e6b800; }
.plan-avenir   { border-left-color: var(--green); }
.plan-sansdate { border-left-color: var(--text-faint); }
.plan-termine  { border-left-color: var(--text-faint); opacity: .75; }

/* Lignes d'ordres */
.plan-list { display: flex; flex-direction: column; gap: 6px; }
.plan-row {
    display: grid;
    grid-template-columns: 96px 1fr auto auto;
    align-items: center;
    gap: 14px;
    padding: 9px 12px;
    border-radius: var(--r-sm);
    background: var(--surface-2);
    text-decoration: none;
    color: var(--text);
    transition: background var(--trans, .15s);
}
.plan-row:hover { background: var(--brand-soft); }
.plan-date { font-variant-numeric: tabular-nums; color: var(--text-soft); font-size: var(--fs-sm); white-space: nowrap; }
.plan-client { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan-ref { font-family: monospace; color: var(--brand-600, #c77f1a); font-weight: 600; margin-right: 6px; }
.plan-volets { color: var(--text-soft); font-size: var(--fs-sm); white-space: nowrap; }

@media (max-width: 720px) {
    .plan-row {
        grid-template-columns: 1fr auto;
        grid-row-gap: 4px;
    }
    .plan-date { order: -1; }
    .plan-volets { text-align: right; }
}
/* =============================================================================
   LVSTORE — Planning calendrier hebdomadaire (glisser-déposer)
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

.cal-toolbar {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}
.cal-week-label { font-weight: 600; }

/* Disposition : liste à gauche, calendrier à droite */
.cal-layout {
    display: grid;
    grid-template-columns: 260px 1fr;
    gap: 16px;
    align-items: start;
}

/* --- Colonne des ordres --- */
.cal-orders {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    padding: 12px;
    position: sticky;
    top: 16px;
    max-height: calc(100vh - var(--topbar-h, 60px) - 32px);
    display: flex;
    flex-direction: column;
}
.cal-orders-title { margin: 0 0 10px; font-size: .95rem; }
.cal-search {
    width: 100%;
    margin-bottom: 10px;
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    font-size: var(--fs-sm);
}
.cal-orders-list { overflow-y: auto; display: flex; flex-direction: column; gap: 7px; }

.cal-order {
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    padding: 8px 10px;
    cursor: grab;
    font-size: var(--fs-sm);
}
.cal-order:hover { border-color: var(--brand); }
.cal-order:active { cursor: grabbing; }
.cal-order.is-placed { opacity: .6; }
.cal-order-main { display: block; font-weight: 500; }
.cal-order-meta { display: block; color: var(--text-soft); font-size: .78rem; margin-top: 3px; }
.cal-placed-tag {
    display: inline-block;
    background: var(--brand-soft);
    color: var(--brand-600, #c77f1a);
    border-radius: 8px;
    padding: 1px 7px;
    font-weight: 600;
    margin-left: 4px;
}
.cal-ref { font-family: monospace; color: var(--brand-600, #c77f1a); font-weight: 600; }

/* --- Grille calendrier : 7 colonnes --- */
.cal-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 8px;
    min-width: 0;
}
.cal-day {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
.cal-day.is-today { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand); }
.cal-day-head {
    background: var(--surface-2);
    padding: 7px 8px;
    font-size: .8rem;
    font-weight: 600;
    text-align: center;
    border-bottom: 1px solid var(--border);
}
.cal-day-num { color: var(--text-soft); }

/* --- Cases demi-journée --- */
.cal-cell {
    flex: 1 1 auto;
    min-height: 110px;
    display: flex;
    flex-direction: column;
    border-bottom: 1px solid var(--border);
}
.cal-cell:last-child { border-bottom: none; }
.cal-cell-head {
    font-size: .68rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-faint);
    padding: 4px 7px 2px;
}
.cal-cell-body {
    flex: 1 1 auto;
    padding: 4px 5px 7px;
    display: flex;
    flex-direction: column;
    gap: 5px;
}
.cal-cell.cal-drop { background: var(--brand-soft); }

/* --- Cartes posées --- */
.cal-card {
    position: relative;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-left: 3px solid var(--brand);
    border-radius: var(--r-sm);
    padding: 6px 22px 6px 8px;
    font-size: .76rem;
    cursor: grab;
}
.cal-card:active { cursor: grabbing; }
.cal-card-main { display: block; font-weight: 500; line-height: 1.25; }
.cal-card-meta { display: block; color: var(--text-soft); font-size: .7rem; margin-top: 2px; }
.cal-card-del {
    position: absolute;
    top: 3px;
    right: 4px;
    border: none;
    background: none;
    color: var(--text-faint);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 2px;
}
.cal-card-del:hover { color: var(--red); }

/* La badge réduite dans les cartes */
.cal-card .badge, .cal-card-meta .badge { font-size: .62rem; padding: 1px 5px; }

/* --- Responsive : calendrier en colonnes empilées sur petit écran --- */
@media (max-width: 1100px) {
    .cal-layout { grid-template-columns: 1fr; }
    .cal-orders { position: static; max-height: none; }
    .cal-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
    .cal-grid { grid-template-columns: 1fr; }
}
/* =============================================================================
   LVSTORE — Languette "PDF" fixée au bord droit
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

.odf-pdf-tab {
    position: fixed;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    z-index: 998;                 /* sous le volet (1000), au-dessus du contenu */
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 14px 8px;
    border: none;
    border-radius: var(--r-sm) 0 0 var(--r-sm);
    background: var(--brand);
    color: #fff;
    cursor: pointer;
    box-shadow: -2px 2px 10px rgba(0,0,0,.18);
    transition: padding-right .15s ease, background .15s ease;
}
.odf-pdf-tab:hover { background: var(--brand-600, #c77f1a); padding-right: 12px; }
.odf-pdf-tab-label {
    writing-mode: vertical-rl;
    text-orientation: mixed;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .08em;
    text-transform: uppercase;
}

@media (max-width: 700px) {
    .odf-pdf-tab { padding: 10px 6px; }
    .odf-pdf-tab-label { font-size: .65rem; }
}
/* =============================================================================
   LVSTORE — Bloc "lames rayées / pertes" du poste de découpe
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

.decoupe-pertes { margin-bottom: 16px; border-left: 3px solid var(--red); }
.decoupe-pertes-liste { display: flex; flex-direction: column; gap: 6px; margin-bottom: 6px; }
.decoupe-perte-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 6px 10px;
    background: var(--surface-2);
    border-radius: var(--r-sm);
    font-size: var(--fs-sm);
}
.decoupe-perte-form {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    align-items: center;
    margin-top: 10px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}
.decoupe-perte-form select,
.decoupe-perte-form input {
    padding: 7px 10px;
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    font-size: var(--fs-sm);
}
.decoupe-perte-form input[name="longueur"] { width: 170px; }
.decoupe-perte-form input[name="note"] { flex: 1 1 160px; min-width: 120px; }

@media (max-width: 600px) {
    .decoupe-perte-form { flex-direction: column; align-items: stretch; }
    .decoupe-perte-form input[name="longueur"] { width: 100%; }
}
/* =============================================================================
   LVSTORE — Lames cliquables dans le plan de coupe (signalement zone abîmée)
   Complément à lot-rayures.css. À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

.cut-lame { transition: filter .12s ease, outline .12s ease; }
.cut-lame:hover { filter: brightness(1.12); outline: 2px solid #fff; outline-offset: -2px; }
/* =============================================================================
   LVSTORE — Alerte "découpes à réaliser" sur le tableau de bord
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

.dash-decoupe-alert {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 13px 16px;
    margin-bottom: 18px;
    background: var(--brand-soft);
    border: 1px solid var(--brand);
    border-left: 4px solid var(--brand);
    border-radius: var(--r-lg);
    color: var(--text);
    text-decoration: none;
    transition: background .15s ease;
}
.dash-decoupe-alert:hover { background: #fdeecf; }
.dash-decoupe-ico {
    display: inline-flex;
    color: var(--brand-600, #c77f1a);
    flex-shrink: 0;
}
.dash-decoupe-go {
    margin-left: auto;
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--brand-600, #c77f1a);
    white-space: nowrap;
}
@media (max-width: 600px) {
    .dash-decoupe-alert { flex-wrap: wrap; }
    .dash-decoupe-go { margin-left: 0; }
}
/* =============================================================================
   LVSTORE — Correctif affichage mobile du détail d'un ordre
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

@media (max-width: 900px) {
    /* Le détail déplié d'un ordre est dans un <td colspan>. La règle mobile
       générique "table td { display:flex; justify-content:space-between }"
       le mettait en flex horizontal, ce qui poussait les volets hors de l'écran.
       On le remet en flux vertical normal. */
    table td.odf-detail-cell {
        display: block !important;
        width: 100%;
        padding: 14px !important;
    }
    table td.odf-detail-cell::before { content: none !important; }

    /* Cartes de volets : SVG au-dessus des caractéristiques (1 colonne),
       au lieu de côte à côte (230px + reste) qui débordait. */
    .volet-card-grid { grid-template-columns: 1fr !important; }

    /* La vignette SVG du volet ne dépasse pas la largeur dispo */
    .volet-svg-wrap { max-width: 100%; overflow: hidden; }
}
/* =============================================================================
   LVSTORE — Languette "Étiquettes" sous la languette "PDF" (bord droit)
   Complète lot-pdftab.css. À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

/* Conteneur qui empile les languettes au bord droit, centré verticalement. */
.odf-tabs {
    position: fixed;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    z-index: 998;                 /* sous le volet (1000), au-dessus du contenu */
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 8px;
}

/* Les languettes ne se positionnent plus seules : c'est le conteneur qui le fait.
   (On neutralise le position:fixed individuel défini dans lot-pdftab.css.) */
.odf-tabs .odf-pdf-tab,
.odf-tabs .odf-label-tab {
    position: static;
    transform: none;
    top: auto;
}

/* Languette "Étiquettes" : même forme que la languette PDF, teinte plus foncée
   pour la distinguer. */
.odf-label-tab {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 14px 8px;
    border: none;
    border-radius: var(--r-sm) 0 0 var(--r-sm);
    background: var(--brand-600, #c77f1a);
    color: #fff;
    cursor: pointer;
    box-shadow: -2px 2px 10px rgba(0,0,0,.18);
    transition: padding-right .15s ease, background .15s ease;
}
.odf-label-tab:hover { background: #a8690f; padding-right: 12px; }

@media (max-width: 700px) {
    .odf-label-tab { padding: 10px 6px; }
}
/* =============================================================================
   LVSTORE — Interrupteur (switch) rouge/vert pour actif/inactif
   Remplace les badges Actif/Inactif + boutons activer/désactiver.
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

.switch-toggle {
    position: relative;
    display: inline-block;
    width: 42px;
    height: 24px;
    border: none;
    border-radius: 12px;
    cursor: pointer;
    padding: 0;
    vertical-align: middle;
    transition: background .18s ease;
    flex-shrink: 0;
}
.switch-toggle .switch-knob {
    position: absolute;
    top: 3px;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 3px rgba(0,0,0,.35);
    transition: left .18s ease;
}
.switch-on  { background: var(--green, #16a34a); }
.switch-on  .switch-knob { left: 21px; }
.switch-off { background: var(--red, #dc2626); }
.switch-off .switch-knob { left: 3px; }
.switch-toggle:hover { filter: brightness(1.05); }
/* =============================================================================
   LVSTORE — Panneau d'outils : languettes d'action (statut, suppression)
   + correctif des icônes de boutons sur mobile.
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

/* Languettes d'action, même forme que les languettes PDF/Étiquettes. */
.odf-tool-tab {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 14px 8px;
    border: none;
    border-radius: var(--r-sm) 0 0 var(--r-sm);
    color: #fff;
    cursor: pointer;
    box-shadow: -2px 2px 10px rgba(0,0,0,.18);
    transition: padding-right .15s ease, background .15s ease;
    text-decoration: none;
}
.odf-tool-tab:hover { padding-right: 12px; }

.odf-tool-decoupe { background: var(--blue, #2563eb); }
.odf-tool-decoupe:hover { background: #1d4ed8; }
.odf-tool-fab { background: var(--green, #16a34a); }
.odf-tool-fab:hover { background: #15803d; }
.odf-tool-del { background: var(--red, #dc2626); }
.odf-tool-del:hover { background: #b91c1c; }

@media (max-width: 700px) {
    .odf-tool-tab { padding: 10px 6px; }
}

/* -----------------------------------------------------------------------------
   Correctif : icônes SVG des boutons compressées à zéro sur mobile.
   Les boutons sont en display:inline-flex ; un bouton icône+texte sur écran
   étroit comprimait l'icône (flex-item) jusqu'à la masquer. On la fige.
   ----------------------------------------------------------------------------- */
.btn svg, .btn-ico svg { flex-shrink: 0; }
/* =============================================================================
   LVSTORE — Bannière "ordres en découpe non planifiés" (tableau de bord)
   Variante de la bannière découpe, en bleu (mène au planning).
   À concaténer UNE SEULE FOIS à styles.css.
   ============================================================================= */

.dash-plan-alert {
    background: #eaf1fe;
    border-color: var(--blue, #2563eb);
    border-left-color: var(--blue, #2563eb);
    margin-top: -6px;
}
.dash-plan-alert:hover { background: #dbe7fd; }
.dash-plan-alert .dash-decoupe-ico,
.dash-plan-alert .dash-decoupe-go { color: var(--blue, #2563eb); }
