/* Espace établissement.
   Palette et échelles : /design.css (bloc :root[data-console="etab"]), à la
   couleur de marque kelWINE. Composants communs (boutons, tableaux, champs,
   cartes, badges) : /composants.css. Ici, uniquement ce qui n'existe que dans
   cette console.

   La console n'est plus peinte au thème choisi par l'établissement : ce thème
   habille sa carte cliente, et s'aperçoit dans le panneau de personnalisation,
   sur la vraie WebApp. */
:root {
  /* Accent atténué, encore utilisé par quelques règles de cette feuille. */
  --accent2: #a86b74;
}
* { box-sizing: border-box; }
[hidden] { display: none !important; } /* corrige : le menu ne doit pas s'afficher avant login */

body { margin: 0; background: var(--bg); color: var(--ink); }
/* Colonne plus étroite que la console super-admin : moins de tableaux larges,
   plus de formulaires, la lecture y gagne. */
.container { max-width: 1040px; margin: var(--esp-5) auto var(--esp-6); padding: 0 var(--esp-5); }
a { color: var(--accent); }

/* Le pied de la barre latérale rappelle la version, comme côté super-admin. */
.sidebar .brand small { letter-spacing: .05em; }

.field { margin-bottom: var(--esp-4); }

/* Carte des vins (back-office) */
.mill { border-top: 1px solid var(--line); padding: var(--esp-3) 0; margin-top: var(--esp-2); }
.mill-head { display: flex; align-items: center; gap: var(--esp-2); flex-wrap: wrap; }
.mill-head .fav { display: flex; align-items: center; gap: var(--esp-1); font-size: var(--txt-sm); }
.mill-head .fav input { width: auto; }
.px-row { display: flex; gap: var(--esp-3); flex-wrap: wrap; margin-top: var(--esp-2); }
.px { display: flex; flex-direction: column; font-size: var(--txt-xs); color: var(--muted); }
.px input { width: 96px; }

/* Carte complète (sections et éléments) */
.item { border-top: 1px dashed var(--line); padding: var(--esp-3) 0; margin-top: var(--esp-2); }
.ip-list { margin: var(--esp-2) 0; }
.ip-row { display: flex; gap: var(--esp-2); margin-bottom: var(--esp-1); align-items: center; }
.ip-row .ip-cont { flex: 1; }
.ip-row .ip-prix { width: 96px; }

/* Photos */
.bo-photo { display: flex; align-items: center; gap: var(--esp-3); margin-top: var(--esp-3); flex-wrap: wrap; }
.bo-thumb { height: 48px; border-radius: var(--r-sm); border: 1px solid var(--line); object-fit: cover; }

.kv { margin: var(--esp-2) 0; font-size: var(--txt-sm); }

/* Connexion */
.login-wrap { max-width: 400px; margin: 4rem auto; padding: 0 var(--esp-4); }
.login-card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--ombre-2); padding: var(--esp-6);
}
.login-card h1 { margin: 0 0 var(--esp-1); font-size: var(--txt-xl); }
.login-card .brand-line { color: var(--accent); font-weight: 700; letter-spacing: .5px; margin-bottom: var(--esp-5); }
.login-card .brand-line span { font-weight: 300; }
.login-card .btn { width: 100%; margin-top: var(--esp-2); }


/* Sélecteur de thème */
.themes-grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); gap: var(--esp-3); margin: var(--esp-3) 0; }
.theme-pastille { cursor: pointer; border: 2px solid transparent; border-radius: var(--r-sm); padding: var(--esp-1); background: none; font: inherit; }
.theme-pastille.on { border-color: var(--accent); }
.theme-swatch { height: 42px; border-radius: var(--r-sm); border: 1px solid var(--line); position: relative; overflow: hidden; }
.theme-swatch .acc { position: absolute; right: 6px; bottom: 6px; width: 16px; height: 16px; border-radius: 50%; }
.theme-nom { display: block; font-size: var(--txt-xs); color: var(--muted); margin-top: var(--esp-1); }

/* Bloc repliable (« Demander l'ajout d'un vin ») */
.collapse-head {
  width: 100%; display: flex; align-items: center; justify-content: space-between;
  background: none; border: none; cursor: pointer; font: inherit;
  font-size: var(--txt-lg); font-weight: 600;
  color: inherit; padding: var(--esp-4) var(--esp-5); text-align: left;
}
.collapse-head .chev { color: var(--muted); transition: transform .25s ease; }
.collapse-head[aria-expanded="true"] .chev { transform: rotate(180deg); }
.collapse-body { max-height: 0; overflow: hidden; transition: max-height .3s ease; }

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

