/*
 * ============================================================
 *  Charte graphique — ERP Vandora Food
 * ============================================================
 *
 *  Couleurs de marque : noir #1A1A1A, or #C9A24B, blanc.
 *  Titres en Oswald 500, textes en Inter, boutons en Inter 700.
 *
 *  Une règle non négociable, mesurée et non supposée :
 *
 *      or sur blanc              2,40:1   illisible
 *      or sur noir               7,25:1   excellent
 *      noir sur or               7,25:1   excellent
 *
 *  Le minimum lisible (WCAG AA) est de 4,5:1. L'or ne peut donc
 *  jamais porter du texte sur fond clair. Il sert de SURFACE — un
 *  bouton or à texte noir — ou d'accent sur le noir de la barre de
 *  navigation. Pour les rares textes qui doivent être dorés sur
 *  fond clair, --or-fonce (4,89:1) prend le relais.
 *
 *  C'est ce qui donne sa structure à l'interface : navigation
 *  sombre où l'or s'exprime pleinement, zone de travail claire où
 *  il se limite aux actions et aux repères.
 *
 *  Aucune couleur ne doit être écrite en dur ailleurs que dans ce
 *  fichier : c'est ce qui rendra un futur changement de charte
 *  indolore.
 */

/* ------------------------------------------------------------------ */
/*  Polices — hébergées localement                                     */
/*                                                                     */
/*  Pas de CDN Google : une dépendance externe de moins, et l'adresse  */
/*  IP des utilisateurs ne part pas chez un tiers (CDC §4.7, CNDP).    */
/* ------------------------------------------------------------------ */

@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("../fonts/inter-latin-Gz7AlRl.woff2") format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
        U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
        U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("../fonts/inter-latin-ext-1Br77OV.woff2") format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
        U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
        U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: 'Oswald';
    font-style: normal;
    font-weight: 200 700;
    font-display: swap;
    src: url("../fonts/oswald-latin-adbz0dn.woff2") format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
        U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
        U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'Oswald';
    font-style: normal;
    font-weight: 200 700;
    font-display: swap;
    src: url("../fonts/oswald-latin-ext-NRsvKql.woff2") format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304,
        U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
        U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ------------------------------------------------------------------ */
/*  Jetons                                                             */
/* ------------------------------------------------------------------ */

:root {
    /* --- Marque --- */
    --noir: #1a1a1a;
    --or: #c9a24b;
    --or-clair: #e0c07a;  /* accent sur fond sombre */
    --or-fonce: #8a6d25;  /* seul or admis en TEXTE sur fond clair */
    --creme: #f5f1e6;     /* le blanc cassé du monogramme */
    --blanc: #ffffff;

    /* --- Neutres, légèrement chauds pour s'accorder au crème --- */
    --gris-50: #faf9f7;
    --gris-100: #f4f2ee;
    --gris-200: #e8e5df;
    --gris-300: #d5d1c8;
    --gris-400: #a8a29a;
    --gris-500: #78736b;
    --gris-600: #57534e;
    --gris-700: #3f3b37;
    --gris-800: #2a2724;

    /* --- Rôles : zone de travail claire --- */
    --fond: var(--gris-50);
    --surface: var(--blanc);
    --surface-attenuee: var(--gris-100);
    --texte: var(--noir);
    --texte-attenue: var(--gris-500);
    --bordure: var(--gris-200);
    --bordure-forte: var(--gris-300);

    /* --- Rôles : navigation sombre --- */
    --nav-fond: var(--noir);
    --nav-texte: rgba(245, 241, 230, 0.72);
    --nav-texte-actif: var(--creme);
    --nav-survol: rgba(245, 241, 230, 0.07);
    --nav-actif: rgba(201, 162, 75, 0.14);
    --nav-bordure: rgba(245, 241, 230, 0.1);

    /* --- États --- */
    /* L'orange d'alerte est volontairement éloigné de l'or : deux tons
       dorés voisins rendraient une alerte indiscernable d'un accent. */
    --succes: #15803d;
    --succes-fond: #ecfdf3;
    --alerte: #c2410c;
    --alerte-fond: #fff4ed;
    --erreur: #b91c1c;
    --erreur-fond: #fef2f2;
    --info: #1d4ed8;
    --info-fond: #eff6ff;

    /* --- Typographie --- */
    --police-titre: 'Oswald', 'Arial Narrow', sans-serif;
    --police: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --police-mono: ui-monospace, 'Cascadia Mono', Consolas, monospace;

    /* --- Formes --- */
    --rayon: 6px;
    --rayon-large: 10px;
    --ombre: 0 1px 2px rgba(26, 26, 26, .05), 0 1px 3px rgba(26, 26, 26, .06);
    --ombre-haute: 0 4px 6px -1px rgba(26, 26, 26, .08), 0 2px 4px -2px rgba(26, 26, 26, .06);

    --largeur-nav: 244px;
}

/* ------------------------------------------------------------------ */
/*  Base                                                               */
/* ------------------------------------------------------------------ */

*,
*::before,
*::after {
    box-sizing: border-box;
}

/* L'attribut `hidden` doit toujours l'emporter.

   Le navigateur ne le pose qu'en display:none par defaut : la moindre
   regle qui donne un display a l'element — .pastille est en
   inline-block — le fait reapparaitre, et l'on obtient une etiquette
   vide a l'ecran. Le piege a deja mordu une fois ici, sur les sections
   de formulaire. */
[hidden] { display: none !important; }

html {
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background: var(--fond);
    color: var(--texte);
    font: 400 14.5px/1.6 var(--police);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 {
    margin: 0;
    font-family: var(--police-titre);
    font-weight: 500;
    letter-spacing: .01em;
    line-height: 1.25;
}

h1 { font-size: 1.75rem; }
h2 { font-size: 1.3rem; }
h3 { font-size: 1.05rem; }

p { margin: 0 0 1rem; }

a {
    color: var(--or-fonce);
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
}

a:hover { color: var(--noir); }

code {
    font-family: var(--police-mono);
    font-size: .9em;
}

:focus-visible {
    outline: 2px solid var(--or-fonce);
    outline-offset: 2px;
}

/* ------------------------------------------------------------------ */
/*  Bandeau d'environnement                                            */
/* ------------------------------------------------------------------ */

.bandeau-instance {
    padding: 5px 14px;
    color: var(--blanc);
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: .04em;
    text-align: center;
}

.bandeau-instance--preprod { background: var(--alerte); }
.bandeau-instance--inconnu { background: var(--gris-600); }

.bandeau-instance__detail {
    font-weight: 400;
    opacity: .85;
}

/* ------------------------------------------------------------------ */
/*  Coquille applicative : navigation sombre + zone de travail claire   */
/* ------------------------------------------------------------------ */

.coquille {
    display: grid;
    grid-template-columns: var(--largeur-nav) 1fr;
    min-height: 100vh;
}

.nav {
    display: flex;
    flex-direction: column;
    background: var(--nav-fond);
    color: var(--nav-texte);
}

.nav__marque {
    display: flex;
    align-items: center;
    gap: .7rem;
    padding: 1.1rem 1.15rem;
    border-bottom: 1px solid var(--nav-bordure);
    color: var(--creme);
    text-decoration: none;
}

.nav__monogramme {
    width: 26px;
    height: 27px;
    flex: none;
    color: var(--creme);
}

.nav__nom {
    font-family: var(--police-titre);
    font-size: 1rem;
    font-weight: 500;
    letter-spacing: .16em;
    line-height: 1.1;
}

.nav__nom span {
    display: block;
    color: var(--or);
    font-size: .62rem;
    font-weight: 400;
    letter-spacing: .3em;
}

.nav__groupes {
    flex: 1;
    padding: 1rem .6rem;
    overflow-y: auto;
}

.nav__titre-groupe {
    margin: 1.25rem 0 .4rem;
    padding: 0 .55rem;
    color: var(--gris-500);
    font-family: var(--police-titre);
    font-size: .66rem;
    font-weight: 500;
    letter-spacing: .18em;
    text-transform: uppercase;
}

.nav__titre-groupe:first-child { margin-top: 0; }

.nav__lien {
    display: flex;
    align-items: center;
    gap: .65rem;
    padding: .48rem .55rem;
    border-radius: var(--rayon);
    color: var(--nav-texte);
    font-size: .875rem;
    font-weight: 500;
    text-decoration: none;
}

.nav__lien:hover {
    background: var(--nav-survol);
    color: var(--nav-texte-actif);
}

/* Le repère actif est une barre dorée : l'or sert d'indicateur, jamais
   de couleur de texte. */
.nav__lien--actif {
    position: relative;
    background: var(--nav-actif);
    color: var(--nav-texte-actif);
}

.nav__lien--actif::before {
    content: '';
    position: absolute;
    left: -.6rem;
    top: 50%;
    width: 3px;
    height: 1.15rem;
    background: var(--or);
    border-radius: 0 2px 2px 0;
    transform: translateY(-50%);
}

.nav__lien svg {
    width: 17px;
    height: 17px;
    flex: none;
    opacity: .85;
}

.nav__pied {
    padding: .85rem 1.15rem;
    border-top: 1px solid var(--nav-bordure);
    font-size: .8rem;
}

.nav__utilisateur {
    color: var(--nav-texte-actif);
    font-weight: 500;
}

.nav__role {
    color: var(--gris-500);
    font-size: .74rem;
}

.nav__deconnexion {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    margin-top: .5rem;
    color: var(--nav-texte);
    font-size: .8rem;
    text-decoration: none;
}

.nav__deconnexion:hover { color: var(--or-clair); }
.nav__deconnexion svg { width: 15px; height: 15px; }

.zone-travail {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* ------------------------------------------------------------------ */
/*  Mise en page de contenu                                            */
/* ------------------------------------------------------------------ */

/*
 * Les écrans de gestion occupent 90 % de la zone de travail : un tableau
 * de stock ou de marges vit de sa largeur, et le brider à une colonne de
 * lecture obligerait à faire défiler horizontalement pour rien.
 *
 * Le plafond très haut existe seulement pour les écrans très larges, où
 * une ligne de tableau devenue trop longue cesse d'être lisible.
 */
.page {
    width: 90%;
    max-width: 120rem;
    margin: 0 auto;
    padding: 2rem 0 4rem;
}

/* Les écrans de lecture — messages, états vides — gardent une largeur de
   confort : 90 % d'un grand écran pour trois phrases serait illisible. */
.page--etroite {
    width: 100%;
    max-width: 46rem;
    padding-left: 2rem;
    padding-right: 2rem;
}

.page__entete {
    margin-bottom: 1.75rem;
    padding-bottom: 1.1rem;
    border-bottom: 1px solid var(--bordure);
}

.page__titre { margin: 0 0 .2rem; }

.page__intro {
    margin: 0;
    color: var(--texte-attenue);
}

.carte {
    padding: 1.35rem 1.5rem;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon-large);
    background: var(--surface);
    box-shadow: var(--ombre);
}

.carte + .carte { margin-top: 1.25rem; }

.carte__titre {
    margin: 0 0 1rem;
    font-size: .78rem;
    font-family: var(--police-titre);
    font-weight: 500;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--texte-attenue);
}

