/* ============================================================
   Shell 1a — contrat leader-ui §1/§3/§4/§7bis.
   Toutes les couleurs, polices et ombres viennent de tokens.css ;
   la géométrie (px) suit les specs chiffrées de la skill.
   ============================================================ */

* { box-sizing: border-box; }
body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  color: var(--fg-1);
  background: var(--bg-page);
}
h1, h2, h3, p { margin: 0; }
.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums lining-nums; }

/* --- Layout ------------------------------------------------- */
.shell { display: flex; min-height: 100vh; }
.main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.content { flex: 1; padding: 20px 24px; }

/* --- Rail de navigation (§1) -------------------------------- */
.rail {
  width: 216px;
  flex: none;
  display: flex;
  flex-direction: column;
  background: var(--bg-surface);
  border-right: 1px solid var(--border-default);
  transition: width var(--dur-base) var(--ease-inout);
}
html[data-rail-collapsed] .rail { width: 58px; }
html[data-rail-collapsed] .rail__label { display: none; }

.rail__nav {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 8px 8px;
  overflow: hidden;
}
.rail__item {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 36px;
  padding: 0 10px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--fg-2);
  font-family: inherit;
  font-size: var(--fs-sm);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.rail__item svg { width: 17px; height: 17px; flex: none; }
.rail__item:hover { background: var(--bg-hover); text-decoration: none; }
.rail__item.is-active {
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: var(--fw-semibold);
}
.rail__toggle { margin: 0 8px 4px; }
/* Filet entre les pages du quotidien et celles d'installation (`admin`). */
.rail__sep { height: 1px; margin: 8px 10px; background: var(--border-subtle); flex: none; }

.rail__account {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-top: 1px solid var(--border-default);
  overflow: hidden;
}
.avatar {
  flex: none;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
}
.rail__who { display: flex; flex-direction: column; line-height: 1.25; white-space: nowrap; }
.rail__who strong { font-size: var(--fs-xs); font-weight: var(--fw-semibold); }
.rail__who small { font-size: var(--fs-2xs); color: var(--fg-3); }
.rail__account form { margin-left: auto; }
html[data-rail-collapsed] .rail__account form { display: none; }

/* --- Topbar (§1) --------------------------------------------- */
.topbar {
  height: 56px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 16px;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border-default);
}
.topbar__crumb { display: flex; align-items: center; gap: 8px; min-width: 0; }
.topbar__crumb svg { width: 13px; height: 13px; color: var(--fg-3); flex: none; }
.topbar__sep-crumb { color: var(--fg-4); }
.topbar__crumb h1 { font-size: 16px; font-weight: var(--fw-semibold); white-space: nowrap; }
/* La méta cède avant tout le reste : sur téléphone, « Journée comptable du
   14/08/2026 · 90 articles » dépassait de la fenêtre et faisait défiler la page
   horizontalement, ce que le contrat interdit. */
.topbar__meta {
  font-size: 11.5px;
  color: var(--fg-3);
  white-space: nowrap;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.topbar__actions { display: flex; align-items: center; gap: 8px; }
.topbar__search {
  width: 250px;
  height: 32px;
  padding: 0 10px;
  border: 1px solid var(--border-default);
  border-radius: 6px;
  background: var(--bg-sunken);
  font-family: inherit;
  font-size: var(--fs-sm);
  color: var(--fg-1);
}
.topbar__search:focus { outline: none; border-color: var(--border-focus); box-shadow: var(--ring-focus); }
.topbar__sep { width: 1px; height: 20px; background: var(--border-default); }

/* --- Boutons icône (§3) -------------------------------------- */
.icon-btn {
  position: relative;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--fg-2);
  cursor: pointer;
}
.icon-btn svg { width: 15px; height: 15px; }
.icon-btn:hover { background: var(--bg-hover); }
.icon-btn__dot {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 7px;
  height: 7px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  box-shadow: 0 0 0 1px var(--bg-surface);
}

/* --- Volet latéral : le détail d'une ligne (`?site=`, `?produit=`, `?jour=`).
   Rendu côté serveur : le fermer est un lien, l'URL se partage. ---------- */
