/*
 * Freezer — feuille de style applicative.
 *
 * Parti pris visuel : un écran de gestion, pas une page web. La référence
 * assumée est SAP GUI — densité maximale, quadrillage complet, angles droits,
 * aucune ombre. Chaque pixel sert à afficher une donnée ou à séparer deux
 * données.
 *
 * Conséquences concrètes de ce choix :
 *   - `border-radius: 0` partout. Un coin arrondi coûte de la place et
 *     n'apporte aucune information.
 *   - Lignes de tableau à 22 px, texte à 12 px : on veut voir trente lignes
 *     d'un coup, pas huit.
 *   - Bordures sur toutes les cellules. Dans un tableau dense, l'œil suit la
 *     grille ; sans elle, il saute de ligne.
 *   - La couleur ne décore pas : bleu = colonne clé, or = ligne sélectionnée,
 *     rouge/orange/vert = état. Rien d'autre n'est coloré.
 *
 * Thème clair uniquement, volontairement. Un écran de gestion se consulte à
 * longueur de journée sur le même poste : suivre le thème du système ferait
 * changer l apparence de l outil au gré de l heure, sans rien apporter.
 *
 * Écrite à la main, sans build (voir docs/REFONTE.md §6).
 *
 * Sommaire
 *   1. Variables
 *   2. Base
 *   3. Coque (bandeau, arborescence, barre d'état)
 *   4. Barre de titre et barre d'outils
 *   5. Tableaux
 *   6. Blocs de sélection et champs
 *   7. Indicateurs et messages
 *   8. Connexion
 *   9. Responsive
 */

/* ------------------------------------------------------------------ */
/* 1. Variables                                                       */
/* ------------------------------------------------------------------ */

:root {
    /* Interdit au navigateur d'assombrir la page de lui-même.

       Chrome et Edge, quand le systeme est en thème sombre, inversent
       automatiquement les couleurs des pages qui ne déclarent pas le thème
       qu'elles supportent. Sans cette ligne, la feuille reste claire mais
       l'affichage, lui, sort en sombre — et rien dans le CSS ne permet de
       comprendre pourquoi. */
    color-scheme: light;

    /* Palette claire, calquée sur SAP GUI : des gris très pâles, du cyan
       clair pour les colonnes d'identification, du jaune crème pour la ligne
       active. Les contrastes forts sont réservés au texte et aux états —
       le reste doit s'effacer derrière les données. */
    --shell: #eceff3;          /* bandeau applicatif, gris clair */
    --shell-text: #1c2530;

    --bg: #eef1f4;             /* fond de travail */
    --surface: #ffffff;
    --panel: #f2f4f7;          /* blocs de sélection, barres d'outils */

    --grid: #d5dae1;           /* filets du quadrillage */
    --border: #c3c9d2;         /* contours de zones */

    --header-top: #fbfcfd;     /* en-tête de bloc et de boîte de dialogue */
    --header-bottom: #e9edf2;

    --table-header-top: #c7d0db;    /* en-tête de colonne de tableau, plus soutenu */
    --table-header-bottom: #aebac6;

    --key-col: #dcedf7;        /* colonne clé, cyan pâle */
    --row-alt: #f2f4f7;
    --row-hover: #eaf4fb;
    --row-select: #fff2cc;     /* ligne active, jaune crème */

    --text: #1a1f26;
    --text-soft: #5a6470;
    --text-faint: #8b95a1;

    --accent: #0a6ed1;
    --accent-bg: #e2eefb;

    --ok: #14672f;
    --ok-bg: #e6f4ea;
    --warning: #8a5300;
    --warning-bg: #fdf3dc;
    --danger: #9d1c14;
    --danger-bg: #fdeae8;

    --row-h: 24px;
}

/* ------------------------------------------------------------------ */
/* 2. Base                                                            */
/* ------------------------------------------------------------------ */

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

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

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: "Segoe UI", Tahoma, Arial, "Helvetica Neue", sans-serif;
    font-size: 13px;
    line-height: 1.4;
}