/* Un titre de carte accompagne parfois une action : l'action reste à
   droite, le titre garde sa marge basse. */
.carte__entete {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
}

.carte__entete .carte__titre { margin-bottom: 1rem; }

/* ------------------------------------------------------------------ */
/*  Inventaire (CDC §6.5)                                              */
/*                                                                     */
/*  Les zones sont de grandes cibles : on les touche avec un téléphone */
/*  dans une main et un carton dans l'autre. Le champ de comptage      */
/*  suit la même logique — large, et en clavier numérique.             */
/* ------------------------------------------------------------------ */

/* Une liste de produits qu'on parcourt à l'image : suppléments d'un
   plat, plats qui portent un supplément. Le minimum de colonne tient la
   vignette de 150 px et le libellé à côté d'elle. */
.grille-vignettes {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: .85rem 1.4rem;
    margin-top: .6rem;
}

.grille-zones {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: .85rem;
}

.zone {
    display: block;
    padding: 1rem 1.1rem;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    background: var(--gris-50);
    text-decoration: none;
    color: inherit;
    transition: border-color .12s, background .12s;
}

.zone:hover {
    border-color: var(--or);
    background: var(--blanc);
}

.zone--complete {
    border-color: var(--succes);
    background: var(--succes-fond);
}

.zone__nom {
    font-family: var(--police-titre);
    font-weight: 500;
    font-size: 1.02rem;
}

.zone__avancement {
    margin-top: .15rem;
    font-size: 1.35rem;
    font-weight: 600;
}

.zone__detail {
    margin-top: .3rem;
    color: var(--texte-attenue);
    font-size: .78rem;
    line-height: 1.35;
}

/* Le champ d'une feuille de comptage : large, aligné à droite, lisible
   à bout de bras. */
.champ__saisie--comptage {
    max-width: 9rem;
    margin-left: auto;
    text-align: right;
    font-size: 1.05rem;
    font-variant-numeric: tabular-nums;
}

.tableau--comptage td { vertical-align: middle; }

/* Un refus se motive sur place : le champ et son bouton restent
   ensemble, sans ouvrir un écran de plus pour trois mots. */
.formulaire-motif {
    display: flex;
    gap: .35rem;
    align-items: center;
}

.champ__saisie--motif {
    min-width: 9rem;
    padding: .3rem .5rem;
    font-size: .82rem;
}

/* Une quantité signée se lit d'un coup d'oeil : un stock négatif est une
   alerte du CDC §6.4, pas une valeur ordinaire. */
.valeur--negative { color: var(--erreur); }
.valeur--positive { color: var(--succes); }

/* Un groupe de cases à cocher — les boutiques d'un compte — se lit en
   ligne : empilées, deux boutiques occupent autant de hauteur que tout
   le reste du bloc. */
.cases-multiples {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem 1.5rem;
}

/* Un catalogue se garnit par poignées : à deux cents références, les
   cases s'affichent en colonnes plutôt qu'en ligne. Une liste à plat
   ferait défiler dix écrans là où trois suffisent, et l'oeil ne
   retrouve plus la case voisine d'une ligne à l'autre. */
.cases-multiples--colonnes {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
    gap: .45rem 1.5rem;
}

/* La barre de recherche et d'enregistrement reste sous la main : à deux
   cents lignes, le bouton est autrement à trois écrans de la première
   case cochée. */
.barre-selection {
    position: sticky;
    top: .5rem;
    z-index: 5;
}

/* Un prix saisi dans une grille : étroit, aligné à droite, chiffres de
   largeur fixe pour que la colonne se lise comme une colonne. */
.champ__saisie--nombre {
    max-width: 7rem;
    margin-left: auto;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Une valeur de tuile qui est un identifiant technique — un DSN, une
   adresse — se lit en monospace et doit pouvoir déborder sans pousser la
   tuile hors de la grille. */
.tuile__valeur--code {
    font-family: ui-monospace, "SFMono-Regular", "Menlo", "Consolas", monospace;
    font-size: .82rem;
    line-height: 1.4;
    overflow-wrap: anywhere;
}

/* Le champ de test et son bouton sur une même ligne : l'un ne sert à
   rien sans l'autre. */
.ligne-test {
    display: flex;
    align-items: flex-end;
    gap: .75rem;
    flex-wrap: wrap;
}

.ligne-test .champ {
    flex: 1 1 18rem;
    margin: 0;
}

/* ------------------------------------------------------------------ */
/*  Permissions (CDC §4.2)                                             */
/*                                                                     */
/*  Une trentaine de cases : sans mise en grille, l'écran devient une  */
/*  colonne interminable où l'on perd le fil des groupes. Chaque case  */
/*  dit aussi ce que le rôle en fait — c'est la seule façon de voir    */
/*  d'un coup d'oeil ce qui est une exception.                         */
/* ------------------------------------------------------------------ */

.grille-permissions {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: .5rem 1.5rem;
}

.permission {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: baseline;
    column-gap: .55rem;
    padding: .35rem 0;
}

.permission__libelle {
    font-size: .9rem;
    cursor: pointer;
}

.permission__note {
    grid-column: 2;
    color: var(--texte-attenue);
    font-size: .75rem;
}

/* Un garde-fou du CDC §4.2 : visible, expliqué, mais jamais cochable. */
.permission--verrouillee .permission__libelle {
    color: var(--texte-attenue);
    cursor: not-allowed;
}

.permission--verrouillee .permission__note { color: var(--or-fonce); }

/* Le thème de formulaire enveloppe les cases : dans cette grille, on ne
   veut que la case elle-même. */
.permission .champ,
.permission .champ--case {
    margin: 0;
    display: contents;
}

.permission .champ__etiquette,
.permission .champ__aide { display: none; }

/* ------------------------------------------------------------------ */
/*  Prix par canal (CDC §5.4, §5.7)                                    */
/*                                                                     */
/*  Chaque canal est une carte : la saisie à gauche, les trois         */
/*  repères du conseiller à droite. Les mettre côte à côte est le      */
/*  point de l'écran — on tape un prix en regardant ce qu'il vaut.     */
/* ------------------------------------------------------------------ */

.canal-entete {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
}

.canal-entete__detail {
    margin: -.6rem 0 0;
    color: var(--texte-attenue);
    font-size: .84rem;
}

.canal-corps {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
    align-items: end;
    gap: 1.5rem;
    margin-top: 1rem;
}

@media (max-width: 900px) {
    .canal-corps { grid-template-columns: 1fr; align-items: stretch; }
}

.reperes {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: .75rem;
}

.repere {
    padding: .7rem .85rem;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    background: var(--gris-50);
    text-align: center;
}

.repere__coefficient {
    font-family: var(--police-titre);
    font-weight: 500;
    font-size: .95rem;
    color: var(--texte-attenue);
}

.repere__prix {
    margin-top: .1rem;
    font-size: 1.15rem;
    font-weight: 600;
}

.repere__detail {
    margin-top: .15rem;
    color: var(--texte-attenue);
    font-size: .76rem;
}

/* ------------------------------------------------------------------ */
/*  Tableau de propriétés                                              */
/* ------------------------------------------------------------------ */

.fiche {
    width: 100%;
    border-collapse: collapse;
}

.fiche th,
.fiche td {
    padding: .62rem 0;
    text-align: left;
    vertical-align: top;
}

.fiche tr + tr th,
.fiche tr + tr td {
    border-top: 1px solid var(--bordure);
}

.fiche th {
    width: 13rem;
    color: var(--texte-attenue);
    font-weight: 500;
}

.alerte-douce {
    color: var(--texte-attenue);
    font-size: .88rem;
}

/* ------------------------------------------------------------------ */
/*  Encadrés                                                           */
/* ------------------------------------------------------------------ */

.note {
    margin: 1.5rem 0 0;
    padding: .85rem 1rem;
    border-left: 3px solid var(--or);
    border-radius: 0 var(--rayon) var(--rayon) 0;
    background: var(--surface-attenuee);
    color: var(--gris-600);
    font-size: .88rem;
}

.message {
    display: flex;
    gap: .6rem;
    padding: .75rem .95rem;
    border-radius: var(--rayon);
    font-size: .88rem;
    line-height: 1.5;
}

.message svg { width: 17px; height: 17px; flex: none; margin-top: .15rem; }

.message--erreur { background: var(--erreur-fond); color: var(--erreur); }
.message--succes { background: var(--succes-fond); color: var(--succes); }
.message--alerte { background: var(--alerte-fond); color: var(--alerte); }
.message--info { background: var(--info-fond); color: var(--info); }

/* ------------------------------------------------------------------ */
/*  Formulaires                                                        */
/* ------------------------------------------------------------------ */

.champ + .champ { margin-top: 1rem; }

.champ__etiquette {
    display: block;
    margin-bottom: .35rem;
    font-size: .82rem;
    font-weight: 600;
    letter-spacing: .01em;
}

.champ__saisie {
    width: 100%;
    padding: .6rem .75rem;
    border: 1px solid var(--bordure-forte);
    border-radius: var(--rayon);
    background: var(--surface);
    color: var(--texte);
    font: inherit;
}

.champ__saisie::placeholder { color: var(--gris-400); }

.champ__saisie:focus {
    border-color: var(--or-fonce);
    outline: 2px solid rgba(201, 162, 75, .3);
    outline-offset: 0;
}

.champ__aide {
    margin: .35rem 0 0;
    color: var(--texte-attenue);
    font-size: .8rem;
}

/* Un code généré occupe la place d'un champ pour que la grille reste
   alignée, mais n'en a jamais l'apparence : pas de cadre, pas de fond
   clair, rien qui invite à cliquer dedans. */
.code-genere {
    margin: 0;
    padding: .62rem 0;
    font-family: ui-monospace, "SFMono-Regular", "Menlo", "Consolas", monospace;
    font-size: .95rem;
    letter-spacing: .04em;
    color: var(--texte);
}

.code-genere--attente {
    font-family: inherit;
    letter-spacing: normal;
    font-style: italic;
    color: var(--texte-attenue);
}

/* ------------------------------------------------------------------ */
/*  Boutons — Inter 700                                                */
/* ------------------------------------------------------------------ */

.bouton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .45rem;
    padding: .6rem 1.15rem;
    border: 1px solid transparent;
    border-radius: var(--rayon);
    font-family: var(--police);
    font-size: .875rem;
    font-weight: 700;
    letter-spacing: .01em;
    line-height: 1.2;
    text-decoration: none;
    cursor: pointer;
}