.volet__fond { position: fixed; inset: 0; z-index: 60; background: rgba(10, 10, 8, .24); }
.volet {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 61;
  width: min(460px, 100vw);
  display: flex;
  flex-direction: column;
  background: var(--bg-surface);
  border-left: 1px solid var(--border-default);
  box-shadow: var(--shadow-xl);
}
.volet__tete { display: flex; align-items: flex-start; gap: 10px; padding: 16px 20px; border-bottom: 1px solid var(--border-default); }
.volet__tete > div { flex: 1; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.volet__tete h2 { font-size: var(--fs-lg); font-weight: var(--fw-semibold); }
.volet__tete small { font-size: var(--fs-xs); color: var(--fg-3); }
.volet__corps { flex: 1; overflow-y: auto; padding: 16px 20px; display: flex; flex-direction: column; gap: 22px; }
.volet__section { display: flex; flex-direction: column; gap: 10px; }
.volet__section h3 {
  font-size: 11px;
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-3);
}
.volet__form { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.volet__form label { display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-xs); color: var(--fg-2); }
.volet__form input, .volet__form select {
  height: 36px;
  padding: 0 10px;
  border: 1px solid var(--border-default);
  border-radius: 4px;
  background: var(--bg-surface);
  font-family: inherit;
  font-size: var(--fs-sm);
  color: var(--fg-1);
}
.volet__form input.mono { font-family: var(--font-mono); }
.volet__form input:focus, .volet__form select:focus { outline: none; border-color: var(--border-focus); box-shadow: var(--ring-focus); }
.volet__form small { color: var(--fg-3); }
.volet__form .reglages__case { flex-direction: row; align-items: center; gap: 8px; font-size: var(--fs-sm); color: var(--fg-1); }
.volet__plein { grid-column: 1 / -1; }
/* Un bouton dans la grille du volet se range à droite, comme toutes les actions du volet. */
.volet__form > .btn { justify-self: end; }
.volet__kv { display: grid; grid-template-columns: max-content 1fr; gap: 6px 14px; margin: 0; font-size: var(--fs-sm); }
.volet__kv dt { color: var(--fg-3); }
.volet__kv dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.volet__kv .mono { font-size: var(--fs-xs); }
.volet__alerte { font-size: var(--fs-sm); color: var(--warning); }
.volet__aide { font-size: var(--fs-xs); color: var(--fg-3); }
.volet__ecran { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-bottom: 1px solid var(--border-subtle); font-size: var(--fs-sm); }
.volet__ecran > svg { width: 16px; height: 16px; color: var(--fg-3); flex: none; }
.volet__ecran > div { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.volet__ecran small { font-size: var(--fs-2xs); color: var(--fg-3); }
.volet__diagnostic summary { display: flex; align-items: baseline; gap: 10px; cursor: pointer; list-style: none; }
.volet__diagnostic summary::-webkit-details-marker { display: none; }
.volet__diagnostic summary small { font-size: var(--fs-xs); color: var(--fg-3); }
.volet__pied { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 20px; border-top: 1px solid var(--border-default); }
.pastille { width: 8px; height: 8px; border-radius: var(--radius-pill); flex: none; background: var(--fg-4); }
.pastille--success { background: var(--success); }
.pastille--warning { background: var(--warning); }
.pastille--danger { background: var(--danger); }
/* Ligne dont le volet est ouvert (§5.7 : sélection). */
.tableau tbody tr.est-choisie td { background: var(--accent-soft); }
.tableau tbody tr.est-choisie td:first-child { box-shadow: inset 2px 0 0 var(--accent); }
.tableau.liste { table-layout: auto; }
.tableau.liste a { color: var(--fg-1); font-weight: var(--fw-semibold); }
@media (max-width: 768px) {
  .volet__form { grid-template-columns: 1fr; }
  .volet__form > .btn { justify-self: stretch; }
  .volet__form input, .volet__form select { height: 44px; }
  .volet__ecran .icon-btn { width: 44px; height: 44px; }
}

/* --- Production : les temps dans leur case, le rattachement en ligne --- */
.produits td.champ { padding: 0 4px; }
/* Onglet Stocks : 1 px de cellule + 1 px de bordure + 8 px de saisie = les
   10 px de l'en-tête, les chiffres tombent sous leur titre. Les cartons passent
   dessous, alignés de même. */
.stocks td.champ { padding: 0 1px; }
.stock__case { display: inline-flex; flex-direction: column; align-items: flex-end; vertical-align: middle; }
.stock__case small { font-size: var(--fs-2xs); line-height: 1.2; }
.stocks td.champ .stock__case small, .stocks td.champ .champ__erreur, .stocks td.champ .champ__ok { padding-right: 9px; }
.th__site { display: block; font-size: var(--fs-2xs); font-weight: var(--fw-medium); text-transform: none; letter-spacing: 0; color: var(--fg-2); }
/* Un champ qui se lit comme du texte tant qu'on ne le touche pas : la grille
   reste lisible, et corriger un temps ne demande qu'un clic. */
.champ__saisie {
  width: 64px;
  height: 30px;
  padding: 0 8px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  text-align: right;
  color: var(--fg-1);
}
.champ__saisie:hover { border-color: var(--border-default); background: var(--bg-surface); }
.champ__saisie:focus { outline: none; border-color: var(--border-focus); box-shadow: var(--ring-focus); background: var(--bg-surface); }
.champ__saisie.est-en-erreur { border-color: var(--danger); }
.champ__saisie.htmx-request { opacity: .6; }
.champ__saisie--dlc { width: 104px; }
.champ__saisie--dlc[type="datetime-local"] { width: 200px; }
/* Un temps manquant empêche d'afficher le produit : il doit sauter aux yeux. */
.champ--manquant { background: var(--warning-soft); }
.champ--manquant .champ__saisie::placeholder { color: var(--warning); opacity: 1; }
.champ__erreur, .champ__ok { display: block; font-family: var(--font-sans); font-size: var(--fs-2xs); white-space: normal; }
.champ__erreur { color: var(--danger); }
.champ__ok { color: var(--success); }
.rattacher { display: flex; align-items: center; gap: 6px; }
/* 28 px : la hauteur de son bouton `.btn--sm`, champs et boutons alignés. */
.rattacher select, .rattacher input {
  height: 28px;
  padding: 0 8px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  font-family: inherit;
  font-size: var(--fs-sm);
  color: var(--fg-1);
}
.rattacher select { max-width: 220px; }
.rattacher input { width: 56px; font-family: var(--font-mono); text-align: right; }
.ignores { margin-top: 16px; }
@media (max-width: 768px) {
  .champ__saisie, .rattacher select, .rattacher input { height: 44px; }
  .rattacher { flex-wrap: wrap; }
}

/* --- Cloche : les alertes qui demandent une action ----------- */
.cloche { position: relative; }
.cloche summary { list-style: none; }
.cloche summary::-webkit-details-marker { display: none; }
.cloche__compte {
  position: absolute;
  top: 1px;
  right: 0;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--accent-fg);
  font-size: 10px;
  font-weight: var(--fw-semibold);
  line-height: 16px;
  text-align: center;
  box-shadow: 0 0 0 2px var(--bg-surface);
}
.cloche__menu {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  width: 340px;
  max-width: calc(100vw - 24px);
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: 8px;
  box-shadow: var(--shadow-lg);
  z-index: 50;
  overflow: hidden;
}
.cloche__tete { padding: 10px 14px; border-bottom: 1px solid var(--border-default); font-size: var(--fs-sm); font-weight: var(--fw-semibold); }
.cloche__item { display: flex; gap: 10px; padding: 11px 14px; color: var(--fg-1); text-decoration: none; }
.cloche__item + .cloche__item { border-top: 1px solid var(--border-subtle); }
.cloche__item:hover { background: var(--bg-hover); text-decoration: none; }
.cloche__item span { display: flex; flex-direction: column; gap: 2px; font-size: var(--fs-sm); }
.cloche__item strong { font-weight: var(--fw-semibold); }
.cloche__item small { font-size: var(--fs-xs); color: var(--fg-3); }
.cloche__icone { width: 16px; height: 16px; flex: none; margin-top: 1px; }
.cloche__icone--danger { color: var(--danger); }
.cloche__icone--warning { color: var(--warning); }
.cloche__icone--info { color: var(--info); }
.cloche__vide { padding: 14px; font-size: var(--fs-sm); color: var(--fg-3); }