h1, h2, h3 { margin: 0; font-weight: 700; }
h1 { font-size: 14px; }
h2 { font-size: 13px; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

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

@media (prefers-reduced-motion: reduce) {
    * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ------------------------------------------------------------------ */
/* 3. Coque                                                           */
/* ------------------------------------------------------------------ */

.shell {
    display: grid;
    grid-template-rows: auto 1fr auto;
    grid-template-columns: 210px 1fr;
    grid-template-areas:
        "header header"
        "nav    main"
        "status status";
    min-height: 100vh;
}

.shell-header {
    grid-area: header;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    height: 28px;
    padding: 0 10px;
    background: var(--shell);
    color: var(--shell-text);
    border-bottom: 1px solid var(--border);
    font-size: 12px;
    font-weight: 600;
}

.shell-header a { color: var(--shell-text); }

.shell-header-right {
    display: flex;
    align-items: center;
    gap: 10px;
    font-weight: 400;
}

/* Bouton hamburger : masqué sur poste de travail, où l'arborescence tient
   déjà en colonne fixe. Voir la media query mobile plus bas. */
.nav-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 22px;
    padding: 0;
    border: 1px solid var(--border);
    background: var(--panel);
    color: var(--shell-text);
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
}

.shell-title-short { display: none; }

.nav {
    grid-area: nav;
    background: var(--surface);
    border-right: 1px solid var(--border);
    padding: 4px 0;
    overflow-y: auto;
}

.nav-group {
    padding: 6px 8px 3px;
    font-size: 12px;
    font-weight: 700;
    color: var(--text-faint);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.nav a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    padding: 3px 8px 3px 16px;
    color: var(--text);
    border-left: 3px solid transparent;
}

.nav a:hover { background: var(--row-hover); text-decoration: none; }

.nav a.is-active {
    background: var(--accent-bg);
    border-left-color: var(--accent);
    font-weight: 700;
}

.nav-count {
    min-width: 18px;
    padding: 0 4px;
    background: var(--danger);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.main {
    grid-area: main;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.statusbar {
    grid-area: status;
    display: flex;
    gap: 16px;
    align-items: center;
    height: 24px;
    padding: 0 10px;
    background: var(--panel);
    border-top: 1px solid var(--border);
    font-size: 12px;
    color: var(--text-soft);
}

.statusbar strong { color: var(--text); }

/* ------------------------------------------------------------------ */
/* 4. Barre de titre et barre d'outils                                */
/* ------------------------------------------------------------------ */

.screen-title {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    background: linear-gradient(var(--header-top), var(--header-bottom));
    border-bottom: 1px solid var(--border);
    font-size: 14px;
    font-weight: 700;
}

.toolbar {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
    padding: 3px 6px;
    background: var(--panel);
    border-bottom: 1px solid var(--border);
}

.toolbar-sep {
    width: 1px;
    height: 18px;
    background: var(--grid);
    margin: 0 3px;
}

.toolbar-info {
    margin-left: auto;
    font-size: 12px;
    color: var(--text-soft);
    font-variant-numeric: tabular-nums;
}

.work {
    flex: 1;
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

/* ------------------------------------------------------------------ */
/* 5. Tableaux                                                        */
/* ------------------------------------------------------------------ */

.grid-wrap {
    background: var(--surface);
    border: 1px solid var(--border);
    overflow-x: auto;
}

table.grid {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}

table.grid th,
table.grid td {
    height: var(--row-h);
    padding: 2px 9px;
    border-right: 1px solid var(--grid);
    border-bottom: 1px solid var(--grid);
    text-align: left;
    white-space: nowrap;
    vertical-align: middle;
}

table.grid th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: linear-gradient(var(--table-header-top), var(--table-header-bottom));
    border-bottom: 1px solid var(--border);
    font-weight: 700;
    font-size: 12px;
    color: var(--text);
}

table.grid th a {
    color: inherit;
    display: block;
}

table.grid th a::after {
    content: " ⇅";
    color: var(--text-faint);
    font-size: 11px;
}

table.grid th a.sorted-asc::after { content: " ▲"; color: var(--accent); }
table.grid th a.sorted-desc::after { content: " ▼"; color: var(--accent); }

table.grid tbody tr:nth-child(even) { background: var(--row-alt); }
table.grid tbody tr:hover { background: var(--row-hover); }

/* La ligne cliquée reste marquée : dans un tableau dense, on perd sa place
   dès qu'on quitte l'écran des yeux. */
table.grid tbody tr.is-selected,
table.grid tbody tr:focus-within { background: var(--row-select); }

/* Ligne dont la saisie est terminée (ex. réception intégralement reçue) :
   verte et non cliquable, pour qu'elle se distingue au premier coup d'œil
   des lignes qui attendent encore une saisie. */
table.grid tbody tr.row-done,
table.grid tbody tr.row-done:hover { background: var(--ok-bg); }
table.grid tbody tr.row-done .col-key { background: var(--ok-bg); }

/* Colonne clé : celle par laquelle on identifie la ligne. */
table.grid .col-key {
    font-weight: 600;
}

table.grid .col-key a { color: inherit; }

table.grid tbody tr:hover .col-key { background: var(--row-hover); }
table.grid tbody tr.is-selected .col-key,
table.grid tbody tr:focus-within .col-key { background: var(--row-select); }

.num { text-align: right; }
.wrap { white-space: normal; }
.sub { color: var(--text-soft); }

.grid-empty {
    padding: 24px 8px;
    text-align: center;
    color: var(--text-soft);
    background: var(--surface);
}

/* ------------------------------------------------------------------ */
/* 6. Blocs de sélection et champs                                    */
/* ------------------------------------------------------------------ */

.block {
    background: var(--surface);
    border: 1px solid var(--border);
}

.block-title {
    padding: 2px 6px;
    background: linear-gradient(var(--header-top), var(--header-bottom));
    border-bottom: 1px solid var(--border);
    font-size: 12px;
    font-weight: 700;
}

.block-body { padding: 6px; }

/* Un en-tête plus sombre par congélateur, pour repérer le changement sans
   relire le titre : le quadrillage seul ne marque pas assez la coupure
   entre deux tableaux qui se suivent. */
.block-freezer .block-title {
    background: linear-gradient(var(--table-header-top), var(--table-header-bottom));
}

/* Grille étiquette / champ, comme un écran de sélection. */
.fields {
    display: grid;
    /* `minmax(0, 1fr)` et non `1fr` : un élément de grille a `min-width: auto`
       par défaut, ce qui l'empêche de descendre sous la largeur de son
       contenu. Une valeur longue et insécable — une URL, un code-barres —
       refusait donc de rétrécir et débordait par-dessus la colonne voisine. */
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 4px 14px;
    align-items: center;
}

.field {
    display: grid;
    grid-template-columns: 100px minmax(0, 1fr);
    align-items: center;
    gap: 6px;
    min-width: 0;
}

.field > label {
    font-size: 12px;
    color: var(--text-soft);
    text-align: right;
}

/* Un champ qui occupe toute la largeur : pour ce qu'on lit d'un bloc ou
   qu'on recopie — une adresse, un jeton. Le couper en deux le rendrait
   pénible à sélectionner. */
.field-wide {
    grid-column: 1 / -1;
    grid-template-columns: 100px minmax(0, 1fr);
}

/* La valeur d'un champ se casse plutôt que de déborder : mieux vaut une URL
   sur deux lignes qu'une URL par-dessus le champ d'à côté. */
.field > :not(label) {
    min-width: 0;
    overflow-wrap: anywhere;
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="number"],
input[type="date"],
input[type="search"],
select {
    width: 100%;
    height: 23px;
    padding: 0 6px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: 13px;
}

input:focus, select:focus { border-color: var(--accent); }

input:disabled, select:disabled {
    background: var(--panel);
    color: var(--text-faint);
    border-color: var(--grid);
}

/* Numéro d'article saisi sans produit correspondant. */
input.input-error {
    border-color: var(--danger);
    background: var(--danger-bg);
}

.btn {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    gap: 4px;
    height: 24px;
    padding: 0 10px;
    border: 1px solid var(--border);
    background: linear-gradient(var(--surface), var(--panel));
    color: var(--text);
    font: inherit;
    font-size: 13px;
    white-space: nowrap;
    overflow-wrap: normal;
    cursor: pointer;
}

.btn:hover { background: var(--row-hover); text-decoration: none; }
.btn:active { background: var(--panel); }

.btn-primary {
    background: linear-gradient(#1a7fdf, #0a6ed1);
    border-color: #0a5aa0;
    color: #fff;
    font-weight: 600;
}

.btn-primary:hover { background: #0d63ad; }

/* ------------------------------------------------------------------ */
/* 7. Indicateurs et messages                                         */
/* ------------------------------------------------------------------ */

/* Bandeau de chiffres clés : une grille dense, pas des tuiles. */
.figures {
    display: flex;
    flex-wrap: wrap;
    background: var(--surface);
    border: 1px solid var(--border);
}

.figure {
    flex: 1 1 130px;
    padding: 3px 8px;
    border-right: 1px solid var(--grid);
}

.figure:last-child { border-right: none; }

.figure-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-faint);
}

.figure-value {
    font-size: 18px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.figure-warning .figure-value { color: var(--warning); }
.figure-danger .figure-value { color: var(--danger); }

/* Un état se lit à la pastille autant qu'à la couleur : la teinte seule ne
   suffit pas pour qui la distingue mal. */
.status {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 0 5px;
    font-size: 12px;
    font-weight: 600;
    border: 1px solid;
}

.status::before {
    content: "";
    width: 7px;
    height: 7px;
    display: inline-block;
}

.status-ok { color: var(--ok); background: var(--ok-bg); border-color: var(--ok); }
.status-ok::before { background: var(--ok); }

.status-warning { color: var(--warning); background: var(--warning-bg); border-color: var(--warning); }
.status-warning::before { background: var(--warning); }

.status-danger { color: var(--danger); background: var(--danger-bg); border-color: var(--danger); }
.status-danger::before { background: var(--danger); }

.status-neutral { color: var(--text-soft); background: var(--panel); border-color: var(--grid); }
.status-neutral::before { background: var(--text-faint); }

.message {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 3px 8px;
    border: 1px solid;
    font-size: 12px;
}

.message-ok { color: var(--ok); background: var(--ok-bg); border-color: var(--ok); }
.message-warning { color: var(--warning); background: var(--warning-bg); border-color: var(--warning); }
.message-danger { color: var(--danger); background: var(--danger-bg); border-color: var(--danger); }

.pager {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 3px 6px;
    background: var(--panel);
    border: 1px solid var(--border);
    border-top: none;
    font-size: 12px;
}

.pager a,
.pager span.disabled {
    padding: 1px 7px;
    border: 1px solid var(--border);
    background: var(--surface);
}

.pager span.disabled { color: var(--text-faint); }
.pager .pager-info { margin-left: auto; color: var(--text-soft); border: none; background: none; }

/* QR de configuration d'appareil : le SVG n'a qu'un viewBox, pas de largeur
   ni de hauteur propres, pour ne pas fixer sa taille indépendamment de son
   conteneur — sans cette règle, un navigateur lui donnerait une taille par
   défaut qui ignorerait la boîte qui l'entoure. */
.qr-svg { width: 100%; height: 100%; display: block; }

/* ------------------------------------------------------------------ */
/* 8. Connexion                                                       */
/* ------------------------------------------------------------------ */

.logon {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    background: var(--bg);
}

.logon-box {
    width: 100%;
    max-width: 340px;
    border: 1px solid var(--border);
    background: var(--surface);
}

.logon-title {
    padding: 4px 8px;
    background: linear-gradient(var(--header-top), var(--header-bottom));
    color: var(--text);
    border-bottom: 1px solid var(--border);
    font-size: 12px;
    font-weight: 700;
}

.logon-body { padding: 12px; }

.logon-body .field { grid-template-columns: 100px 1fr; margin-bottom: 8px; }

/* ------------------------------------------------------------------ */
/* 9. Responsive                                                      */
/* ------------------------------------------------------------------ */

@media (max-width: 820px) {
    .shell {
        grid-template-columns: 1fr;
        grid-template-areas:
            "header"
            "main"
            "status";
    }

    .nav-toggle { display: inline-flex; }
    .shell-title-full { display: none; }
    .shell-title-short { display: inline; }

    /* L'arborescence occupait une ligne entière de l'écran en permanence,
       avant même d'atteindre le contenu : sur téléphone elle se replie
       derrière le bouton hamburger, en panneau superposé plutôt qu'en
       ligne de la grille. */
    .nav {
        position: fixed;
        top: 28px;
        left: 0;
        right: 0;
        z-index: 20;
        max-height: calc(100vh - 28px);
        overflow-y: auto;
        border-right: none;
        border-bottom: 1px solid var(--border);
        display: none;
        flex-wrap: wrap;
    }

    .nav.is-open { display: flex; }

    /* Liste verticale plutôt que chips côte à côte : un panneau qu'on ouvre
       exprès se consulte comme un menu, pas comme une barre à parcourir du
       regard. Cible tactile de 44px, suivant la préconisation d'Apple. */
    .nav-group { width: 100%; }
    .nav a {
        width: 100%;
        min-height: 44px;
        border-left: none;
        border-bottom: 1px solid var(--grid);
        padding-left: 16px;
    }
    .nav a.is-active { border-left: 3px solid var(--accent); padding-left: 13px; }

    .field { grid-template-columns: 1fr; }
    .field > label { text-align: left; }

    /* Le quadrillage tient encore sur téléphone en défilement horizontal :
       transformer le tableau en fiches ferait perdre la comparaison ligne à
       ligne, qui est tout l'intérêt de cet écran. */
    .grid-wrap { overflow-x: auto; }
    table.grid { min-width: 720px; }

    /* Boutons de navigation et de la boite de saisie manuelle du scan :
       cible tactile 44px seulement sur petit ecran. Sur poste de travail,
       ils gardent la taille standard du reste du site. */
    .scan-mobile-btn { height: 44px; padding: 0 18px; font-size: 15px; }
}

/* ------------------------------------------------------------------ */
/* 10. Sélection de ligne et boîtes de dialogue                       */
/* ------------------------------------------------------------------ */

table.grid tbody tr[data-selectable] { cursor: pointer; }

/* Un bouton qui n'a pas de ligne sur quoi agir se désactive plutôt que
   d'échouer une fois cliqué. */
.btn[disabled] {
    color: var(--text-faint);
    background: var(--panel);
    cursor: not-allowed;
}

dialog {
    padding: 0;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    width: min(380px, 92vw);
    box-shadow: 0 4px 20px rgba(20, 28, 38, .25);
}

dialog::backdrop { background: rgba(20, 28, 38, .35); }

.dialog-title {
    padding: 5px 10px;
    background: linear-gradient(var(--header-top), var(--header-bottom));
    border-bottom: 1px solid var(--border);
    font-size: 13px;
    font-weight: 700;
}

.dialog-body { padding: 12px; }

.dialog-body .field { margin-bottom: 10px; }

.dialog-body .field:last-child { margin-bottom: 0; }

.dialog-actions {
    display: flex;
    justify-content: flex-end;
    gap: 6px;
    padding: 8px 10px;
    background: var(--panel);
    border-top: 1px solid var(--border);
}

/* Tiroir d'historique : replié, seule sa barre dépasse au bas de l'écran ;
   ouvert, il remonte par-dessus la page plutôt que d'allonger le
   défilement d'une consultation secondaire. `position: fixed` + un
   `translateY` de la hauteur du tiroir moins celle de la barre : au repos,
   seule la barre reste dans le cadre visible. */
.history-drawer {
    position: fixed;
    left: 210px;
    right: 0;
    bottom: 24px;
    z-index: 5;
    display: flex;
    flex-direction: column;
    height: 70vh;
    max-height: calc(100vh - 24px - 28px);
    background: var(--surface);
    border-top: 1px solid var(--border);
    box-shadow: 0 -2px 10px rgba(20, 28, 38, .15);
    transform: translateY(calc(100% - 27px));
    transition: transform .18s ease;
}

.history-drawer.is-open { transform: translateY(0); }

.history-bar {
    flex: 0 0 26px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    height: 26px;
    padding: 0 8px;
    background: linear-gradient(var(--header-top), var(--header-bottom));
    border-bottom: 1px solid var(--border);
    font-size: 12px;
    font-weight: 700;
    color: var(--text);
    text-align: left;
    cursor: pointer;
}

.history-bar:hover { background: var(--row-hover); }

.history-bar::after {
    content: "▲";
    color: var(--text-faint);
    font-size: 10px;
    font-weight: 400;
    transition: transform .18s ease;
}

.history-drawer.is-open .history-bar::after { transform: rotate(180deg); }

.history-body {
    flex: 1;
    overflow-y: auto;
}

@media (max-width: 820px) {
    .history-drawer { left: 0; }
}

/* Écran de consommation au scan : pensé pour un usage à une main sur
   téléphone, devant le congélateur. Le reste de l'application vise la
   densité d'un poste de travail ; ici la cible tactile prime — 44px suit
   la préconisation d'Apple, et 16px de corps évite qu'iOS ne zoome sur le
   champ à la prise de focus. */
input.scan-consume-code {
    width: 100%;
    height: 44px;
    padding: 0 10px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: 16px;
}

input.scan-consume-code:focus { border-color: var(--accent); }

.scan-consume-btn {
    height: 44px;
    padding: 0 18px;
    font-size: 15px;
}

/* Un lot par carte, quantité centrée au milieu de l'écran plutôt que
   collée à droite dans une grille : c'est le seul champ que le pouce doit
   trouver sans viser, le reste ne fait que l'expliquer. */
.scan-consume-lot {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 10px 0;
    border-bottom: 1px solid var(--grid);
    text-align: center;
}

.scan-consume-lot:first-child { padding-top: 0; }
.scan-consume-lot:last-child { border-bottom: none; }

input.scan-consume-qty {
    width: 120px;
    text-align: center;
    font-size: 22px;
    font-weight: 700;
}

/* Éléments de l'écran de scan, communs au poste de travail et au
   téléphone. Ce sont les anciens styles en ligne de la vue, sortis ici
   pour que le mode application puisse les surcharger. */
.scan-code-form { display: flex; gap: 6px; }
.scan-code-form .scan-consume-code { flex: 1; }

.scan-camera-btn { display: none; }

.scan-candidates { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; }
.scan-candidate { display: flex; justify-content: space-between; align-items: center; gap: 8px; }

.scan-choices { display: flex; flex-wrap: wrap; gap: 6px; }
.scan-choice-qty::before { content: "— "; }

.scan-back { margin-bottom: 8px; }

.scan-qty { display: flex; align-items: center; gap: 6px; }
.scan-qty-step { width: 44px; justify-content: center; padding: 0; font-size: 20px; font-weight: 700; }

.scan-reasons { display: flex; flex-wrap: wrap; gap: 6px; }

.scan-consume-actions { margin-top: 10px; }

.scan-appbar-title { display: none; }

/* Boîte de scan : un <details> pour pouvoir la replier sur téléphone. Sur
   poste de travail, rien ne la distingue d'un bloc ordinaire (pas de
   marqueur, titre non cliquable, 📷 du titre masqué). */
.scan-box-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    list-style: none;
}

.scan-box-title::-webkit-details-marker { display: none; }
.scan-box-camera { display: none; }

/* Calque caméra, plein écran, au-dessus de tout. */
.camera-overlay {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    flex-direction: column;
    background: #000;
    color: #fff;
}

.camera-overlay[hidden] { display: none; }

.camera-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 12px;
    padding-top: max(8px, env(safe-area-inset-top));
    background: linear-gradient(var(--header-top), var(--header-bottom));
    border-bottom: 1px solid var(--border);
    color: var(--text);
    font-size: 15px;
    font-weight: 700;
}

.camera-view { flex: 1; min-height: 0; position: relative; overflow: hidden; display: flex; align-items: center; background: #000; }
.camera-view video { display: block; }

.camera-hint {
    padding: 10px 12px;
    padding-bottom: max(10px, env(safe-area-inset-bottom));
    font-size: 14px;
    text-align: center;
}

.camera-hint:empty { display: none; }

/* ------------------------------------------------------------------ */
/* Mode application (téléphone)                                       */
/* ------------------------------------------------------------------ */

/* Écrans déclarés `mobileApp` (layout) sur petit écran : ils se
   présentent comme une application de téléphone, notamment une fois
   ajoutés à l'écran d'accueil de l'iPhone. On garde l'identité SAP (angles
   droits, filets, dégradés d'en-tête, bleu d'action) et on retire tout ce
   qui ne sert pas à un geste d'une seule main devant le congélateur : le
   bandeau, l'arborescence, le titre avec code transaction et la barre
   d'état. La page passe sous l'encoche (viewport-fit=cover) ; les marges
   env(safe-area-inset-*) la ramènent dans la zone visible. */
@media (max-width: 820px) {
    .is-mobile-app .shell {
        grid-template-rows: 1fr;
        grid-template-areas: "main";
        min-height: 100vh;
        min-height: 100dvh;
    }

    .is-mobile-app .shell-header,
    .is-mobile-app .nav,
    .is-mobile-app .screen-title,
    .is-mobile-app .statusbar { display: none; }

    /* Barre d'application : retour à gauche, titre au centre. Collée en
       haut pour que le retour reste accessible pendant le défilement. */
    .is-mobile-app .scan-appbar {
        position: sticky;
        top: 0;
        z-index: 10;
        flex-wrap: nowrap;
        gap: 8px;
        padding: 6px 10px;
        padding-top: max(6px, env(safe-area-inset-top));
        padding-left: max(10px, env(safe-area-inset-left));
        padding-right: max(10px, env(safe-area-inset-right));
        background: linear-gradient(var(--header-top), var(--header-bottom));
    }

    .is-mobile-app .scan-appbar .toolbar-info { display: none; }

    .is-mobile-app .scan-appbar-title {
        display: block;
        flex: 1;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-size: 17px;
        font-weight: 700;
    }

    .is-mobile-app .work {
        gap: 10px;
        padding: 10px;
        padding-left: max(10px, env(safe-area-inset-left));
        padding-right: max(10px, env(safe-area-inset-right));
        padding-bottom: max(10px, env(safe-area-inset-bottom));
        font-size: 15px;
    }

    /* Les blocs se suivaient bord à bord : sur téléphone, un espace les
       sépare pour que chaque étape se lise comme une carte à part. */
    .is-mobile-app .scan-consume { display: flex; flex-direction: column; gap: 10px; }
    .is-mobile-app .scan-consume > .message { margin-bottom: 0 !important; }

    .is-mobile-app .block-title { padding: 6px 10px; font-size: 13px; }
    .is-mobile-app .block-body { padding: 10px; }

    /* En bloc plutôt qu en flex : un texte mêlé de <strong> se coupait en
       colonnes sur un écran étroit. */
    .is-mobile-app .message { display: block; padding: 10px 12px; font-size: 15px; }

    .is-mobile-app .field > label { font-size: 13px; }

    /* Scan : la caméra en premier, sur toute la largeur — c'est le geste
       normal sur téléphone. Le champ reste dessous, pour une douchette
       Bluetooth ou un code tapé à la main. */
    .has-camera .is-mobile-app .scan-camera-btn {
        display: flex;
        justify-content: center;
        width: 100%;
        height: 56px;
        margin-bottom: 10px;
        font-size: 17px;
    }

    /* Boîte de scan repliable : titre de 44px, chevron d'état à gauche,
       raccourci 📷 à droite quand elle est repliée (déployée, le grand
       bouton caméra est déjà là). */
    .is-mobile-app .scan-box-title {
        min-height: 44px;
        padding: 0 0 0 10px;
        font-size: 15px;
        cursor: pointer;
        -webkit-user-select: none;
        user-select: none;
    }

    .is-mobile-app .scan-box:not([open]) .scan-box-title { border-bottom: none; }
    .is-mobile-app .scan-box-title > span::before { content: "▸ "; color: var(--text-soft); }
    .is-mobile-app .scan-box[open] .scan-box-title > span::before { content: "▾ "; }

    .has-camera .is-mobile-app .scan-box:not([open]) .scan-box-camera {
        display: inline-flex;
        justify-content: center;
        width: 64px;
        height: 44px;
        padding: 0;
        border: none;
        border-left: 1px solid var(--border);
        font-size: 20px;
    }

    /* Choix du congélateur et du tiroir : une ligne pleine largeur par
       choix, nom à gauche et quantité à droite, comme une liste iOS mais
       quadrillée. */
    .is-mobile-app .scan-choices { flex-direction: column; flex-wrap: nowrap; gap: 0; }

    .is-mobile-app .scan-choice {
        width: 100%;
        height: 56px;
        justify-content: space-between;
        padding: 0 14px;
        font-size: 16px;
        white-space: normal;
        text-align: left;
    }

    .is-mobile-app .scan-choice + .scan-choice { border-top: none; }
    .is-mobile-app .scan-choice-name { font-weight: 600; }
    .is-mobile-app .scan-choice-qty { color: var(--text-soft); font-variant-numeric: tabular-nums; }
    .is-mobile-app .scan-choice-qty::before { content: none; }
    .is-mobile-app .scan-choice-qty::after { content: " ›"; color: var(--text-faint); }

    .is-mobile-app .scan-back { height: 44px; padding: 0 14px; font-size: 15px; }

    .is-mobile-app .scan-candidate {
        padding: 8px 0;
        border-bottom: 1px solid var(--grid);
    }

    .is-mobile-app .scan-candidate:last-child { border-bottom: none; }

    /* Lots : − quantité + au centre, en grand. */
    .is-mobile-app .scan-consume-lot { padding: 14px 0; font-size: 16px; }
    .is-mobile-app .scan-qty-step { width: 56px; height: 56px; font-size: 26px; }
    .is-mobile-app input.scan-consume-qty { height: 56px; width: 110px; font-size: 26px; }

    .is-mobile-app .scan-reasons {
        display: grid;
        grid-template-columns: 1fr 1fr;
    }

    .is-mobile-app .scan-reasons .btn { justify-content: center; white-space: normal; }

    /* Barre de validation collée en bas, au-dessus de la barre d'accueil.
       Deux boutons pleine largeur : valider (large) et annuler. */
    .is-mobile-app .scan-consume-actions {
        position: sticky;
        bottom: 0;
        z-index: 5;
        flex-wrap: nowrap;
        gap: 8px;
        margin: 12px -10px -10px;
        padding: 10px;
        padding-bottom: max(10px, env(safe-area-inset-bottom));
        border-top: 1px solid var(--border);
        border-bottom: none;
    }

    .is-mobile-app .scan-consume-actions .btn {
        height: 52px;
        justify-content: center;
        font-size: 17px;
    }

    .is-mobile-app .scan-consume-actions .btn-primary { flex: 2; }
    .is-mobile-app .scan-consume-actions .btn:not(.btn-primary) { flex: 1; }
}

/* Choix du bénéficiaire d'un don : encadré sous les motifs, pour qu'on voie
   d'un coup d'œil qu'il manque quelque chose avant de valider. */
.scan-recipients {
    margin-top: 8px;
    padding: 8px;
    border: 1px solid var(--border);
    background: var(--panel);
}