.bouton svg { width: 16px; height: 16px; }

/* L'or en surface, le noir en texte : 7,25:1, largement lisible. */
.bouton--principal {
    background: var(--or);
    color: var(--noir);
}

.bouton--principal:hover { background: var(--or-clair); }

.bouton--secondaire {
    border-color: var(--bordure-forte);
    background: var(--surface);
    color: var(--texte);
}

.bouton--secondaire:hover { background: var(--surface-attenuee); }

.bouton--pleine-largeur { width: 100%; }

/* ------------------------------------------------------------------ */
/*  Écran de connexion                                                 */
/* ------------------------------------------------------------------ */

.connexion {
    display: grid;
    grid-template-columns: 1fr 1fr;
    min-height: 100vh;
}

/* Le panneau de marque : c'est là que l'or s'exprime, sur son noir. */
.connexion__marque {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.5rem;
    padding: 3rem;
    background: var(--noir);
    color: var(--creme);
    text-align: center;
}

.connexion__logo {
    width: 190px;
    height: 190px;
    border-radius: var(--rayon-large);
}

.connexion__accroche {
    max-width: 22rem;
    margin: 0;
    color: rgba(245, 241, 230, .62);
    font-size: .9rem;
    line-height: 1.65;
}

.connexion__formulaire {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 3rem 2rem;
    background: var(--surface);
}

.connexion__boite {
    width: 100%;
    max-width: 21rem;
}

.connexion__titre { margin: 0 0 .3rem; }

.connexion__sous-titre {
    margin: 0 0 1.75rem;
    color: var(--texte-attenue);
    font-size: .9rem;
}

.connexion__action { margin-top: 1.5rem; }

.connexion__pied {
    margin: 1.75rem 0 0;
    color: var(--gris-400);
    font-size: .78rem;
    text-align: center;
}

@media (max-width: 860px) {
    .connexion { grid-template-columns: 1fr; }

    .connexion__marque {
        gap: 1rem;
        padding: 2.25rem 2rem;
    }

    .connexion__logo { width: 104px; height: 104px; }
    .connexion__accroche { display: none; }
}

/* ------------------------------------------------------------------ */
/*  Adaptation aux petits écrans                                       */
/* ------------------------------------------------------------------ */

@media (max-width: 900px) {
    .coquille { grid-template-columns: 1fr; }

    .nav { flex-direction: row; align-items: center; overflow-x: auto; }
    .nav__groupes { display: flex; align-items: center; gap: .25rem; padding: .5rem; }
    .nav__titre-groupe { display: none; }
    .nav__lien { white-space: nowrap; }
    .nav__lien--actif::before { display: none; }
    .nav__marque { border-bottom: 0; border-right: 1px solid var(--nav-bordure); }
    .nav__pied { border-top: 0; border-left: 1px solid var(--nav-bordure); }

    .page { width: 100%; padding: 1.5rem 1.25rem 3rem; }
}

/* ------------------------------------------------------------------ */
/*  Entrées de navigation pas encore développées                       */
/*                                                                     */
/*  Affichées mais inertes : elles montrent la structure visée sans    */
/*  promettre un écran qui n'existe pas. Elles disparaîtront au fur    */
/*  et à mesure que les gestions du CDC seront livrées.                */
/* ------------------------------------------------------------------ */

.nav__lien--a-venir {
    color: var(--gris-600);
    cursor: default;
}

.nav__lien--a-venir:hover {
    background: none;
    color: var(--gris-600);
}

.nav__lien--a-venir svg { opacity: .45; }

.nav__jalon {
    margin-left: auto;
    padding: .05rem .34rem;
    border: 1px solid var(--gris-700);
    border-radius: 3px;
    color: var(--gris-500);
    font-size: .6rem;
    font-weight: 600;
    letter-spacing: .06em;
}

/* ------------------------------------------------------------------ */
/*  Barre de contexte : quelle boutique on regarde                     */
/*                                                                     */
/*  Presque tout l'ERP est local (coût, stock, marges). L'écran doit   */
/*  dire en permanence de quelle boutique il parle.                    */
/* ------------------------------------------------------------------ */

.barre-contexte {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .65rem 5%;
    border-bottom: 1px solid var(--bordure);
    background: var(--surface);
}

.barre-contexte__libelle {
    color: var(--texte-attenue);
    font-size: .8rem;
    letter-spacing: .02em;
}

.barre-contexte__boutiques {
    display: flex;
    gap: .35rem;
}

.puce-boutique {
    padding: .3rem .7rem;
    border: 1px solid var(--bordure-forte);
    border-radius: 999px;
    background: var(--surface);
    color: var(--texte-attenue);
    font-size: .8rem;
    font-weight: 500;
    text-decoration: none;
}

.puce-boutique:hover { background: var(--surface-attenuee); color: var(--texte); }

.puce-boutique--active {
    border-color: var(--noir);
    background: var(--noir);
    color: var(--creme);
}

.puce-boutique--active:hover { background: var(--noir); color: var(--creme); }

/* ------------------------------------------------------------------ */
/*  Tableaux de données                                                */
/* ------------------------------------------------------------------ */

.tableau-enveloppe {
    overflow-x: auto;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon-large);
    background: var(--surface);
}

.tableau {
    width: 100%;
    border-collapse: collapse;
    font-size: .88rem;
}

.tableau th {
    padding: .7rem .9rem;
    border-bottom: 1px solid var(--bordure);
    background: var(--gris-50);
    color: var(--texte-attenue);
    font-family: var(--police-titre);
    font-size: .7rem;
    font-weight: 500;
    letter-spacing: .12em;
    text-align: left;
    text-transform: uppercase;
    white-space: nowrap;
}

.tableau td {
    padding: .65rem .9rem;
    border-bottom: 1px solid var(--bordure);
    vertical-align: middle;
}

.tableau tbody tr:last-child td { border-bottom: 0; }
.tableau tbody tr:hover { background: var(--gris-50); }

.tableau a { font-weight: 500; }

.tableau__nombre {
    font-family: var(--police-mono);
    font-size: .84rem;
    text-align: right;
    white-space: nowrap;
}

.tableau__vide {
    padding: 2rem;
    color: var(--texte-attenue);
    text-align: center;
}

.tableau--serre td { padding: .45rem .9rem; }

/* ------------------------------------------------------------------ */
/*  Pastilles                                                          */
/* ------------------------------------------------------------------ */

.pastille {
    display: inline-block;
    padding: .16rem .5rem;
    border-radius: 4px;
    background: var(--surface-attenuee);
    color: var(--gris-600);
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .02em;
    white-space: nowrap;
}

.pastille--or { background: rgba(201, 162, 75, .18); color: var(--or-fonce); }
.pastille--succes { background: var(--succes-fond); color: var(--succes); }
.pastille--alerte { background: var(--alerte-fond); color: var(--alerte); }
.pastille--erreur { background: var(--erreur-fond); color: var(--erreur); }
.pastille--info { background: var(--info-fond); color: var(--info); }

/* ------------------------------------------------------------------ */
/*  Filtres                                                            */
/* ------------------------------------------------------------------ */

/* ------------------------------------------------------------------ */
/*  Onglets de catégorie                                               */
/*                                                                     */
/*  Distincts des pastilles de filtre volontairement : un filtre       */
/*  restreint une liste, un onglet CHANGE ce qu'on regarde. Le trait   */
/*  sous l'onglet actif le dit mieux qu'une pastille de plus dans une  */
/*  rangée qui en compte déjà.                                         */
/*                                                                     */
/*  Ils défilent horizontalement plutôt que de passer à la ligne : une */
/*  carte de vingt catégories occuperait sinon trois rangées avant     */
/*  qu'on ait vu le premier produit.                                   */
/* ------------------------------------------------------------------ */

.onglets {
    display: flex;
    gap: .25rem;
    margin-bottom: 1.1rem;
    overflow-x: auto;
    border-bottom: 1px solid var(--bordure);
    scrollbar-width: thin;
}

.onglet {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    flex: 0 0 auto;
    padding: .55rem .85rem;
    margin-bottom: -1px;
    border-bottom: 2px solid transparent;
    color: var(--texte-attenue);
    font-size: .85rem;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
}

.onglet:hover { color: var(--texte); background: var(--surface-attenuee); }

.onglet--actif {
    border-bottom-color: var(--or-fonce);
    color: var(--texte);
    font-weight: 600;
}

/* Le compte se lit sans détourner l'œil du libellé : c'est une
   indication, pas une alerte. */
.onglet__compte {
    padding: .05rem .4rem;
    border-radius: 999px;
    background: var(--gris-100);
    color: var(--texte-attenue);
    font-size: .72rem;
    font-variant-numeric: tabular-nums;
}

.onglet--actif .onglet__compte { color: var(--texte); }

.filtres {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin-bottom: 1.25rem;
}

.filtre {
    padding: .32rem .75rem;
    border: 1px solid var(--bordure-forte);
    border-radius: 999px;
    color: var(--texte-attenue);
    font-size: .8rem;
    font-weight: 500;
    text-decoration: none;
}

.filtre:hover { background: var(--surface-attenuee); color: var(--texte); }

.filtre--actif {
    border-color: var(--or-fonce);
    background: rgba(201, 162, 75, .14);
    color: var(--or-fonce);
}