/* --- Sélecteur d'entité (§1) --------------------------------- */
.entity { position: relative; }
.entity summary {
  list-style: none;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border: 1px solid var(--border-default);
  border-radius: 6px;
  background: var(--bg-surface);
  cursor: pointer;
}
.entity summary::-webkit-details-marker { display: none; }
.entity summary img {
  width: 28px;
  height: 28px;
  object-fit: contain;
  background: var(--zinc-0);
  border-radius: 4px;
}
.entity__menu {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  width: 290px;
  padding: 6px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: 8px;
  box-shadow: var(--shadow-lg);
  z-index: 50;
}
.entity__current, .entity__opt {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.entity__current { border-bottom: 1px solid var(--border-default); border-radius: 6px 6px 0 0; cursor: default; }
.entity__opt:hover { background: var(--bg-hover); }
.entity__current img, .entity__opt img {
  width: 30px;
  height: 30px;
  object-fit: contain;
  background: var(--zinc-0);
  border: 1px solid var(--border-subtle);
  border-radius: 4px;
  flex: none;
}
.entity__names { display: flex; flex-direction: column; min-width: 0; flex: 1; line-height: 1.3; }
.entity__names strong { font-size: var(--fs-sm); font-weight: var(--fw-semibold); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.entity__names small { font-size: var(--fs-2xs); color: var(--fg-3); }
.entity__dot { flex: none; width: 8px; height: 8px; border-radius: var(--radius-pill); }
.entity__head {
  padding: 8px 8px 4px;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--fg-3);
}
.entity__logout { border-top: 1px solid var(--border-default); margin-top: 4px; padding-top: 4px; }
.entity__logout button {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  font-family: inherit;
  font-size: var(--fs-sm);
  color: var(--fg-2);
  cursor: pointer;
}
.entity__logout button:hover { background: var(--bg-hover); }
.entity__logout svg { width: 15px; height: 15px; }

/* --- Boutons texte (§3) --------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 36px;
  padding: 0 14px;
  border-radius: 4px;
  border: 1px solid transparent;
  font-family: inherit;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  text-decoration: none;
  cursor: pointer;
}
.btn svg { width: 15px; height: 15px; flex: none; }
.btn--primary { background: var(--accent); color: var(--accent-fg); }
.btn--primary:hover { background: var(--accent-hover); text-decoration: none; }
.btn--secondary { background: var(--bg-surface); color: var(--fg-1); border-color: var(--border-default); }
.btn--secondary:hover { background: var(--bg-hover); }
/* Ghost (§3) : l'action de retrait d'un popover de filtre, qui ne doit pas
   peser autant que « Appliquer ». */
.btn--ghost { background: transparent; color: var(--fg-2); }
.btn--ghost:hover { background: var(--bg-hover); text-decoration: none; }
/* Danger (§3) : action destructive, jamais primaire. */
.btn--danger { background: var(--danger-soft); color: var(--danger); border-color: var(--danger-border); }
.btn--danger:hover { border-color: var(--danger); }
.btn--lg { height: 44px; padding: 0 18px; }
.btn--sm { height: 28px; padding: 0 10px; font-size: var(--fs-xs); }
/* Trois hauteurs, pas une de plus (§3) : 28 compact (lignes de tableau, barres
   d'outils), 36 par défaut (formulaires), 44 au doigt (téléphone). Un champ
   posé à côté d'un bouton prend la hauteur de ce bouton. */
@media (max-width: 768px) {
  .btn, .reglages__ajout input:not([type="checkbox"]), .reglages__ajout select { min-height: 44px; }
}

/* --- KPI (§4) -------------------------------------------------- */
.kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin-bottom: 20px;
}
.kpi {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 15px 16px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: 6px;
}
.kpi__label {
  font-size: 11px;
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-3);
}
.kpi__value {
  font-size: 22px;
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums lining-nums;
  white-space: nowrap;
}
/* La puce d'écart reste sur la ligne de la valeur (§4) : elle qualifie le
   nombre, elle ne se lit pas seule. */