/* Coup de cœur : remonté juste sous le titre du vin. Un interrupteur par
   millésime, le cœur ne se colore que lorsque la case est cochée. */
.fav-row { display: flex; flex-wrap: wrap; gap: .3rem 1rem; margin-top: .5rem; }
.fav-row .fav { display: flex; align-items: center; gap: .35rem; font-size: .85rem; cursor: pointer; }
.fav-row .fav input { width: auto; margin: 0; }
.fav-row .fav .fa-heart { color: var(--line); transition: color .12s; }
.fav-row .fav input:checked + .fa-heart { color: #E53E3E; }
.fav-row .fav .crumb { margin: 0; }

/* --- Carte des vins : masquage, ordre manuel, contenances (lot 3) --- */

/* Référence masquée : visible et modifiable côté établissement, absente de la
   carte cliente. Aucune donnée n'est perdue, l'affichage doit le refléter. */
.vin-inactif { opacity: .62; border-style: dashed; }
.vin-inactif .dot { filter: grayscale(1); }

/* Millésime modifiable sur place, dès l'intégration du vin. */
.mill-edit { display: flex; align-items: center; gap: .4rem; font-size: .85rem; color: var(--ink); margin: 0; }
.mill-edit input { width: 130px; }
.mill-edit input::placeholder { font-style: italic; }

/* Regroupement par couleur en mode manuel : des sous-listes courtes plutôt
   qu'une seule liste de plusieurs centaines de références. */
.grp-couleur { display: flex; align-items: center; gap: .5rem; font-size: .95rem;
  margin: 1.2rem 0 .5rem; padding-bottom: .3rem; border-bottom: 1px solid var(--line); }
.grp-couleur .crumb { margin: 0; font-weight: 400; }
.grp-liste { min-height: 1rem; }

/* Déplacement par flèches plutôt que par glisser-déposer : plus facile à viser,
   utilisable au clavier et sur mobile. Les flèches de bout de liste sont
   désactivées, pas masquées, pour que la rangée de boutons ne saute pas.
   Le déplacement se fait uniquement ainsi : aucun rang numérique n'est exposé,
   la notion n'était pas lisible pour l'utilisateur. */
.fleches { display: inline-flex; gap: .2rem; }
.fleches .btn { min-width: 2rem; padding: .25rem .45rem; line-height: 1; }

/* Dialogue de portée d'une contenance : deux choix explicites. */
.dlg-portee { border: 1px solid var(--line); border-radius: var(--radius); padding: 1.2rem; max-width: 420px; }
.dlg-portee::backdrop { background: rgba(0, 0, 0, .35); }
.dlg-portee h3 { margin: 0 0 .8rem; font-size: 1.05rem; }
.dlg-portee p { font-size: .88rem; margin: .8rem 0 .6rem; }
.dlg-actions { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: .9rem; }
.dlg-actions .btn { flex: 1 1 auto; }

/* Les champs d'une fenêtre se suivaient sans respirer : un libellé collé au
   champ précédent, on ne voyait plus où finissait un renseignement et où
   commençait le suivant. Un libellé qui suit un champ ouvre un groupe, il lui
   faut de l'air au-dessus ; à l'intérieur d'un groupe, rien ne change. */
.dlg-portee input + label,
.dlg-portee select + label,
.dlg-portee textarea + label,
.dlg-portee .px-row + label { margin-top: 1rem; }
.dlg-portee textarea { width: 100%; font: inherit; }
.dlg-groupe { margin-top: 1rem; }

/* La fenêtre d'ajout d'un millésime porte cinq renseignements : elle défile
   plutôt que de dépasser de l'écran sur un portable. */
.dlg-portee { max-height: 85dvh; overflow-y: auto; }

/* Le mot de l'établissement sur un millésime : replié par défaut, parce que le
   cas courant est de laisser parler la fiche kelWINE. */
.mot-etab { margin-top: var(--esp-3); border-top: 1px solid var(--line); padding-top: var(--esp-2); }
.mot-etab summary { cursor: pointer; font-size: var(--txt-sm); color: var(--muted); }
.mot-etab summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }
.mot-etab label { display: block; margin-top: var(--esp-2); font-size: var(--txt-sm); }
.mot-etab textarea, .mot-etab input { width: 100%; font: inherit; margin-top: .2rem; }

/* Création d'une section depuis la fenêtre d'ajout d'une formule. Le lien reste
   discret : c'est une sortie de secours, pas le chemin ordinaire. */