.filtre__compte {
    margin-left: .3rem;
    opacity: .65;
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------------ */
/*  Grille de cartes de synthèse                                       */
/* ------------------------------------------------------------------ */

.grille-synthese {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: 1rem;
    margin-bottom: 1.5rem;
}

/* Deux tuiles dans une carte : `auto-fit` en étalerait une seule sur
   toute la largeur, et le chiffre unique d'une journée creuse aurait
   l'air d'un titre. */
.grille-synthese--paire {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin-bottom: 1rem;
}

/* Deux cartes côte à côte, qui passent l'une sous l'autre sur un écran
   étroit. Les encaissements et les achats se lisent ensemble : c'est
   l'argent entré et l'argent sorti du même jour. */
.grille-deux-colonnes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(28rem, 1fr));
    gap: 1rem;
    align-items: start;
}

/* Dans la grille, c'est l'écart de la grille qui sépare les cartes : la
   marge de `.carte + .carte` décalait la seconde vers le bas. */
.grille-deux-colonnes > .carte + .carte { margin-top: 0; }

/* Un chiffre qu'on ne connaît pas — pas un zéro. Il se distingue à
   l'œil des montants voisins, sinon le tiret se lit comme une valeur. */
.valeur--indisponible { color: var(--texte-attenue); }

/* Le sélecteur de journée, posé dans l'en-tête d'une carte. */
.barre-filtres--serree {
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
}

.champ--inline {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin: 0;
}

.champ--inline .champ__etiquette { margin: 0; white-space: nowrap; }

.tuile {
    padding: 1rem 1.15rem;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon-large);
    background: var(--surface);
}

.tuile__libelle {
    margin-bottom: .3rem;
    color: var(--texte-attenue);
    font-size: .74rem;
    font-weight: 500;
    letter-spacing: .06em;
    text-transform: uppercase;
}

.tuile__valeur {
    font-family: var(--police-titre);
    font-size: 1.5rem;
    font-weight: 500;
    line-height: 1.1;
}

.tuile__detail {
    margin-top: .2rem;
    color: var(--texte-attenue);
    font-size: .78rem;
}

/* ------------------------------------------------------------------ */
/*  Sections d'une fiche technique                                     */
/* ------------------------------------------------------------------ */

.section-recette + .section-recette { margin-top: 1.5rem; }

.section-recette__titre {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: .5rem;
    color: var(--texte-attenue);
    font-family: var(--police-titre);
    font-size: .74rem;
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
}

.fil-ariane {
    margin-bottom: .75rem;
    color: var(--texte-attenue);
    font-size: .82rem;
}

.fil-ariane a { color: var(--texte-attenue); }
.fil-ariane a:hover { color: var(--noir); }

/* ------------------------------------------------------------------ */
/*  Navigation repliable                                               */
/*                                                                     */
/*  Repliée, la barre ne garde que ses icônes : on récupère près de     */
/*  200 px de largeur pour les tableaux, sans perdre la navigation.     */
/*  Le choix est mémorisé par navigateur.                               */
/* ------------------------------------------------------------------ */

.coquille--nav-repliee { --largeur-nav: 58px; }

.coquille--nav-repliee .nav__nom,
.coquille--nav-repliee .nav__titre-groupe,
.coquille--nav-repliee .nav__libelle,
.coquille--nav-repliee .nav__jalon,
.coquille--nav-repliee .nav__utilisateur,
.coquille--nav-repliee .nav__role,
.coquille--nav-repliee .nav__deconnexion span {
    display: none;
}

.coquille--nav-repliee .nav__marque,
.coquille--nav-repliee .nav__lien,
.coquille--nav-repliee .nav__pied,
.coquille--nav-repliee .nav__deconnexion {
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
}

.coquille--nav-repliee .nav__lien--actif::before { left: 0; }

.nav__bascule {
    display: flex;
    align-items: center;
    gap: .65rem;
    width: 100%;
    padding: .5rem .55rem;
    margin: 0 0 .35rem;
    border: 0;
    border-radius: var(--rayon);
    background: none;
    color: var(--gris-500);
    cursor: pointer;
    font: inherit;
    font-size: .8rem;
    text-align: left;
}

.nav__bascule:hover { background: var(--nav-survol); color: var(--nav-texte-actif); }
.nav__bascule svg { width: 16px; height: 16px; flex: none; }

.coquille--nav-repliee .nav__bascule { justify-content: center; }
.coquille--nav-repliee .nav__bascule svg { transform: rotate(180deg); }

/* ------------------------------------------------------------------ */
/*  Vignettes                                                          */
/*                                                                     */
/*  Un référentiel se parcourt à l'image. Faute de photo, on affiche    */
/*  les initiales sur un fond dérivé du nom : deux articles voisins     */
/*  restent distinguables, et la ligne garde sa hauteur.                */
/* ------------------------------------------------------------------ */

/* UNE SEULE TAILLE, et généreuse.

   Trois tailles supposaient qu'on lit une photo différemment selon
   l'écran. C'est faux : on la lit pour reconnaître un plat, et une
   vignette de 34 pixels ne se reconnaît pas — elle occupe la place
   d'une image sans en rendre le service. Autant n'en pas mettre.

   150 pixels, c'est la taille à laquelle un burger se distingue d'un
   autre burger. La contrepartie est assumée : les lignes de liste
   deviennent hautes, et une liste de deux cents articles se parcourt
   au défilement plutôt que d'un coup d'œil. Le compromis penche du
   côté de la reconnaissance, qui est la raison d'être de l'image. */
.vignette {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 150px;
    height: 150px;
    overflow: hidden;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon-large);
    background: var(--surface-attenuee);
    color: var(--gris-600);
    font-family: var(--police-titre);
    font-size: 2.4rem;
    font-weight: 500;
    letter-spacing: .04em;
    text-transform: uppercase;
    user-select: none;
}

/* 44 px : un repère à côté d'un champ, pas une image qu'on regarde.
   Voir le macro pour la raison de cette seconde taille. */
.vignette--compacte {
    width: 44px;
    height: 44px;
    border-radius: var(--rayon);
    font-size: .95rem;
    letter-spacing: 0;
}

/* La place de la vignette d'une ligne encore vide : sans elle, le
   sélecteur d'une ligne neuve serait décalé de 44 px vers la gauche par
   rapport à ses voisines. */
.vignette--vide {
    border-style: dashed;
    background: transparent;
}

.vignette img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}


/* Cellule « image + libellé », pour que le nom reste lisible à côté. */
.cellule-identite {
    display: flex;
    align-items: center;
    gap: .7rem;
    min-width: 0;
}

/* Le libellé a besoin d'un plancher.

   `min-width: 0` laissait le texte se comprimer jusqu'à se briser mot
   par mot : à côté d'une vignette de 150 pixels, « Burger signature »
   tombait sur deux lignes et le tableau perdait en lisibilité ce que
   l'image lui faisait gagner. */
.cellule-identite__texte { min-width: 9rem; }

/* ------------------------------------------------------------------ */
/*  Recherche                                                          */
/* ------------------------------------------------------------------ */

.barre-recherche {
    display: flex;
    align-items: center;
    gap: .55rem;
    margin-bottom: 1rem;
}

.barre-recherche__champ {
    position: relative;
    flex: 1;
    max-width: 26rem;
}

.barre-recherche__champ svg {
    position: absolute;
    top: 50%;
    left: .7rem;
    width: 16px;
    height: 16px;
    color: var(--gris-400);
    transform: translateY(-50%);
    pointer-events: none;
}

.barre-recherche__champ input {
    width: 100%;
    padding: .55rem .75rem .55rem 2.15rem;
    border: 1px solid var(--bordure-forte);
    border-radius: var(--rayon);
    background: var(--surface);
    color: var(--texte);
    font: inherit;
    font-size: .9rem;
}

.barre-recherche__champ input::placeholder { color: var(--gris-400); }

.barre-recherche__champ input:focus {
    border-color: var(--or-fonce);
    outline: 2px solid rgba(201, 162, 75, .3);
}

.lien-effacer {
    color: var(--texte-attenue);
    font-size: .82rem;
}

/* ------------------------------------------------------------------ */
/*  En-têtes triables                                                  */
/* ------------------------------------------------------------------ */

.entete-tri {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    color: inherit;
    font: inherit;
    text-decoration: none;
    white-space: nowrap;
}

.entete-tri:hover { color: var(--noir); }
.entete-tri--actif { color: var(--or-fonce); }

.entete-tri__fleche {
    font-size: .85em;
    line-height: 1;
}

.tableau__nombre .entete-tri { justify-content: flex-end; }

/* ------------------------------------------------------------------ */
/*  Pagination                                                         */
/* ------------------------------------------------------------------ */

.pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1rem;
    margin-top: 1rem;
}

.pagination__compte {
    color: var(--texte-attenue);
    font-size: .85rem;
}

.pagination__pages {
    display: flex;
    align-items: center;
    gap: .25rem;
}

.page-lien {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2rem;
    height: 2rem;
    padding: 0 .45rem;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    color: var(--texte-attenue);
    font-size: .85rem;
    font-variant-numeric: tabular-nums;
    text-decoration: none;
}

.page-lien:hover { background: var(--surface-attenuee); color: var(--texte); }

.page-lien--actif {
    border-color: var(--noir);
    background: var(--noir);
    color: var(--creme);
    font-weight: 600;
}

.page-lien--inerte { opacity: .35; }
.page-lien--inerte:hover { background: none; }

.page-ellipse {
    padding: 0 .2rem;
    color: var(--gris-400);
}

/* Bandeau d'aide quand une recherche ne donne rien */
.resultat-vide {
    padding: 2.5rem 1rem;
    text-align: center;
}

.resultat-vide__titre {
    margin-bottom: .3rem;
    font-family: var(--police-titre);
    font-size: 1.05rem;
    font-weight: 500;
}

.resultat-vide__detail {
    color: var(--texte-attenue);
    font-size: .88rem;
}

/* ------------------------------------------------------------------ */
/*  Formulaires — compléments du thème Twig                            */
/* ------------------------------------------------------------------ */

.champ__requis { color: var(--erreur); }

.champ--en-erreur .champ__saisie {
    border-color: var(--erreur);
}