.kpi__delta { margin-left: 6px; vertical-align: 2px; }

/* --- Chips (§4) ------------------------------------------------ */
.chip {
  display: inline-flex;
  align-items: center;
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border-default);
  background: var(--bg-sunken);
  font-size: 11.5px;
  font-weight: var(--fw-semibold);
  white-space: nowrap;
}
.chip--success { background: var(--success-soft); border-color: var(--success-border); color: var(--success); }
.chip--warning { background: var(--warning-soft); border-color: var(--warning-border); color: var(--warning); }
.chip--danger  { background: var(--danger-soft);  border-color: var(--danger-border);  color: var(--danger); }
.chip--info    { background: var(--info-soft);    border-color: var(--info-border);    color: var(--info); }

/* --- Cartes ----------------------------------------------------- */
.card {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: 6px;
  margin-bottom: 20px;
}
.card__row { display: flex; align-items: center; gap: 12px; padding: 14px 16px; }
.card__row > svg { width: 20px; height: 20px; color: var(--accent); flex: none; }
.card__row > div { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.card__row small { color: var(--fg-3); font-size: var(--fs-xs); }
/* Empilées dans une même carte, les lignes ont besoin d'un filet : sans lui
   elles se confondent dès qu'il y en a plus de deux. */
.card__row + .card__row { border-top: 1px solid var(--border-subtle); }
/* Valeur alignée à droite d'une ligne de carte (volumes, tailles de fichier).
   Mono tabulaire : ces nombres changent à chaque rafraîchissement. */
.card__value {
  flex: none;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums lining-nums;
  font-size: var(--fs-sm);
  color: var(--fg-2);
}

/* --- Liste de réglages : un bloc repliable par élément, formulaire
   d'ajout en pied. Utilisé par Droits d'accès et par Restaurants — c'est le
   motif « liste + ajout » de l'application, à réutiliser tel quel. ------- */
.reglages__head { margin-bottom: 14px; }
.reglages__head h2 { font-size: var(--fs-lg); font-weight: var(--fw-semibold); }
.reglages__head p { font-size: var(--fs-sm); color: var(--fg-2); margin-top: 4px; }

.reglages__bloc {
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: 6px;
  margin-bottom: 10px;
}
.reglages__bloc summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  cursor: pointer;
  list-style: none;
  font-size: var(--fs-sm);
}
.reglages__bloc summary::-webkit-details-marker { display: none; }
.reglages__bloc summary svg { width: 16px; height: 16px; color: var(--fg-2); }
.reglages__bloc summary small { color: var(--fg-4); font-size: var(--fs-2xs); }
.reglages__scroll { overflow-x: auto; }
/* Texte d'aide sous un formulaire de réglages. */
.reglages__aide { font-size: var(--fs-xs); color: var(--fg-3); margin-top: 10px; }
.reglages__retrait { display: flex; justify-content: flex-end; padding: 10px 14px; border-top: 1px solid var(--border-subtle); }
.reglages__table { width: 100%; min-width: 460px; border-collapse: collapse; }
.reglages__table td {
  padding: 8px 14px;
  border-top: 1px solid var(--border-subtle);
  font-size: var(--fs-sm);
}
.reglages__table td:first-child { display: flex; align-items: center; gap: 8px; }
.reglages__table td svg { width: 15px; height: 15px; color: var(--fg-3); }
.reglages__table td:last-child { text-align: right; }
.reglages__table td:last-child .mono { font-size: var(--fs-xs); word-break: break-all; }