.dlg-lien { background: none; border: none; padding: .2rem 0; margin-top: .45rem; cursor: pointer;
  font: inherit; font-size: var(--txt-sm); color: var(--accent); text-decoration: underline; }
.dlg-lien:hover { color: var(--accent-fort); }
.dlg-lien:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }
.dlg-ligne { display: flex; gap: .5rem; align-items: flex-start; }
.dlg-ligne input { flex: 1; }
/* Une même zone dit la confirmation et l'erreur : deux emplacements auraient
   laissé un ancien message sous le nouveau. */
.dlg-msg { font-size: var(--txt-sm); margin: .6rem 0 0; color: var(--succes); }
.dlg-msg.erreur { color: var(--danger); }

/* Suppression d'une contenance ajoutée par l'établissement. Discrète au repos,
   nette au survol et au clavier : l'action efface des prix. */
.px span { display: inline-flex; align-items: center; gap: .25rem; }
.px-suppr { border: none; background: transparent; cursor: pointer; padding: 0 .15rem;
  font-size: .78rem; line-height: 1; color: var(--muted); opacity: .55; border-radius: 4px; }
.px:hover .px-suppr, .px-suppr:focus-visible { opacity: 1; color: var(--danger); }
.px-suppr:focus-visible { outline: 2px solid var(--danger); outline-offset: 1px; }

/* Choix des couleurs à l'ajout d'un vin décliné sous le même nom. */
.couleurs-choix { display: flex; align-items: center; gap: .5rem 1rem; flex-wrap: wrap; margin-top: .5rem; }
.couleurs-choix .fav { cursor: pointer; }

/* --- Lot 4 : logo, filtres de carte, repères de recherche --- */

/* Logo : aperçu à l'échelle réelle du réglage, dans un cadre neutre qui montre
   la place occupée sur la carte cliente. */
.logo-zone { display: flex; align-items: center; gap: 1.2rem; flex-wrap: wrap; }
.logo-cadre { display: flex; align-items: center; justify-content: center;
  min-width: 200px; min-height: 100px; padding: .6rem;
  border: 1px dashed var(--line); border-radius: 8px; background: var(--bg); }