.champ__erreurs {
    margin: .4rem 0 0;
    padding: 0;
    list-style: none;
    color: var(--erreur);
    font-size: .82rem;
}

.case-a-cocher {
    display: flex;
    align-items: flex-start;
    gap: .55rem;
    cursor: pointer;
    font-size: .9rem;
    font-weight: 500;
}

.case-a-cocher input[type="checkbox"] {
    width: 1rem;
    height: 1rem;
    margin: .15rem 0 0;
    accent-color: var(--or-fonce);
    flex: none;
}

.champ--case + .champ { margin-top: 1rem; }
.champ__aide--case { margin-left: 1.55rem; }

select.champ__saisie {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2378736b' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-position: right .6rem center;
    background-repeat: no-repeat;
    background-size: 16px;
    padding-right: 2.2rem;
}

.barre-actions {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin-top: 1.75rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--bordure);
}

/* ------------------------------------------------------------------ */
/*  En-tête avec action, colonne d'actions                             */
/* ------------------------------------------------------------------ */

.page__entete--avec-action {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1.5rem;
}

.page__entete--avec-action .bouton { flex: none; }

/* Plusieurs actions dans un en-tête : elles restent groupées à droite au
   lieu de s'étaler sur toute la largeur. */
.barre-actions--entete {
    margin: 0;
    flex: none;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.entete-produit {
    display: flex;
    align-items: center;
    gap: 1.25rem;
}

/* Une pastille qui bascule au clic : elle doit rester une pastille, pas
   devenir un bouton. Seul le curseur trahit qu'elle est actionnable. */
.bascule-pastille {
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    font: inherit;
}

.bascule-pastille:focus-visible {
    outline: 2px solid var(--or);
    outline-offset: 2px;
    border-radius: 999px;
}

.bascule-pastille:hover .pastille { filter: brightness(.94); }

/* Une CELLULE DE TABLEAU, pas un conteneur flex.

   `display: flex` sur un `td` lui retire son statut de cellule : elle
   cesse de s'étirer à la hauteur de sa ligne et se tasse en haut. Tant
   que les lignes faisaient trente pixels, l'écart ne se voyait pas ;
   avec des vignettes de cent cinquante, les boutons flottaient au-dessus
   du reste de la ligne.

   Les enfants s'alignent donc eux-mêmes, en ligne : c'est le
   `vertical-align: middle` de la cellule qui les centre, et il ne
   fonctionne que sur une vraie cellule. */
.colonne-actions {
    text-align: right;
    white-space: nowrap;
}

.colonne-actions > *,
.colonne-actions > form {
    display: inline-block;
    vertical-align: middle;
    margin: 0 0 0 .4rem;
}

.colonne-actions > :first-child { margin-left: 0; }

/* Les écrans qui groupent déjà leurs boutons gardent leur rangée. */
.colonne-actions > .actions-ligne { display: inline-flex; }

.bouton--petit {
    padding: .34rem .7rem;
    font-size: .78rem;
}

/* Le rouge n'apparaît qu'au survol : une colonne d'actions criarde fait
   perdre de vue l'action principale. */
.bouton--danger:hover {
    border-color: var(--erreur);
    background: var(--erreur-fond);
    color: var(--erreur);
}

/* ------------------------------------------------------------------ */
/*  Sections de formulaire                                             */
/* ------------------------------------------------------------------ */

.section-formulaire {
    margin-top: 1.5rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--bordure);
}

.section-formulaire__titre {
    margin: 0 0 .9rem;
    color: var(--texte-attenue);
    font-family: var(--police-titre);
    font-size: .72rem;
    font-weight: 500;
    letter-spacing: .14em;
    text-transform: uppercase;
}

/* ------------------------------------------------------------------ */
/*  Conséquences de la nature                                          */
/* ------------------------------------------------------------------ */

.carte--consequences {
    border-left: 3px solid var(--or);
    background: var(--surface-attenuee);
    box-shadow: none;
}

.consequences {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: .7rem 1.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.consequences li {
    display: flex;
    flex-direction: column;
    gap: .1rem;
    font-size: .88rem;
}

.consequences__cle {
    color: var(--texte-attenue);
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
}

/* ------------------------------------------------------------------ */
/*  Zone de téléversement d'image                                      */
/* ------------------------------------------------------------------ */

/* L'aperçu fait la même taille que les vignettes de liste : le
   formulaire doit montrer ce que l'écran d'à côté affichera. Un aperçu
   plus petit que le rendu laisse découvrir le cadrage après coup. */
.depot-image {
    display: grid;
    grid-template-columns: 150px 1fr;
    gap: 1rem;
    align-items: start;
}

.depot-image__apercu {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 150px;
    height: 150px;
    overflow: hidden;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon-large);
    background: var(--surface-attenuee);
}

.depot-image__apercu img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.depot-image__vide {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: var(--gris-400);
}

.depot-image__vide svg { width: 34px; height: 34px; }

.depot-image__zone {
    padding: 1.1rem 1.25rem;
    border: 1px dashed var(--bordure-forte);
    border-radius: var(--rayon-large);
    background: var(--surface);
    cursor: pointer;
    text-align: center;
    transition: border-color .12s, background .12s;
}

.depot-image__zone:hover {
    border-color: var(--or-fonce);
    background: var(--gris-50);
}

.depot-image__zone--survolee {
    border-color: var(--or-fonce);
    border-style: solid;
    background: rgba(201, 162, 75, .09);
}

.depot-image__invite {
    margin: 0 0 .25rem;
    font-size: .9rem;
}

.depot-image__regles {
    margin: 0;
    color: var(--texte-attenue);
    font-size: .78rem;
}

.depot-image__retour {
    margin: .6rem 0 0;
    font-size: .82rem;
    font-weight: 500;
}

.depot-image__retour--erreur { color: var(--erreur); }
.depot-image__retour--succes { color: var(--succes); }

/* Le champ natif reste dans le flux mais discret : il porte la valeur
   soumise et garde l'accès au clavier. */
.depot-image__champ {
    margin-top: .75rem;
}

.depot-image__champ input[type="file"] {
    width: 100%;
    font-size: .8rem;
    color: var(--texte-attenue);
}

.depot-image__retrait {
    grid-column: 1 / -1;
    margin-top: -.35rem;
}

.depot-image__retrait .champ { margin-top: 0; }

@media (max-width: 620px) {
    .depot-image { grid-template-columns: 1fr; }
    .depot-image__apercu { width: 100%; height: 160px; }
}

/* Filtres d'état : distincts des filtres de nature, on les sépare
   visuellement pour qu'on ne les confonde pas. */
.filtres--etat {
    padding-top: .85rem;
    margin-top: -.5rem;
    border-top: 1px solid var(--bordure);
}

/* ------------------------------------------------------------------ */
/*  Colonne d'actions épinglée                                         */
/*                                                                     */
/*  Sur une grille large, la colonne d'actions sort du cadre et oblige  */
/*  à faire défiler pour chaque ligne. On l'épingle à droite : elle     */
/*  reste atteignable quelle que soit la position horizontale.          */
/* ------------------------------------------------------------------ */

.tableau th:last-child,
.tableau td.colonne-actions {
    position: sticky;
    right: 0;
    z-index: 1;
    background: var(--surface);
    box-shadow: -8px 0 8px -8px rgba(26, 26, 26, .18);
}

.tableau th:last-child { background: var(--gris-50); }
.tableau tbody tr:hover td.colonne-actions { background: var(--gris-50); }


/* ------------------------------------------------------------------ */
/*  Composition d'une fiche technique                                  */
/* ------------------------------------------------------------------ */

.lignes-recette { display: flex; flex-direction: column; gap: .5rem; }

/* Six colonnes sur un plat : composant, quantité, section, indication,
   « le client peut le refuser », et le bouton de retrait. Une
   préparation n'en a que quatre — ni section ni retrait possible. */
.ligne-recette {
    display: grid;
    grid-template-columns:
        minmax(0, 2.4fr)
        minmax(9rem, .9fr)
        minmax(9.5rem, 1fr)
        minmax(0, 1.3fr)
        minmax(6.5rem, .7fr)
        auto;
    gap: .6rem;
    align-items: end;
    padding: .75rem;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    background: var(--gris-50);
}

/* Sans section, la colonne disparait plutot que de laisser un vide. */
.ligne-recette--sans-section {
    grid-template-columns: minmax(0, 2.4fr) minmax(0, .9fr) minmax(0, 1.6fr) auto;
}

.ligne-recette .champ { margin-top: 0; }
.ligne-recette .champ__aide { display: none; }

/* Les étiquettes ne servent que sur la première ligne : les répéter dix
   fois transformerait la composition en mur de texte. */
.ligne-recette:not(:first-child) .champ__etiquette { display: none; }

.ligne-recette__retrait { padding-bottom: .1rem; }

/* Une etape de menu : le produit, la quantite, le retrait. Trois
   colonnes seulement -- un menu ne pese ni section ni indication. */
.etape-menu {
    display: grid;
    grid-template-columns: minmax(0, 3.2fr) minmax(0, .9fr) auto;
    gap: .6rem 1rem;
    align-items: end;
    padding: .7rem .9rem;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    background: var(--gris-50);
}

.etape-menu + .etape-menu { margin-top: .6rem; }
.etape-menu .champ { margin-top: 0; }
.etape-menu .champ__aide { display: none; }
.etape-menu:not(:first-child) .champ__etiquette { display: none; }

/* La case s'aligne sur la ligne de base des champs voisins plutôt que
   sur leur bas : une case à cocher est plus courte qu'une saisie. */
.ligne-recette__retirable { padding-bottom: .5rem; }

/* Chaque cellule occupe toute la hauteur de la ligne et pousse son champ
   en bas. Sans cela, une etiquette qui se replie sur deux lignes decale
   son champ vers le haut et la ligne se lit en escalier. */
.ligne-recette > * {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    min-width: 0;
}

/* La vignette du composant, a cote de son selecteur. Le champ prend
   ce qui reste : sans `min-width: 0`, une grille refuse de reduire un
   element en dessous de son contenu et la ligne deborde. */
.ligne-recette__avec-vignette {
    display: flex;
    align-items: flex-end;
    gap: .5rem;
}

/* La vignette s'aligne sur le champ, pas sur son etiquette : les deux
   bas coincident, et la ligne se lit d'un trait. */