.segments { display: inline-flex; border: 1px solid var(--border-default); border-radius: 6px; overflow: hidden; }
.segments__opt {
  height: 28px;
  padding: 0 12px;
  border: 0;
  border-left: 1px solid var(--border-default);
  background: var(--bg-surface);
  font-family: inherit;
  font-size: var(--fs-xs);
  color: var(--fg-2);
  cursor: pointer;
}
.segments__opt:first-child { border-left: 0; }
.segments__opt:hover { background: var(--bg-hover); }
.segments__opt.is-active {
  background: var(--accent);
  color: var(--accent-fg);
  font-weight: var(--fw-semibold);
}

.reglages__ajout { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
.reglages__ajout .reglages__aide { flex: 1 1 100%; margin-top: 0; }
.reglages__ajout input {
  height: 36px;
  padding: 0 10px;
  border: 1px solid var(--border-default);
  border-radius: 6px;
  background: var(--bg-surface);
  font-family: inherit;
  font-size: var(--fs-sm);
}
.reglages__ajout input:focus { outline: none; border-color: var(--border-focus); box-shadow: var(--ring-focus); }
/* Les listes déroulantes et la case à cocher de la ligne d'ajout suivent la
   même géométrie que les champs texte : un seul style de contrôle dans l'app. */
.reglages__ajout select {
  height: 36px;
  padding: 0 10px;
  border: 1px solid var(--border-default);
  border-radius: 6px;
  background: var(--bg-surface);
  font-family: inherit;
  font-size: var(--fs-sm);
  color: var(--fg-1);
}
.reglages__case {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--fs-xs);
  color: var(--fg-2);
}
.reglages__case input { height: auto; accent-color: var(--accent); }
/* Dans un formulaire en ligne, la case reste à côté de son libellé. */

/* --- Barre de page : onglets à gauche, période à droite ------------ */
.barre-page { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.barre-page__espace { flex: 1; }
.barre-page__periode { font-size: var(--fs-sm); }
.barre-page__jour { display: flex; align-items: center; gap: 6px; }
.barre-page__jour input {
  height: 28px;
  padding: 0 8px;
  border: 1px solid var(--border-default);
  border-radius: 5px;
  background: var(--bg-surface);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--fg-1);
}
.barre-page__jour input:focus { outline: none; border-color: var(--border-focus); box-shadow: var(--ring-focus); }
.onglets {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  background: var(--bg-sunken);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
}
.onglets__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  padding: 0 12px;
  border-radius: var(--radius-sm);
  color: var(--fg-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  text-decoration: none;
  white-space: nowrap;
}
.onglets__item:hover { color: var(--fg-1); text-decoration: none; }
.onglets__item.is-active { background: var(--bg-surface); color: var(--fg-1); box-shadow: var(--shadow-sm); }
.onglets__compte { font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--fg-3); }
.onglets__compte--accent { color: var(--accent); font-weight: var(--fw-semibold); }

/* --- Tableau de bord : une carte par site ------------------------------
   Grille dense : la carte d'un site en direct occupe trois rangées, les cartes
   compactes (sites sans agent) remplissent les colonnes voisines. Les quatre
   sites tiennent ainsi sans défiler, quel que soit le nombre en direct. */