.logo-cadre img { object-fit: contain; }
.logo-cmd { display: flex; flex-direction: column; gap: .5rem; }
.logo-boutons { display: flex; gap: .5rem; flex-wrap: wrap; }
.logo-taille { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.logo-taille input[type="range"] { flex: 1 1 200px; width: auto; padding: 0; }
.logo-taille input[type="number"] { width: 84px; }

/* Filtres de la carte : une grille souple, lisible sur mobile comme sur desktop. */
/* Chaque filtre prend la largeur de son libellé, et la ligne se replie.
   En grille à colonnes égales, la colonne la plus étroite imposait sa largeur
   à toutes : « Toutes contenances » sortait en « Toutes contena ». Un select
   ne réduit pas son texte, il le coupe, et le libellé ne se lisait plus.
   Une largeur en dur aurait vieilli au premier libellé rallongé ; ici la
   largeur vient du contenu, donc elle suit. */
.filtres-carte { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
/* Les champs de la console sont larges de 100 % par défaut, ce qui ne se voyait
   pas dans une colonne de grille. En ligne souple, cela leur ferait prendre
   toute la largeur chacun : ici, la largeur vient du contenu.
   Un filtre plus large que la zone se replie sur sa ligne plutôt que de
   pousser la page en défilement latéral. */
.filtres-carte > * { width: auto; max-width: 100%; }
/* La recherche prend ce qui reste de la ligne : c'est le seul champ où l'on
   écrit, les autres se choisissent dans une liste. */
.filtres-carte input[type="search"] { flex: 1 1 12rem; min-width: 10rem; }
/* Un prix et une année sont courts. Laissés à la taille par défaut d'un champ
   numérique, ils prenaient plus de place que les filtres qui portent du texte. */
.filtres-carte input[type="number"] { width: 8rem; }

/* Résultat de recherche déjà présent sur la carte : signalé sans être bloqué,
   un établissement peut vouloir ajouter un autre millésime de la référence. */
.badge.deja { background: var(--accent2, #e5eefc); color: var(--on-accent, #1c5fd6); }
.res-deja { background: color-mix(in srgb, var(--accent) 7%, transparent); }

/* Croix de suppression d'une seule contenance dans un élément du menu. */
.ip-suppr { border: none; background: transparent; cursor: pointer; padding: 0 .35rem;
  font-size: .82rem; line-height: 1; color: var(--muted); opacity: .6; border-radius: 4px; }
.ip-row:hover .ip-suppr, .ip-suppr:focus-visible { opacity: 1; color: var(--danger); }
.ip-suppr:focus-visible { outline: 2px solid var(--danger); outline-offset: 1px; }

/* Couleurs souhaitées sur une demande d'ajout de vin. */
.dem-couleurs { display: flex; align-items: center; gap: .4rem .9rem; flex-wrap: wrap; margin-top: .5rem; }
.dem-couleurs .crumb { flex-basis: 100%; margin: 0 0 .1rem; }
.dem-couleurs .fav { cursor: pointer; font-size: .85rem; }
/* Les bulles ne sont pas une couleur : un trait les separe du groupe, sinon
   on croit cocher une cinquieme couleur. */
.dem-couleurs .dem-bulles {
  padding-left: .9rem;
  border-left: 1px solid var(--line);
}

/* --- Personnalisation avancée (lot A3) --- */

/* Repliée par défaut : la plupart des établissements se contentent d'un thème.
   Elle s'ouvre d'office si des réglages sont déjà enregistrés. */
.perso-panneau { margin-top: 1rem; border-top: 1px solid var(--line); padding-top: .8rem; }
.perso-panneau summary { cursor: pointer; font-weight: 600; padding: .3rem 0; }
/* Panneau seul dans sa carte : le trait du haut tomberait au ras du bord et
   se lirait comme une ligne perdue au-dessus du titre. Il passe sous le
   titre, où il sépare vraiment quelque chose. */
.perso-panneau--option { margin-top: 0; border-top: 0; padding-top: 0; }
.perso-panneau--option summary { border-bottom: 1px solid var(--line); padding-bottom: .6rem; }
/* Replié, le trait n'a rien à séparer : il ne s'affiche qu'une fois ouvert. */
.perso-panneau--option:not([open]) summary { border-bottom: 0; padding-bottom: .3rem; }
.perso-panneau summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.perso-panneau > .crumb { display: block; margin: .3rem 0 .9rem; }

.perso-grille { display: grid; gap: 1rem; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.perso-grille > div { min-width: 0; }
.perso-grille .crumb { display: block; margin-top: .25rem; }

.perso-couleur { display: flex; gap: .5rem; align-items: center; }
.perso-couleur input[type="color"] { width: 46px; height: 38px; padding: 2px; flex: none; }
.perso-couleur input[type="text"] { font-family: ui-monospace, Consolas, monospace; text-transform: uppercase; }

/* Choix fermés : des boutons, pas un champ libre. */
.perso-choix { display: flex; gap: .35rem; flex-wrap: wrap; }
.perso-choix button {
  font: inherit; font-size: .84rem; cursor: pointer;
  border: 1px solid var(--line); background: #fff; color: var(--ink);
  border-radius: 999px; padding: .35rem .8rem;
}
.perso-choix button:hover { border-color: var(--accent); }
.perso-choix button.on { background: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: 600; }
.perso-choix button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Le garde-fou de contraste parle, il ne corrige pas en silence. */
.perso-avertissement { background: #fdeede; border: 1px solid #f0d4ac; color: var(--warn); margin-top: 1rem; font-size: .88rem; }

.perso-apercu-onglets { display: flex; gap: .35rem; margin-bottom: .5rem; }
.perso-apercu-onglets button {
  font: inherit; font-size: .84rem; cursor: pointer; background: none;
  border: none; border-bottom: 2px solid transparent; padding: .4rem .7rem; color: var(--muted);
}
.perso-apercu-onglets button.on { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }

/* Cadre d'aperçu aux proportions d'un téléphone : c'est là que la carte sera lue. */
.perso-cadre {
  width: 390px; max-width: 100%; height: 660px;
  border: 1px solid var(--line); border-radius: 16px; overflow: hidden;
  background: var(--bg); margin: 0 auto;
}
.perso-cadre iframe { width: 100%; height: 100%; border: 0; display: block; }

/* =====================================================================
   Page de connexion établissement
   =====================================================================
   Écran coupé en deux : formulaire à gauche sur fond clair, photo à droite
   en plein cadre. Le logo et le slogan se posent en haut de la photo, là où
   le fond est sombre et où le texte blanc tient sans caisson.

   Tout est préfixé cx- et ne sert qu'ici. « Mot de passe oublié » et la
   réinitialisation gardent la mise en page sobre de login-card.
   ===================================================================== */

/* Couleur de marque de cette page. Ce n'est pas le bordeaux de la console :
   elle vit à part, avant toute session. */
.cx {
  --cx-marque: #bf336a;
  --cx-marque-fonce: #a72a5b;
  --cx-encre: #2A1F24;
  --cx-gris: #8C7F85;
  --cx-fond: #F7F4F5;
  --cx-bord: #E7DBDF;

  display: flex;
  min-height: 100dvh;
}

/* La coquille impose une colonne centrée et des marges : la connexion prend
   tout l'écran, elle. Restreint à l'état déconnecté, donc sans effet ailleurs. */
.shell[data-chrome="off"] > .colonne > .container:has(.cx) {
  max-width: none;
  margin: 0;
  padding: 0;
}

/* --- Gauche : le formulaire ------------------------------------------- */
.cx-form {
  flex: 1;
  background: var(--cx-fond);
  display: flex; flex-direction: column;
  padding: 2.75rem 3.25rem;
  color: var(--cx-encre);
}
.cx-marque {
  font-family: 'Dosis', system-ui, sans-serif;
  font-weight: 700; font-size: 1.375rem; letter-spacing: .02em;
  color: var(--cx-encre);
}
.cx-marque b { font-weight: 700; color: var(--cx-marque); }

/* margin auto sur l'axe vertical : le bloc se centre sans hauteur figée. */
.cx-bloc { margin: auto 0; width: 100%; max-width: 360px; align-self: center; }
.cx-bloc h1 {
  font-family: 'Fraunces', Georgia, serif;
  font-weight: 600; font-size: 2rem; line-height: 1.1;
  letter-spacing: -.01em; color: var(--cx-encre); margin: 0;
}
.cx-intro {
  color: var(--cx-gris); font-size: .906rem; line-height: 1.5;
  margin: .5rem 0 1.875rem;
}

.cx-champ { margin-bottom: 1.125rem; }
.cx-champ label {
  display: block; font-size: .781rem; font-weight: 600;
  color: var(--cx-encre); margin-bottom: .437rem;
}
.cx-saisie { position: relative; }
.cx-saisie input {
  width: 100%; font: inherit; font-size: .875rem; color: var(--cx-encre);
  background: #fff; border: 1px solid var(--cx-bord); border-radius: 11px;
  padding: .812rem .937rem;
  transition: border-color .15s, box-shadow .15s;
}
/* De la place pour l'œil, sinon le texte passe dessous. */
.cx-saisie:has(.cx-oeil) input { padding-right: 2.75rem; }
.cx-saisie input::placeholder { color: #B7ABB0; }
.cx-saisie input:focus {
  outline: none;
  border-color: var(--cx-marque);
  box-shadow: 0 0 0 3px rgba(191, 51, 106, .18);
}

.cx-oeil {
  position: absolute; right: .812rem; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center;
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--cx-gris);
}
.cx-oeil svg { width: 19px; height: 19px; }
.cx-oeil:hover { color: var(--cx-encre); }
.cx-oeil:focus-visible { outline: 2px solid var(--cx-marque); outline-offset: 2px; border-radius: 4px; }

.cx-oubli { display: flex; justify-content: flex-end; margin: -.25rem 0 1.375rem; }
.cx-oubli a {
  font-size: .781rem; font-weight: 500; color: var(--cx-marque); text-decoration: none;
}
.cx-oubli a:hover { text-decoration: underline; }

.cx-valider {
  width: 100%; font: inherit; font-size: .906rem; font-weight: 600;
  color: #fff; background: var(--cx-marque);
  border: 0; border-radius: 11px; padding: .875rem;
  cursor: pointer; transition: background .15s;
  display: flex; align-items: center; justify-content: center; gap: .5rem;
}
.cx-valider:hover { background: var(--cx-marque-fonce); }
.cx-valider:focus-visible { outline: 2px solid var(--cx-marque-fonce); outline-offset: 2px; }
.cx-valider svg { width: 17px; height: 17px; }

.cx-pied {
  font-size: .719rem; color: var(--cx-gris); text-align: center; margin: 1.5rem 0 0;
}
/* Le bandeau d'erreur du formulaire, ramené à l'échelle de cette page. */
.cx-bloc .alert { margin-bottom: 1rem; font-size: .812rem; }

/* --- Droite : la photo ------------------------------------------------ */
.cx-photo { flex: 1.05; position: relative; background: #000; overflow: hidden; }
/* Recadrage : le verre et le filet de vin restent dans le cadre quelle que
   soit la hauteur de la fenêtre.

   Hors du flux : la maquette fixait la hauteur du cadre, pas nous. Avec un
   parent de hauteur automatique, height: 100% retombe sur auto et l'image
   impose sa propre hauteur, 1043 px pour 820 de large. La page dépassait
   alors la fenêtre de plusieurs dizaines de pixels. */
.cx-photo > img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; display: block;
  object-fit: cover; object-position: 60% 55%;
}
.cx-calque {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center;
  padding-top: 4.375rem;
  /* Voile en haut seulement : le bas de la photo est déjà noir, et un voile
     sur toute la hauteur ternirait le verre. */
  background: linear-gradient(to bottom, rgba(0, 0, 0, .55) 0%, rgba(0, 0, 0, 0) 34%);
}
.cx-logo { width: 150px; height: auto; }
.cx-slogan {
  font-family: 'Montserrat', system-ui, sans-serif;
  font-weight: 500; font-size: 1.187rem; letter-spacing: .02em;
  color: #fff; margin: 1rem 0 0;
  text-shadow: 0 2px 14px rgba(0, 0, 0, .5);
}

/* --- Écran étroit : la photo passe au-dessus, en bandeau -------------- */
@media (max-width: 820px) {
  .cx { flex-direction: column-reverse; min-height: 100dvh; }
  .cx-photo { flex: none; min-height: 230px; }
  .cx-calque { padding-top: 2.125rem; }
  .cx-logo { width: 112px; }
  .cx-slogan { font-size: 1rem; }
  .cx-form { padding: 2.25rem 1.875rem 2.75rem; }
  .cx-bloc { margin: 1.5rem 0 0; }
}

/* Le réglage système est respecté : aucune transition pour qui n'en veut pas
   (déjà posé dans design.css, rappelé ici pour les transitions propres). */
@media (prefers-reduced-motion: reduce) {
  .cx-saisie input, .cx-valider { transition: none; }
}

/* Le coup de cœur et la suggestion d'apéritif vont par paire, un millésime à
   la fois : les serrer évite de croire que l'icône appartient au millésime
   suivant. */
.fav-paire { display: inline-flex; align-items: center; gap: .35rem; }
/* Deux gestes distincts sur la même ligne : le coup de cœur, qui met le vin en
   avant sur la carte du client, et la suggestion à l'apéritif, qui le range
   dans la vitrine. Collés, la case et l'icône se lisaient comme une seule
   commande. Un trait fin les sépare, le même que partout ailleurs.
   Il est posé comme élément et non en bordure de la bascule : celle-ci prend
   un fond arrondi au survol, qui aurait avalé le trait. */
.fav-sep { flex: none; width: 1px; height: 1.15rem; background: var(--line); }

/* --- Personnalisation en deux colonnes -------------------------------- */
/* L'établissement ne voyait ses changements qu'en faisant défiler. Réglages à
   gauche, aperçu à droite, et l'aperçu suit le défilement : le changement se
   voit au moment où on le fait. */
.perso-deux-colonnes {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 390px);
  gap: 1.6rem;
  align-items: start;
}
.perso-reglages { min-width: 0; }
.perso-vitrine { min-width: 0; position: sticky; top: var(--esp-4); }
.perso-vitrine > label { display: block; margin-bottom: .4rem; }

/* Sous 900 px, deux colonnes de 390 px ne tiennent plus : l'aperçu repasse
   dessous, et cesse de suivre le défilement puisqu'il n'est plus à côté. */
@media (max-width: 900px) {
  .perso-deux-colonnes { grid-template-columns: 1fr; }
  .perso-vitrine { position: static; }
}

/* --- Textes de l'accueil ---------------------------------------------- */
.textes-grille {
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  margin-top: .6rem;
}
.textes-grille > div { min-width: 0; }
.textes-grille .crumb { display: block; margin-top: .25rem; }

/* --- Icônes de l'accueil ----------------------------------------------- */
.icones-grille {
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  margin-top: .6rem;
}
.icones-place { min-width: 0; }
.icones-choix { display: flex; gap: .5rem; margin-top: .3rem; }
/* Le choix se voit au cadre, pas à la couleur du dessin : l'icône doit
   s'afficher telle que le client la verra. */
.icones-choix button {
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px; padding: 0;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--bg2); color: var(--ink); cursor: pointer;
  transition: border-color .12s ease, background-color .12s ease;
}
.icones-choix button:hover { border-color: var(--accent); }
.icones-choix button.on {
  border-color: var(--accent); border-width: 2px;
  background: color-mix(in srgb, var(--accent) 10%, var(--bg2));
}
.icones-choix button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* --- Éditeur d'affiche ------------------------------------------------- */
/* Réglages à gauche, aperçu à droite, comme la personnalisation : on voit ce
   qu'on change au moment où on le change. */
.af-editeur {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 320px);
  gap: 1.6rem;
  align-items: start;
  margin-top: .6rem;
}
.af-reglages { min-width: 0; }
.af-vitrine { min-width: 0; position: sticky; top: var(--esp-4); }
.af-vitrine > label { display: block; margin-bottom: .4rem; }
.af-vitrine .crumb { display: block; margin-top: .5rem; }

/* Sous 900 px, deux colonnes ne tiennent plus : l'aperçu repasse dessous. */
@media (max-width: 900px) {
  .af-editeur { grid-template-columns: 1fr; }
  .af-vitrine { position: static; }
}

/* Photo d'affiche en deçà de la résolution conseillée : on prévient sans
   refuser. Le ton reste celui d'un avertissement, pas d'une erreur. */
.af-alerte { color: var(--warn); }

/* Carte papier : cocher ce qu'on réimprime. Les cases sont nombreuses, elles
   se rangent en grille souple plutôt qu'en colonne interminable. */
.cp-groupe { margin-top: 1rem; }
.cp-modeles { margin-top: .4rem; }
.cp-cases { display: flex; flex-wrap: wrap; gap: .3rem 1.2rem; }
.cp-case { display: inline-flex; align-items: center; gap: .4rem; margin: 0;
  font-weight: 400; cursor: pointer; }
.cp-case input { width: auto; margin: 0; accent-color: var(--accent-fort); }

/* Mes supports : le QR d'un côté, le lien de l'autre. Sous 720 px la colonne
   du lien passe dessous, elle ne se comprime pas en bande illisible. */
.sup-duo { display: grid; grid-template-columns: auto 1fr; gap: 1.6rem; align-items: start;
  margin-top: 1rem; }
.sup-col { min-width: 0; display: flex; flex-direction: column; gap: .8rem; align-items: flex-start; }
.sup-qr { width: 200px; height: 200px; border: 1px solid var(--line); border-radius: 8px;
  background: #fff; }
.sup-duo .kv { margin: 0; }
.sup-duo a { overflow-wrap: anywhere; }
@media (max-width: 720px) { .sup-duo { grid-template-columns: 1fr; } }

/* Tutoriel tablette. Une fenêtre large : deux systèmes côte à côte se
   comparent, l'un sous l'autre ils s'oublient. */
.dlg-tuto { border: none; border-radius: var(--radius); padding: 0; max-width: 860px; width: 92vw;
  max-height: 90vh; background: var(--surface); color: var(--ink); overflow: hidden;
  display: flex; flex-direction: column; }
.dlg-tuto::backdrop { background: rgba(0, 0, 0, .45); }
.tuto-fermer { position: absolute; top: .7rem; right: .7rem; width: 2.2rem; height: 2.2rem;
  border-radius: 50%; background: var(--tint); border: none; color: inherit; font-size: 1rem;
  cursor: pointer; z-index: 2; }
.tuto-corps { padding: 1.6rem 1.6rem .4rem; overflow-y: auto; }
.tuto-corps h3 { margin: 0 0 .4rem; font-size: 1.25rem; }
.tuto-intro { margin: 0 0 1rem; color: var(--muted); font-size: var(--txt-sm); }
.tuto-lien { margin: 0 0 1.4rem; padding: .7rem .9rem; background: var(--tint);
  border-radius: var(--r-sm); font-size: var(--txt-sm); }
.tuto-lien code { overflow-wrap: anywhere; }
.tuto-duo { display: grid; grid-template-columns: 1fr 1fr; gap: 1.6rem; }
@media (max-width: 700px) { .tuto-duo { grid-template-columns: 1fr; } }
.tuto-col h4 { margin: 0 0 .8rem; font-size: 1rem; display: flex; align-items: center; gap: .5rem;
  color: var(--accent-fort); }
/* Les étapes sont numérotées à la main : le numéro est un repère qu'on montre
   du doigt à côté d'une tablette, il doit rester lisible. */
.tuto-etapes { list-style: none; counter-reset: etape; margin: 0; padding: 0; }
.tuto-etapes li { counter-increment: etape; position: relative; padding: 0 0 .9rem 2.2rem; }
.tuto-etapes li::before { content: counter(etape); position: absolute; left: 0; top: 0;
  width: 1.6rem; height: 1.6rem; border-radius: 50%; background: var(--accent-fort);
  color: var(--on-accent); font-size: .78rem; font-weight: 600;
  display: flex; align-items: center; justify-content: center; }
.tuto-etapes b { display: block; font-size: var(--txt-sm); }
.tuto-etapes span { display: block; font-size: var(--txt-sm); color: var(--muted); margin-top: .15rem; }
.tuto-sortie { margin: .2rem 0 0; padding: .7rem .9rem; background: var(--tint-soft, var(--tint));
  border-left: 3px solid var(--accent); border-radius: 0 var(--r-sm) var(--r-sm) 0;
  font-size: var(--txt-sm); }
.tuto-note { margin: 1.4rem 0 .6rem; font-size: var(--txt-sm); color: var(--muted); }
.tuto-conseils { margin: 0 0 1rem; padding-left: 1.1rem; font-size: var(--txt-sm); color: var(--muted); }
.tuto-conseils li { margin-bottom: .3rem; }
.tuto-pied { display: flex; gap: .6rem; justify-content: flex-end; flex-wrap: wrap;
  padding: 1rem 1.6rem; border-top: 1px solid var(--line); background: var(--tint); }

/* À l'impression, seule la fenêtre part sur le papier : la console autour
   n'a rien à y faire. */
@media print {
  body.impression-tuto > *:not(.dlg-tuto) { display: none !important; }
  body.impression-tuto .dlg-tuto { position: static; max-height: none; width: auto; max-width: none;
    box-shadow: none; overflow: visible; }
  body.impression-tuto .tuto-corps { overflow: visible; }
  body.impression-tuto .tuto-fermer,
  body.impression-tuto .tuto-pied { display: none !important; }
}

/* Sélecteur de vins conseillés. La liste peut être longue : elle défile dans
   la fenêtre plutôt que de pousser les boutons hors de l'écran. */
.dlg-vins { max-width: 520px; width: 92vw; }
.vins-liste { max-height: 46vh; overflow-y: auto; margin-top: .6rem;
  border: 1px solid var(--line); border-radius: var(--r-sm); }
.vins-option { display: flex; align-items: flex-start; gap: .6rem; margin: 0;
  padding: .5rem .7rem; cursor: pointer; font-weight: 400;
  border-bottom: 1px solid var(--line); }
/* Le trait de separation tombe sous la derniere ligne VISIBLE : filtrer ne
   doit pas laisser un trait flottant en bas de liste. */
.vins-option:last-child, .vins-option--dernier { border-bottom: none; }
.vins-filtres { display: grid; gap: .5rem; margin-top: .7rem;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); align-items: center; }
.vins-filtres input, .vins-filtres select { min-width: 0; }
.vins-resultat { margin: .45rem 0 0; }
.vins-vide { margin: .6rem 0 0; text-align: center; }
/* Un millésime masqué reste lisible et modifiable, mais se distingue au premier
   coup d'œil de ceux qui sont en vente. */
.mill-masquee { opacity: .62; }
.mill-masquee .badge.inactif { opacity: 1; }
.vins-option:hover { background: var(--tint); }
/* Une case éteinte parce que la limite est atteinte doit se voir : sans cela
   le clic sans effet passe pour une panne. */
.vins-option:has(input:disabled) { opacity: .5; cursor: not-allowed; }
.vins-option input { width: auto; margin: .2rem 0 0; accent-color: var(--accent-fort); }
.vins-option b { display: block; font-size: var(--txt-sm); }
.vins-option small { display: block; color: var(--muted); font-size: var(--txt-xs); }
.vins-option .dot { margin-right: .3rem; }

/* =====================================================================
   Plusieurs établissements : le sélecteur et la liste des membres
   ===================================================================== */

/* La pastille du compte devient un bouton quand il y a un choix à faire.
   Un seul établissement : elle reste ce qu'elle était, inerte et sans
   chevron. C'est la règle de tout le lot, rien ne change pour qui n'a
   qu'un restaurant. */
.user-chip.chip-choix {
  cursor: pointer;
  border-radius: var(--radius);
  padding: .2rem .5rem;
  margin: -.2rem -.5rem;
  transition: background-color .12s ease;
}
.user-chip.chip-choix:hover { background: var(--tint); }
.user-chip.chip-choix:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.user-chip.chip-choix #chip-chevron { font-size: .7rem; color: var(--muted); margin-left: .1rem; }

/* La liste des membres : un établissement par ligne sous le nom, avec ses
   droits en étiquettes. Une matrice personne × droit se lit mal en texte
   suivi ; elle se lit d'un coup sous cette forme. */
.membre-etab { margin: .15rem 0; display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; }
.membre-etab strong { font-weight: 600; margin-right: .2rem; }
.wa-tag-plat {
  display: inline-block;
  background: var(--tint); color: var(--muted);
  border-radius: 999px; padding: .05rem .5rem;
  font-size: var(--txt-xs); white-space: nowrap;
}