.ligne-recette__avec-vignette .vignette { margin-bottom: 1px; }

.ligne-recette__champ { flex: 1 1 auto; min-width: 0; }

/* L'unite d'usage, collee au champ de quantite. Elle est en lecture
   seule : elle vit sur l'article, pas sur la ligne de recette. */
.ligne-recette__avec-unite {
    display: flex;
    /* `flex-end` et non `baseline` : sur la premiere ligne, seule a
       porter les etiquettes, une ligne de base commune collait l'unite
       au libelle « Quantite nette » au lieu du champ. */
    align-items: flex-end;
    gap: .35rem;
}

.ligne-recette__unite {
    flex: 0 0 auto;
    padding-bottom: .55rem;
    color: var(--texte-attenue);
    font-size: .82rem;
    white-space: nowrap;
}

/* ------------------------------------------------------------------ */
/*  Poids servi                                                        */
/*                                                                     */
/*  Un bandeau sous la fiche, pas une tuile de plus dans le bandeau du */
/*  haut : c'est une conclusion de la recette, elle se lit apres elle. */
/* ------------------------------------------------------------------ */

.poids-servi {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .5rem 1rem;
    padding: .75rem 1rem;
    margin-top: 1rem;
    border-radius: var(--rayon);
    background: var(--gris-50);
}

.poids-servi__libelle {
    color: var(--texte-attenue);
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
}

.poids-servi__valeur {
    font-size: 1.05rem;
    font-variant-numeric: tabular-nums;
}

.poids-servi__note {
    margin-left: auto;
    color: var(--texte-attenue);
    font-size: .78rem;
}

.lignes-recette__vide {
    margin: 0;
    padding: 1.75rem 1rem;
    border: 1px dashed var(--bordure-forte);
    border-radius: var(--rayon);
    color: var(--texte-attenue);
    font-size: .88rem;
    text-align: center;
}

.lignes-recette__actions { margin-top: .85rem; }

/* LA BASCULE SE FAIT A 1400 px, ET NON A 900. Six colonnes editables —
   composant, quantite, section, indication, retirable, retrait — ne
   tiennent pas en dessous : les noms se replient sur trois lignes, la
   ligne monte a 205 pixels et se lit en escalier. Empilee, elle reste
   lisible et chaque champ garde son etiquette.

   Le seuil est mesure, pas devine : a 1500 px la ligne fait 113 px et
   rien ne se tronque ; a 1400 px « Salade iceberg (g) » deborde deja. */
@media (max-width: 1400px) {
    .ligne-recette {
        grid-template-columns: 1fr;
        align-items: stretch;
    }

    .ligne-recette:not(:first-child) .champ__etiquette { display: block; }

    /* Empilee, une cellule n'a plus a pousser son champ en bas : elle
       n'a qu'un champ, et le justifier ferait pendre les etiquettes. */
    .ligne-recette > * { justify-content: flex-start; }

    .ligne-recette__retrait { padding-bottom: 0; }
    .ligne-recette__retirable { padding-bottom: 0; }
}

/* ------------------------------------------------------------------ */
/*  Lignes d'un ticket d'achat                                         */
/*                                                                     */
/*  Meme grammaire visuelle que la composition d'une fiche technique :  */
/*  ce sont deux fois des lignes qu'on ajoute et qu'on retire, et les   */
/*  faire differer ferait croire a deux mecanismes distincts.          */
/* ------------------------------------------------------------------ */

.lignes-achat { display: flex; flex-direction: column; gap: .5rem; }

.ligne-achat {
    display: grid;
    /* Article, quantite, montant, TVA, DLC, retrait. La colonne de TVA
       est la plus etroite : elle porte trois choix, jamais un nombre. La
       DLC prend la place d'une date entiere, jj/mm/aaaa, sans quoi le
       navigateur la rogne et on ne lit plus l'annee. */
    grid-template-columns: minmax(0, 2.2fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, .9fr) minmax(0, 1.2fr) auto;
    gap: .6rem;
    align-items: end;
    padding: .75rem;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    background: var(--gris-50);
}

.ligne-achat .champ { margin-top: 0; }
.ligne-achat .champ__aide { display: none; }
.ligne-achat:not(:first-child) .champ__etiquette { display: none; }
.ligne-achat__retrait { padding-bottom: .1rem; }

/* LA DLC NE SE MONTRE QUE SI LA CATEGORIE L'EXIGE. Une colonne de dates
   offerte sur des sacs de farine se remplit au hasard ou pas du tout, et
   dans les deux cas elle n'apprend rien.

   LA CELLULE GARDE SA PLACE : la ligne est une grille, et la retirer
   decalerait d'un cran les colonnes des lignes voisines — les montants ne
   se liraient plus l'un sous l'autre. */
.ligne-achat__dlc { visibility: hidden; }
.ligne-achat__dlc--exigee { visibility: visible; }

/* L'etiquette n'est montree que sur la premiere ligne. Une DLC exigee sur
   la cinquieme porterait sinon un champ de date sans nom : elle la
   remontre, pour cette ligne-la seulement. */
.ligne-achat__dlc--exigee .champ__etiquette { display: block; }
.ligne-achat__erreurs { grid-column: 1 / -1; }

.lignes-achat__actions { margin-top: .85rem; }

/* La TVA relue avant de valider : une ligne par taux, comme au bas d'une
   facture de grossiste. Elle se lit, elle ne se ressaisit pas. */
.recap-tva {
    margin-top: 1rem;
    padding: .85rem;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    background: var(--gris-50);
}

.recap-tva__titre {
    font-size: .78rem;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--texte-attenue);
    margin-bottom: .5rem;
}

.recap-tva table { margin: 0; }
.recap-tva__total td { border-top: 1px solid var(--bordure); }

/* Une ligne de reception : l'article ne se saisit pas, il se lit. La
   colonne est donc plus large que dans une ligne d'achat, et les
   champs qui restent sont ceux qu'on corrige. */
.ligne-reception {
    display: grid;
    grid-template-columns: minmax(0, 2.4fr) minmax(0, .9fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.4fr);
    gap: .6rem;
    align-items: end;
    padding: .75rem;
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    background: var(--gris-50);
}

.ligne-reception .champ { margin-top: 0; }
.ligne-reception .champ__aide { display: none; }
.ligne-reception:not(:first-child) .champ__etiquette { display: none; }
.ligne-reception__article { align-self: center; }

@media (max-width: 900px) {
    .ligne-reception { grid-template-columns: 1fr; align-items: stretch; }
    .ligne-reception:not(:first-child) .champ__etiquette { display: block; }
}

/* Pieces justificatives dans le journal : des liens de telechargement,
   et un depot pour la facture qui arrive apres la marchandise. */

.formulaire-en-ligne { display: inline; }

/* Le formulaire d'approbation d'une tablette : boutique, code, bouton
   sur une seule ligne. `inline` seul laisserait les champs se replier
   n'importe ou dans la cellule d'actions. */
.formulaire-en-ligne--champs {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
}

.formulaire-en-ligne--champs select,
.formulaire-en-ligne--champs input {
    padding: .3rem .5rem;
    border: 1px solid var(--bordure-forte);
    border-radius: var(--rayon);
    font-size: .85rem;
}

.bouton-lien {
    padding: 0;
    border: 0;
    background: none;
    color: var(--texte-attenue);
    font-family: inherit;
    font-size: .76rem;
    text-decoration: underline;
    cursor: pointer;
}

.bouton-lien--danger:hover { color: var(--erreur); }

.depot-piece { margin-top: .5rem; }

/* L'etiquette EST le bouton : le champ fichier qu'elle enveloppe est
   masque, et le clic lui est transmis par le navigateur. */
.depot-piece label { cursor: pointer; white-space: nowrap; }

/* Le total courant face au total du recu : c'est la ou se voit une
   faute de frappe, tant qu'on a encore le papier en main. */
.achat-total {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    align-items: flex-end;
    justify-content: space-between;
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--bordure);
}

.achat-total__lignes {
    display: flex;
    align-items: baseline;
    gap: .65rem;
}

.achat-total__compte {
    color: var(--texte-attenue);
    font-size: .84rem;
}

.achat-total__somme {
    font-family: var(--police-titre);
    font-size: 1.35rem;
    font-weight: 600;
}

.achat-total__ticket { min-width: 14rem; }
.achat-total__ticket .champ { margin-top: 0; }

@media (max-width: 900px) {
    .ligne-achat { grid-template-columns: 1fr; align-items: stretch; }
    .ligne-achat:not(:first-child) .champ__etiquette { display: block; }
    /* En colonne, une cellule invisible laisse un trou vertical : la
       place qu'on garde sur large ecran n'aligne plus rien ici. */
    .ligne-achat__dlc:not(.ligne-achat__dlc--exigee) { display: none; }
}

.ligne-recette__erreurs {
    grid-column: 1 / -1;
    margin-bottom: .25rem;
}

.ligne-recette__erreurs .champ__erreurs { margin-top: 0; }

/* ------------------------------------------------------------------ */
/*  Recherche de composant (TomSelect)                                 */
/*                                                                     */
/*  On habille le composant plutôt que de le laisser avec son style    */
/*  d'origine : un champ de recherche qui ne ressemble pas aux autres  */
/*  champs du formulaire donne l'impression d'un corps étranger.       */
/* ------------------------------------------------------------------ */

.ts-wrapper {
    min-width: 0;
}

.ts-control {
    padding: .55rem .75rem !important;
    border: 1px solid var(--bordure-forte) !important;
    border-radius: var(--rayon) !important;
    background: var(--surface) !important;
    color: var(--texte);
    font: inherit;
    font-size: .9rem;
}

.ts-wrapper.focus .ts-control {
    border-color: var(--or-fonce) !important;
    outline: 2px solid rgba(201, 162, 75, .3);
}

.ts-control input::placeholder { color: var(--gris-400); }

/* Pendant la frappe, la valeur déjà choisie s'efface : sans cela le champ
   afficherait côte à côte l'ancienne étiquette et la recherche en cours,
   « Structuré inform », qui ne veut rien dire. Elle revient dès qu'on
   choisit, qu'on referme la liste ou qu'on quitte le champ. */
.ts-wrapper.single.ts-frappe .ts-control > .item { display: none; }