.kpi__sous { font-size: var(--fs-2xs); color: var(--fg-3); }
.sites {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  grid-auto-flow: dense;
  gap: 16px;
  margin-bottom: 16px;
}
.site {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-md);
  min-width: 0;
}
.site--direct { grid-row: span 3; }
/* L'alerte est la couleur de la carte, plus un paragraphe en tête de page. */
.site--danger { border-color: var(--danger-border); }
.site--warning { border-color: var(--warning-border); }
.site__tete { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.site__tete strong { font-size: var(--fs-lg); font-weight: var(--fw-semibold); }
.site--compact .site__tete strong { font-size: var(--fs-md); }
.site__tete small { font-size: var(--fs-xs); color: var(--fg-3); }
.site__tete .chip { margin-left: auto; }
/* Le réalisé domine : c'est le chiffre qu'on cherche des yeux en entrant. */
.site__chiffres { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.site__reel { font-size: 32px; font-weight: var(--fw-semibold); line-height: 1; }
.site__attendu { font-size: var(--fs-sm); color: var(--fg-3); }
.site__attendu strong { color: var(--fg-1); font-weight: var(--fw-semibold); }
.site__alerte {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  background: var(--danger-soft);
  color: var(--danger);
  font-size: var(--fs-sm);
}
.site__alerte svg { width: 16px; height: 16px; flex: none; }
.site__alerte a { color: inherit; font-weight: var(--fw-semibold); }
.site__vide { font-size: var(--fs-sm); color: var(--fg-3); }
/* Forme de la journée prévue, sur une carte compacte : pas de valeur, juste le
   profil — les heures de pointe se voient d'un coup d'œil. */
.site__profil { display: flex; align-items: flex-end; gap: 3px; height: 28px; }
.site__profil span { flex: 1; min-height: 2px; background: var(--bg-sunken); border-top: 2px solid var(--fg-4); border-radius: 2px 2px 0 0; }
.site__heures summary {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-sm);
  color: var(--fg-2);
  cursor: pointer;
  list-style: none;
}
.site__heures summary::-webkit-details-marker { display: none; }
.site__heures summary svg { width: 14px; height: 14px; transition: transform var(--dur-base) var(--ease-inout); }
.site__heures[open] summary svg { transform: rotate(180deg); }
.site__pied {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  padding-top: 12px;
  border-top: 1px solid var(--border-subtle);
  font-size: var(--fs-sm);
  color: var(--fg-2);
}
.site__pied form { margin-left: auto; }
.bandeau__jauge {
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--bg-sunken);
  overflow: hidden;
}
.bandeau__jauge span { display: block; height: 100%; background: var(--accent); }
.meilleures { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); border-top: 1px solid var(--border-subtle); }
.meilleures__item { display: flex; flex-direction: column; gap: 4px; padding: 12px 16px; border-left: 1px solid var(--border-subtle); }
.meilleures__item:first-child { border-left: 0; }
.meilleures__item strong { font-size: var(--fs-sm); }
.meilleures__item span { font-size: var(--fs-xs); color: var(--fg-3); }
/* Le tampon d'actualisation remplace l'indicateur de chargement : un sondage
   n'est pas une action mutante. Il prouve en plus que le sondage vit encore. */
.journee__horodatage {
  margin: 4px 0 0;
  font-size: var(--fs-2xs);
  color: var(--fg-4);
  text-align: right;
}

/* Le détail par heure, réemployé dans une carte ou un volet : sans retrait. */
.site__heures .heures, .volet .heures { padding: 10px 0 0; }
/* Une heure à venir n'a pas de réel : le pixel de `min-width` de la barre se
   confondrait avec une heure passée sans vente, qui est justement l'anomalie
   qu'on veut voir. Le tiret de la colonne de valeur dit déjà « rien ». */
.heure--a-venir .heure__barre--reel { display: none; }

/* --- Cumul depuis l'ouverture : deux courbes, aucune bibliothèque ---
   Le `viewBox` est un carré de 100 unités et `preserveAspectRatio="none"` :
   la géométrie est en pourcentages, calculée en Python, et la hauteur en
   pixels appartient au CSS. Sans cela la hauteur suivrait la largeur, et le
   même graphique aurait fait trois fois plus haut sur un périmètre d'un seul
   site que sur la vue de groupe.
   Les couleurs passent par des classes et non par des attributs : un attribut
   de présentation SVG ne parse pas `var()` — `stroke="var(--accent)"` ne
   dessine rien du tout. Ici, aucun littéral : le mode sombre suivra seul. */
.cumul {
  display: block;
  width: 100%;
  height: 84px;
  /* Le défaut d'un SVG racine est `hidden` : la moitié du trait posé sur la
     ligne de base serait rognée et le socle paraîtrait deux fois plus fin. */
  overflow: visible;
}
.cumul__aire { fill: var(--accent-soft); stroke: none; }
.cumul__attendu, .cumul__reel { fill: none; stroke-linejoin: round; stroke-linecap: round; }
/* L'attendu est plus fin et neutre, le réel plus épais et accentué : la
   distinction ne repose donc pas sur la seule couleur. */
.cumul__attendu { stroke: var(--fg-4); stroke-width: 1.5; }
.cumul__reel { stroke: var(--accent); stroke-width: 2; }
.cumul__socle { stroke: var(--border-default); stroke-width: 1; }
/* Le réel s'arrête à la dernière heure terminée. Sans ce repère, une courbe
   tronquée se lit comme un effondrement des ventes. */
.cumul__maintenant { stroke: var(--border-strong); stroke-width: 1; }
.cumul__axe {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-top: 6px;
  font-size: var(--fs-2xs);
  color: var(--fg-3);
}
.cumul__legende { display: inline-flex; align-items: center; gap: 6px; }
.cumul__legende i { display: inline-block; width: 14px; height: 2px; background: var(--fg-4); }
.cumul__legende i.cumul__legende-reel { height: 3px; background: var(--accent); }
.cumul__legende i:not(:first-child) { margin-left: 8px; }

/* --- La semaine : une ligne par site, une colonne par jour ---------- */
.semaine__scroll { overflow-x: auto; background: var(--bg-surface); border: 1px solid var(--border-default); border-radius: var(--radius-md); }
.semaine { width: 100%; border-collapse: separate; border-spacing: 0; font-variant-numeric: tabular-nums lining-nums; }
.semaine th, .semaine td { padding: 10px 12px; border-bottom: 1px solid var(--border-subtle); text-align: right; vertical-align: top; }
.semaine thead th {
  background: var(--bg-sunken);
  border-bottom-color: var(--border-default);
  font-size: 11px;
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-3);
  white-space: nowrap;
}
.semaine thead th.est-aujourdhui { color: var(--accent); }
/* La colonne des sites reste en place quand la grille défile (téléphone). */
.semaine th:first-child { position: sticky; left: 0; z-index: 1; text-align: left; background: var(--bg-surface); white-space: nowrap; }
.semaine thead th:first-child { background: var(--bg-sunken); }
.semaine tbody th { font-size: var(--fs-sm); font-weight: var(--fw-semibold); }
.semaine tfoot th, .semaine tfoot td { background: var(--bg-sunken); border-bottom: 0; font-weight: var(--fw-semibold); }
.semaine td.est-aujourdhui { background: var(--accent-soft); }
.semaine td.est-choisie { box-shadow: inset 0 0 0 2px var(--accent); }
.semaine__evenement {
  display: block;
  max-width: 110px;
  margin: 4px 0 0 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 10.5px;
  font-weight: var(--fw-medium);
  text-transform: none;
  letter-spacing: 0;
  color: var(--info);
}
.case { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; min-width: 84px; }
.case__lien { display: contents; color: inherit; text-decoration: none; }
.case__lien:hover .case__valeur { text-decoration: underline; }
.case__valeur { font-family: var(--font-mono); font-size: var(--fs-md); font-weight: var(--fw-semibold); }
.case__sous { display: inline-flex; align-items: center; gap: 3px; font-family: var(--font-mono); font-size: var(--fs-2xs); color: var(--fg-3); }
.case__sous svg { width: 11px; height: 11px; }
.case__sous--ok { color: var(--success); }
.case__sous--erreur { color: var(--danger); font-family: var(--font-sans); white-space: normal; max-width: 140px; text-align: right; }
.case__detail { text-decoration: none; }
.case__detail:hover { color: var(--accent); text-decoration: underline; }
.case .chip { font-size: 10.5px; padding: 1px 7px; }
.case__saisie {
  width: 96px;
  height: 32px;
  padding: 0 8px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-sm);
  background: var(--bg-surface);
  font-family: var(--font-mono);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  text-align: right;
  color: var(--fg-1);
}
/* Le moteur en filigrane : lisible, c'est la valeur qu'on accepte en ne
   saisissant rien. */
.case__saisie::placeholder { color: var(--fg-2); opacity: 1; }
.case__saisie:focus { outline: none; border-color: var(--border-focus); box-shadow: var(--ring-focus); }
/* Une valeur saisie se distingue d'une valeur proposée : sans ce repère, on ne
   sait plus ce qu'on a corrigé la semaine dernière. */
.case__saisie.est-manuelle { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.case__saisie.est-en-erreur { border-color: var(--danger); }
.case__saisie.htmx-request { opacity: .6; }
.semaine__total { font-weight: var(--fw-semibold); }

/* --- CA par heure : deux barres, aucune bibliothèque ---------------- */
.heures { padding: 6px 0 12px 104px; }
.heures__vide, .heures__legende { font-size: var(--fs-xs); color: var(--fg-3); margin-top: 8px; }
.heure {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 3px 0;
}
.heure__label { flex: 0 0 42px; font-size: var(--fs-xs); color: var(--fg-3); text-align: right; }
.heure__barres { flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px; min-width: 60px; }
.heure__barre { height: 6px; border-radius: var(--radius-xs); min-width: 1px; }
.heure__barre--prevu { background: var(--fg-4); }
.heure__barre--reel { background: var(--accent); }
.heure__valeur { flex: 0 0 76px; text-align: right; font-size: var(--fs-xs); }
.heure__legende {
  display: inline-block;
  width: 18px;
  height: 6px;
  border-radius: var(--radius-xs);
  vertical-align: middle;
}
.heure__legende--prevu { background: var(--fg-4); }
.heure__legende--reel { background: var(--accent); }

/* --- États vides & toasts ----------------------------------------- */
.empty-state {
  padding: 32px;
  border: 1px dashed var(--border-default);
  border-radius: 6px;
  color: var(--fg-3);
  font-size: var(--fs-sm);
  text-align: center;
}
.toasts { position: fixed; bottom: 20px; right: 20px; display: flex; flex-direction: column; gap: 8px; z-index: 100; }
.toast {
  padding: 10px 14px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-left: 2px solid var(--accent);
  border-radius: 6px;
  box-shadow: var(--shadow-md);
  font-size: var(--fs-sm);
}
.toast--success { border-left-color: var(--success); }
.toast--error { border-left-color: var(--danger); }

/* --- Écran de connexion --------------------------------------------- */
.login-page { display: grid; place-items: center; min-height: 100vh; }
.login-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  width: 340px;
  padding: 36px 32px;
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  border-radius: 8px;
  text-align: center;
}
.login-card__logo { width: 56px; height: 56px; object-fit: contain; border-radius: 6px; }
.login-card h1 { font-size: var(--fs-xl); font-weight: var(--fw-semibold); }
.login-card p { font-size: var(--fs-sm); color: var(--fg-2); }
.login-card .btn { width: 100%; margin-top: 8px; }