.ts-dropdown {
    margin-top: .25rem;
    border: 1px solid var(--bordure-forte);
    border-radius: var(--rayon);
    background: var(--surface);
    box-shadow: var(--ombre-haute);
    font-size: .88rem;
}

.ts-dropdown .optgroup-header {
    padding: .45rem .75rem .25rem;
    color: var(--texte-attenue);
    font-family: var(--police-titre);
    font-size: .68rem;
    font-weight: 500;
    letter-spacing: .12em;
    text-transform: uppercase;
    background: var(--gris-50);
}

.ts-dropdown .option { padding: .45rem .75rem; }
.ts-dropdown .active { background: rgba(201, 162, 75, .16); color: var(--texte); }

.composant-option {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: .75rem;
}

.composant-option__detail {
    flex: none;
    color: var(--texte-attenue);
    font-family: var(--police-mono);
    font-size: .76rem;
}

.composant-chargement,
.ts-dropdown .no-results {
    padding: .6rem .75rem;
    color: var(--texte-attenue);
    font-size: .84rem;
}

/* ------------------------------------------------------------------ */
/*  Écrans de saisie                                                   */
/*                                                                     */
/*  Les formulaires occupent 75 % de la zone de travail : plus étroit   */
/*  qu'une liste, qui vit de sa largeur, mais assez large pour poser    */
/*  deux colonnes de champs et une composition de recette lisible.      */
/* ------------------------------------------------------------------ */

.page--formulaire {
    width: 75%;
    max-width: none;
    padding-left: 0;
    padding-right: 0;
}

/*
 * Répartition en deux colonnes.
 *
 * À cette largeur, un champ par ligne étirerait chaque saisie sur près
 * de 800 px : un nom de vingt caractères dans un champ de huit cents se
 * lit mal, et l'œil parcourt plus de distance pour rien. Les champs
 * courts se rangent donc côte à côte ; ceux qui ont besoin de la
 * largeur — description, zone d'image, composition — la reprennent.
 */
.grille-champs {
    display: grid;
    /* Deux colonnes, jamais trois : au-delà, les champs redeviennent
       étroits et l'ordre de lecture cesse d'être évident — on ne sait
       plus si l'on doit lire en ligne ou en colonne. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    /* L'espacement vertical vient de la grille, pas des marges des champs :
       une marge ne s'applique qu'aux frères SUIVANTS, si bien que le
       premier champ d'une rangée se retrouvait 1 rem plus haut que son
       voisin de droite. */
    gap: 1rem 1.6rem;
}

@media (max-width: 780px) {
    .grille-champs { grid-template-columns: 1fr; }
}

.grille-champs > .champ { margin-top: 0; }

.grille-champs > .pleine-largeur,
.grille-champs > .champ--case {
    grid-column: 1 / -1;
}

@media (max-width: 1100px) {
    .page--formulaire { width: 90%; }
}

@media (max-width: 900px) {
    .page--formulaire { width: 100%; padding-left: 1.25rem; padding-right: 1.25rem; }
}

/* ------------------------------------------------------------------
   Échéancier : une tranche = une question ("qu'est-ce qui sort d'ici
   là"). Le total de la tranche se lit avant le détail, sinon autant
   afficher une liste plate.
   ------------------------------------------------------------------ */
.bloc-tranche { margin-bottom: 1.75rem; }
.bloc-tranche:last-child { margin-bottom: 0; }

.bloc-tranche__titre {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    margin: 0 0 0.6rem;
    font-size: 0.95rem;
    font-weight: 600;
}

.bloc-tranche__total { font-variant-numeric: tabular-nums; }

.bloc-tranche__compte {
    font-weight: 400;
    font-size: 0.82rem;
    color: var(--texte-attenue);
}

/* ------------------------------------------------------------------
   Histogramme d'évolution : douze barres suffisent à voir une tendance
   là où douze lignes de tableau demandent un calcul mental. Pas de
   bibliothèque — le graphique est trop simple pour justifier 90 ko de
   JavaScript, et il doit rester lisible sans script.
   ------------------------------------------------------------------ */
.histogramme {
    display: flex;
    align-items: flex-end;
    gap: 0.5rem;
    height: 190px;
    padding: 0.5rem 0 0;
    overflow-x: auto;
}

.histogramme__colonne {
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    justify-content: flex-end;
    align-items: center;
    gap: 0.35rem;
    min-width: 58px;
    height: 100%;
}

.histogramme__barre {
    width: 100%;
    min-height: 3px;
    background: linear-gradient(180deg, var(--or-clair), var(--or));
    border-radius: var(--rayon) var(--rayon) 0 0;
}

.histogramme__valeur,
.histogramme__etiquette {
    font-size: 0.74rem;
    font-variant-numeric: tabular-nums;
    color: var(--texte-attenue);
    white-space: nowrap;
}

.histogramme__valeur { font-weight: 600; color: var(--texte); }

/* ------------------------------------------------------------------
   Une barre de filtres placée dans l'en-tête d'une page tient sur une
   ligne : à droite d'un titre, l'espace est étroit et le retour à la
   ligne empile les périodes en colonne, où on les lit comme une liste
   d'options plutôt que comme un choix unique.
   ------------------------------------------------------------------ */
.page__entete--avec-action .filtres {
    flex-wrap: nowrap;
    margin-bottom: 0;
}

/* ------------------------------------------------------------------
   Un dépliant : le formulaire d'ajout d'une réponse n'est utile qu'au
   moment où on l'ouvre. Déplié en permanence, il pousse les réponses
   déjà saisies hors de l'écran — or c'est elles qu'on vient relire.
   ------------------------------------------------------------------ */
.depliant {
    margin-top: 1rem;
    padding-top: .85rem;
    border-top: 1px solid var(--bordure);
}

.depliant > summary {
    cursor: pointer;
    font-weight: 600;
    font-size: .88rem;
    color: var(--or-fonce);
}

.depliant[open] > summary { margin-bottom: 1rem; }

/* Un dépliant secondaire, glissé sous une ligne de tableau : il ne doit
   pas peser autant qu'une section. */
.depliant--serre {
    margin-top: .35rem;
    padding-top: .5rem;
}

.depliant--serre > summary { font-size: .82rem; font-weight: 500; }

.ligne-edition > td { padding-top: 0; border-top: 0; }

/* Une imputation se saisit sur la ligne du document : le montant et le
   bouton côte à côte, pour que l'œil n'ait pas à quitter la ligne. */
.ligne-imputation {
    display: flex;
    gap: .4rem;
    align-items: center;
}

.ligne-imputation .champ__saisie { width: 8.5rem; }

/* ------------------------------------------------------------------
   La barre de période des écrans d'argent : les raccourcis d'un côté,
   les dates libres de l'autre, sur une seule ligne tant que la largeur
   le permet.
   ------------------------------------------------------------------ */
.barre-periode {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: 1.1rem;
}

.barre-periode .filtres { margin-bottom: 0; }

.barre-periode__dates {
    display: flex;
    align-items: center;
    gap: .4rem;
}

.barre-periode__dates .champ__saisie { width: auto; }

.barre-periode__etiquette {
    font-size: .82rem;
    color: var(--texte-attenue);
}

/* ------------------------------------------------------------------
   Le classement à la main : deux flèches en tête de ligne, assez
   grandes pour le doigt sur une tablette.
   ------------------------------------------------------------------ */
.colonne-ordre { width: 4.6rem; white-space: nowrap; }

.fleches-ordre { display: inline-flex; gap: .25rem; }

.fleche-ordre {
    width: 1.9rem;
    height: 1.9rem;
    border: 1px solid var(--bordure);
    border-radius: 6px;
    background: var(--surface);
    color: var(--noir);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}

.fleche-ordre:hover:not(:disabled),
.fleche-ordre:focus-visible { background: var(--gris-100); border-color: var(--bordure-forte); }

.fleche-ordre:disabled { opacity: .35; cursor: default; }

/* ------------------------------------------------------------------
   Une ligne de devis : désignation large, puis quantité, prix et TVA.
   La désignation est le champ qu'on relit, elle mérite la place.
   ------------------------------------------------------------------ */
/* La première colonne porte la vignette ET le sélecteur de produit.

   Son minimum tient compte des 150 pixels de l'image : sans cela, le
   sélecteur se réduisait à quatre-vingt-dix pixels et « Burger
   signature » y devenait illisible — l'image aurait gagné en clarté ce
   que le champ perdait. */
.ligne-devis {
    display: grid;
    grid-template-columns:
        minmax(22rem, 3.2fr)
        minmax(11rem, 2.6fr)
        minmax(5.5rem, .9fr)
        minmax(6.5rem, 1.1fr)
        minmax(6rem, .9fr)
        auto;
    gap: .75rem;
    align-items: end;
}

/* L'apercu du logo, avant de l'envoyer sur un document.

   Fond en damier discret : un PNG transparent sur fond blanc a l'air
   d'un PNG opaque, et la difference ne se decouvre qu'a l'impression. */