/* --- Mobile (§7bis) --------------------------------------------------- */
.tabbar { display: none; }
@media (max-width: 768px) {
  .rail { display: none; }
  .content { padding: 14px 14px 76px; }
  .topbar { gap: 8px; }
  .topbar__search { width: 100%; min-width: 0; }
  .topbar__crumb svg, .topbar__sep-crumb { display: none; }
  .tabbar {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    background: var(--bg-surface);
    border-top: 1px solid var(--border-default);
    z-index: 40;
  }
  .tabbar__item {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 8px 0 10px;
    min-height: 44px;
    color: var(--fg-3);
    font-size: 10px;
    text-decoration: none;
  }
  .tabbar__item svg { width: 21px; height: 21px; }
  .tabbar__item.is-active { color: var(--accent); }
  /* « Plus » : les pages au-delà des quatre premières, en feuille basse. */
  .tabbar__plus { flex: 1; display: flex; }
  .tabbar__plus summary { list-style: none; cursor: pointer; }
  .tabbar__plus summary::-webkit-details-marker { display: none; }
  .tabbar__plus[open] summary { color: var(--accent); }
  /* Ancrée sur la barre (fixe, donc positionnée) : pleine largeur, juste au-dessus. */
  .tabbar__feuille {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 100%;
    padding: 8px 0 12px;
    background: var(--bg-surface);
    border-top: 1px solid var(--border-default);
    border-radius: 12px 12px 0 0;
    box-shadow: var(--shadow-xl);
  }
  .tabbar__feuille a, .tabbar__feuille button {
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    min-height: 52px;
    padding: 0 20px;
    border: 0;
    background: transparent;
    color: var(--fg-1);
    font-family: inherit;
    font-size: var(--fs-md);
    text-align: left;
    text-decoration: none;
  }
  .tabbar__feuille a[aria-current] { color: var(--accent); font-weight: var(--fw-semibold); }
  .tabbar__feuille svg { width: 20px; height: 20px; color: var(--fg-2); }
  .tabbar__feuille form { border-top: 1px solid var(--border-subtle); margin-top: 6px; padding-top: 6px; }
  /* Matrice de droits : cibles tactiles et formulaire pleine largeur. */
  .segments__opt { height: 40px; }
  .reglages__ajout input:not([type="checkbox"]), .reglages__ajout .btn { flex: 1 1 100%; }
  .reglages__retrait .btn { min-height: 44px; flex: 1 1 100%; }
}

/* --- Cartes sur téléphone (§7bis) ------------------------------------- */
@media (max-width: 768px) {
  /* À 360 px, la puce d'état et le montant écrasent le libellé. On les laisse
     passer sous le texte plutôt que de le comprimer sur trois caractères. */
  .card__row { flex-wrap: wrap; }
  .card__row > div { min-width: 60%; }
  .card__value { margin-left: 32px; }

  .heures { padding-left: 0; }
  .case__saisie { height: 44px; }
  .barre-page .icon-btn { width: 44px; height: 44px; }
  .barre-page__jour input, .barre-page__jour .btn, .barre-page .menu__declencheur { min-height: 44px; }
  .reglages__ajout select, .reglages__ajout .reglages__case { flex: 1 1 100%; }
  /* Les montants restent lisibles, la barre se comprime : c'est la forme de la
     journée qui se lit d'abord, pas le pixel de largeur. */
  .heure__valeur { flex: 0 0 62px; }

  /* §7bis : les KPI en 2×2 et non en pile. Empilées, les tuiles faisaient un
     plein écran de chiffres avant le premier graphique — sur la page dont le
     sens est justement le graphique. */
  .kpis { grid-template-columns: 1fr 1fr; gap: 8px; }
  .kpi { padding: 12px; }
  .kpi__value { font-size: 19px; }
  .cumul { height: 96px; }
  /* Même verrou que `.periode .btn` : `min-height` l'emporte sur les 28 px de
     `.btn--sm` et la cible reste à portée de pouce. */
  .sites { grid-template-columns: 1fr; }
  .site__pied .btn { min-height: 44px; }
  .site__pied form { margin-left: 0; flex: 1 1 100%; }
  .site__heures summary { min-height: 44px; }
}