.apercu-logo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    margin-bottom: 1rem;
    border: 1px solid var(--bordure, #e2e2e2);
    border-radius: .5rem;
    background-image:
        linear-gradient(45deg, #f0f0f0 25%, transparent 25%),
        linear-gradient(-45deg, #f0f0f0 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, #f0f0f0 75%),
        linear-gradient(-45deg, transparent 75%, #f0f0f0 75%);
    background-size: 16px 16px;
    background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}

/* Une HAUTEUR explicite, pas seulement un maximum.

   Un SVG qui ne porte qu'un viewBox n'a pas de taille intrinseque :
   Chrome lui donne 0 et un simple max-height le fait disparaitre. Or
   c'est la forme la plus courante d'un logo exporte par un graphiste. */
.apercu-logo img {
    height: 60px;
    width: auto;
    max-width: 320px;
    object-fit: contain;
}

/* Un palier de frais de livraison : deux nombres et un bouton. */
.ligne-palier {
    display: grid;
    grid-template-columns: 1fr 1fr auto;
    gap: .75rem;
    align-items: end;
}

@media (max-width: 700px) {
    .ligne-palier { grid-template-columns: 1fr 1fr; }
}

/* Les actions au bout d'une ligne de liste : on traite une liste de
   devis en enfilade, et deux clics de navigation par ligne finissent
   par peser. Les boutons restent petits et sur une seule ligne. */
.tableau__actions { white-space: nowrap; width: 1%; }

.actions-ligne {
    display: flex;
    flex-wrap: nowrap;
    gap: .3rem;
    justify-content: flex-end;
}

.actions-ligne form { display: contents; }

/* La ligne d'une facture en cours de retouche. */
.ligne-facture {
    display: grid;
    grid-template-columns: minmax(14rem, 3fr) .9fr 1.1fr .9fr auto;
    gap: .75rem;
    align-items: end;
}

@media (max-width: 900px) {
    .ligne-facture { grid-template-columns: 1fr 1fr; }
    .ligne-facture__designation { grid-column: 1 / -1; }
}

/* Le sous-titre d'une fiche : l'objet, quand le titre porte le
   numéro du document. */
.page__sous-titre {
    margin: .15rem 0 0;
    font-size: 1.02rem;
    color: var(--texte-attenue);
}

/* La vignette du produit, collée à son sélecteur sur la ligne de
   devis : une photo vaut mieux qu'un intitulé pour vérifier d'un
   coup d'œil qu'on a chiffré le bon plat. */
.ligne-devis__avec-vignette {
    display: flex;
    /* Centrée sur le champ plutôt qu'alignée par le bas : à 150 pixels,
       une vignette calée sur la ligne de base du sélecteur laisserait
       un vide de la hauteur de l'image au-dessus. */
    align-items: center;
    gap: .5rem;
    min-width: 0;
}

.ligne-devis__avec-vignette .vignette { flex: 0 0 auto; margin-bottom: 0; }
.ligne-devis__champ-produit { flex: 1 1 auto; min-width: 0; }

/* Les frais de livraison : une ligne du devis comme les autres,
   mais qui ne se chiffre pas de la même façon (§5.9). */
.ligne-devis--livraison { background: var(--gris-50); }
.ligne-devis--livraison .ligne-devis__produit { align-self: center; }

/* La clause de règlement, sur la fiche du devis. */
.clause-reglement {
    border-left: 2px solid var(--or);
    padding: .1rem 0 .1rem .9rem;
    margin-top: 1rem;
}

.clause-reglement__intitule {
    display: block;
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--texte-attenue);
}

.clause-reglement p { margin: .2rem 0 0; }

/* La saisie d'imputation, au bout d'une ligne de tableau : le
   champ et son bouton tiennent côte à côte plutôt que de faire
   grandir la ligne. */
.ligne-imputation {
    display: flex;
    gap: .4rem;
    align-items: center;
}

.ligne-imputation .champ__saisie {
    width: 7rem;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Une tranche de balance âgée qui commence à peser. */
.ligne--alerte { background: var(--gris-100); }
/* Une commande dont le net ne suit pas le taux convenu : à valider ou à
   réclamer. Orange franc, et un trait à gauche qui se voit au défilement. */
.ligne--orange { background: var(--alerte-fond); box-shadow: inset 4px 0 0 var(--alerte); }

/* Les questions posées par un produit à options (§5.3) : elles
   appartiennent à la ligne entière, pas à une colonne. */
.ligne-devis__composition { grid-column: 1 / -1; }
.ligne-devis__composition:empty { display: none; }

.ligne-devis__options {
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
    margin-top: .35rem;
}

.options-groupe {
    flex: 1 1 14rem;
    min-width: 0;
    border: 1px solid var(--bordure);
    border-radius: .5rem;
    padding: .5rem .7rem .6rem;
    margin: 0;
}

.options-groupe__titre {
    display: flex;
    align-items: baseline;
    gap: .45rem;
    padding: 0 .25rem;
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
}

.options-groupe__borne {
    font-weight: 400;
    font-size: .72rem;
    letter-spacing: 0;
    text-transform: none;
    color: var(--texte-attenue);
}

.options-groupe__cases {
    display: flex;
    flex-wrap: wrap;
    gap: .3rem .5rem;
    margin-top: .35rem;
}

.option-case {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .2rem .5rem .2rem .35rem;
    border: 1px solid transparent;
    border-radius: 1rem;
    cursor: pointer;
    font-size: .85rem;
}

.option-case:hover { background: var(--gris-100); }

.option-case:has(input:checked) {
    border-color: var(--or);
    background: var(--creme);
}

.option-case input { margin: 0; }

.option-case__supplement {
    font-variant-numeric: tabular-nums;
    font-size: .78rem;
    color: var(--texte-attenue);
    white-space: nowrap;
}

.option-case__supplement--remise { color: var(--succes); }

/* La composition retenue, telle qu'elle figure sur le document. */
.composition-figee {
    margin: .3rem 0 0;
    padding: 0;
    list-style: none;
    font-size: .82rem;
    color: var(--texte-attenue);
}

.composition-figee li { padding: .05rem 0; }

.composition-figee__groupe::after {
    content: ' :';
}

.composition-figee__supplement {
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.tableau__appoint {
    display: block;
    font-size: .75rem;
    font-weight: 400;
    color: var(--texte-attenue);
    white-space: nowrap;
}

/* La rangée en six colonnes ne tient qu'à partir de 1 600 pixels.

   Le chiffre est MESURÉ, pas estimé : à 1 300 la rangée déborde de
   225 pixels, à 1 400 de 150, à 1 500 de 75, et à 1 600 de zéro. La
   vignette de 150 pixels y est pour beaucoup — la colonne du produit
   réclame 352 pixels pour que « Burger signature » reste lisible dans
   son sélecteur.

   En dessous, on empile plutôt que de déborder : un devis se saisit en
   lisant les montants, et un montant coupé à mi-chiffre ne se lit pas. */
@media (max-width: 1599px) {
    .ligne-devis { grid-template-columns: 1fr 1fr; }
    .ligne-devis__produit,
    .ligne-devis__designation { grid-column: 1 / -1; }
    .options-groupe { flex-basis: 100%; }
}

/* LA FACTURE SE SAISIT LE DOCUMENT SOUS LES YEUX. Le PDF à gauche,
   l'en-tête à droite : on lit un chiffre, on le tape, sans changer de
   fenêtre. En dessous de 1 100 pixels, le document passe au-dessus —
   côte à côte, ni l'un ni l'autre ne se lirait. */
.facture-saisie {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    gap: 1rem;
    align-items: start;
}

.facture-saisie__apercu iframe,
.facture-saisie__apercu img {
    display: block;
    width: 100%;
    border: 1px solid var(--bordure);
    border-radius: .5rem;
    background: #fff;
}

.facture-saisie__apercu iframe { height: 75vh; }
.facture-saisie__apercu img { max-height: 75vh; object-fit: contain; }

@media (max-width: 1099px) {
    .facture-saisie { grid-template-columns: 1fr; }
    .facture-saisie__apercu iframe { height: 60vh; }
}


/* L'heure des chiffres affichés, et de quoi les redemander. Discrète :
   elle répond à « est-ce à jour ? », elle ne doit pas le crier. */
.barre-rafraichissement {
    display: flex;
    gap: .75rem;
    align-items: baseline;
    justify-content: flex-end;
    margin: 0 0 .75rem;
}

.carte__sous-titre {
    margin: 1.25rem 0 .5rem;
    font-size: .95rem;
    font-weight: 600;
}

/* ------------------------------------------------------------------
   Une action qui demande une précision avant de partir — un motif
   d'annulation : un bouton qui déplie son petit formulaire sur place.
   ------------------------------------------------------------------ */
.action-repliee > summary { list-style: none; cursor: pointer; }
.action-repliee > summary::-webkit-details-marker { display: none; }

.action-repliee[open] > form {
    display: grid;
    gap: .4rem;
    margin-top: .5rem;
    min-width: 18rem;
    white-space: normal;
    text-align: left;
}

/* L'arrondi du total d'un devis : une ligne, sous les tuiles. */
.barre-arrondi {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem;
}

.barre-arrondi .champ__saisie { width: 8rem; }
.barre-arrondi .champ__aide { flex-basis: 100%; margin: 0; }

/* ------------------------------------------------------------------
   Les graphiques du tableau de bord : une courbe or pour ce qui s'est
   passé, une courbe grise pour l'habitude. La donnée seule est voyante ;
   grille, graduations et légende restent en retrait.
   ------------------------------------------------------------------ */
.graphique__legende {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem 1.2rem;
    margin-bottom: .6rem;
    font-size: .8rem;
    color: var(--texte-attenue);
}

.graphique__legende > span { display: inline-flex; align-items: center; gap: .4rem; }


.graphique__cle-ligne {
    display: inline-block;
    width: 14px;
    height: 2px;
    border-radius: 1px;
    background: #78736b;
}

.graphique__cle-ligne--serie { background: #b8902f; }

.graphique__cadre { position: relative; }

.graphique__trace { width: 100%; min-height: 220px; }
.graphique__trace svg { display: block; max-width: 100%; height: auto; }

.graphique__graduation {
    font-size: 11px;
    fill: var(--texte-attenue);
    font-variant-numeric: tabular-nums;
}

.graphique__zone { cursor: default; outline: none; }
.graphique__zone:focus-visible { stroke: var(--bordure-forte); stroke-width: 1; }

.graphique__infobulle {
    position: absolute;
    top: 0;
    min-width: 11rem;
    padding: .5rem .65rem;
    background: var(--surface);
    border: 1px solid var(--bordure);
    border-radius: var(--rayon);
    box-shadow: var(--ombre-haute);
    font-size: .8rem;
    pointer-events: none;
    z-index: 2;
}

.graphique__infobulle-titre { color: var(--texte-attenue); margin-bottom: .25rem; }

.graphique__infobulle-ligne {
    display: grid;
    grid-template-columns: 14px auto 1fr;
    align-items: center;
    gap: .45rem;
}

.graphique__infobulle-ligne strong { color: var(--texte); font-variant-numeric: tabular-nums; }
.graphique__infobulle-ligne span:last-child { color: var(--texte-attenue); }

.graphique__chiffres { margin-top: .6rem; font-size: .85rem; }
.graphique__chiffres > summary { cursor: pointer; color: var(--texte-attenue); }

/* Ticket programmé : la photo du plat à côté de son choix (19/10/2026). */
.ligne-plat {
    display: flex;
    align-items: center;
    gap: .5rem;
}
.ligne-plat select { flex: 1; min-width: 0; }
