/* ============================================================
   RQDT — Espace adhérent (kit « studio » du design system)
   ------------------------------------------------------------
   On passe de la brochure à l'outil : plus dense, plus posé, du
   mono pour les identifiants et les valeurs. Aucune couleur en
   dur — tout vient de tokens.css.

   Les maquettes n'ont aucun @media (le mobile y est une branche
   JS dans un cadre de 392 px) : les coupures sont écrites ici.
   ============================================================ */

/* `tokens.css` ne pose aucun `box-sizing` global, et il ne se modifie pas à la
   main (c'est le design system). Sans cette ligne, un champ à `min-height:44px`
   plus 22 px de remplissage mesure 68 px, et un `width:100%` déborde de sa
   colonne. Constaté en ligne, invisible aux tests. */
.acces *,
.compte-nav *,
.compte-page * { box-sizing: border-box; }

/* Repéré en passant le 2026-08-22 : cette feuille est la seule chargée sur un
   écran de compte qui n'étend pas `boutique/base_boutique.html` (« Mon
   compte », « Sécurité »…) — sans elle, le label de la barre de recherche de
   l'en-tête (`comptes/base_compte.html`, posé sur toutes ces pages) restait
   affiché en clair au lieu de rester réservé au lecteur d'écran. Copiée telle
   quelle depuis boutique.css/gestion.css : une seule définition, pas une
   version qui diverge. */
.visuellement-cache {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ── Écrans hors connexion : formulaire à gauche, marque à droite ── */

.acces {
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-height: 100vh;
  background: var(--bg);
}

.acces__panneau {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--space-16) var(--space-12);
}

.acces__contenu {
  width: 100%;
  max-width: 27rem;
  margin: 0 auto;
}

.acces__logo { display: inline-flex; align-items: center; }
.acces__logo img { height: 34px; width: auto; }

.acces__titre {
  margin-top: var(--space-8);
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
}

.acces__chapo {
  margin-top: var(--space-3);
  color: var(--fg-muted);
  /* 16 px : c'est du texte courant, et les adhérents ont de 25 à 80 ans. */
  font-size: var(--fs-body);
  line-height: 1.6;
}

.acces__pied {
  margin-top: var(--space-8);
  font-size: var(--fs-body-sm);
  color: var(--fg-muted);
}

/* Le panneau de marque : neutre profond, halo terracotta, jamais de dégradé
   bleu-violet ni de glassmorphisme (règles dures du design system). */
.acces__marque {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-12);
  padding: var(--space-16);
  background: var(--color-neutral-900);
  color: #fff;
}

.acces__halo {
  position: absolute;
  top: -120px;
  right: -120px;
  width: 480px;
  height: 480px;
  border-radius: 50%;
  background: radial-gradient(circle, var(--color-primary-500) 0%, transparent 70%);
  opacity: 0.35;
  filter: blur(20px);
  pointer-events: none;
}

/* `:not(.acces__halo)` n'est pas une coquetterie : sans lui, cette règle
   repose le halo en `relative`, il redevient un élément de la colonne flex et
   pousse tout le contenu de 500 px vers le bas. Vu en ligne, pas en test. */
.acces__marque > *:not(.acces__halo) { position: relative; z-index: 1; }
.acces__marque img { height: 32px; width: auto; }

.acces__accroche {
  margin-top: var(--space-8);
  max-width: 22ch;
  font-size: var(--fs-h2);
  line-height: 1.06;
  color: #fff;
}

.acces__points { display: flex; flex-direction: column; gap: var(--space-5); }

.acces__point { display: flex; gap: var(--space-4); align-items: flex-start; }

.acces__puce {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border-radius: var(--radius-md);
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.14);
  display: grid;
  place-items: center;
  color: var(--color-primary-300);
}

.acces__point strong { display: block; font-size: var(--fs-body-sm); font-weight: 600; }

.acces__point span {
  display: block;
  margin-top: 2px;
  font-size: var(--fs-caption);
  line-height: 1.55;
  color: var(--color-neutral-300);
}

/* Un lien dans le panneau de marque : sans cette règle, le navigateur y pose
   son bleu-violet par défaut — illisible sur `neutral-900`, et hors charte
   (aucun bleu dans le design system). Vu à l'écran sur `/django/`, dont
   l'encart renvoie vers l'espace de gestion. */
.acces__marque a {
  color: var(--color-primary-300);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.acces__marque a:hover { color: #fff; }

/* ── Écrans connectés : barre supérieure + contenu ── */

/* La barre est pleine terracotta, logo et liens en blanc. Elle ne se translucide
   plus : un fond couleur derrière du contenu qui défile a besoin d'être opaque,
   sinon le texte de la page transparaît sous les liens. */
.compte-nav {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--color-primary-500);
  border-bottom: 1px solid var(--color-primary-600);
}

.compte-nav__inner {
  max-width: 76rem;
  margin: 0 auto;
  padding: var(--space-2) var(--space-6);
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
}

/* Le logo blanc est un fichier à part (`logo_rqdt_white.svg`), pas un filtre
   posé sur le logo de couleur : un `invert()` retournerait aussi les nuances
   du soleil. */
.compte-nav__logo img { height: 38px; width: auto; display: block; }
.compte-nav__logo { display: block; border-radius: var(--radius-sm); }
.compte-nav__logo:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
.compte-nav__espace { flex: 1 1 auto; }

.compte-nav__liens { display: flex; align-items: center; gap: var(--space-1); flex-wrap: wrap; }

.compte-nav__liens a,
.compte-nav__liens button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: 0 var(--space-3);
  border: none;
  background: transparent;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  font-weight: 500;
  color: rgba(255, 255, 255, 0.92);
  text-decoration: none;
  cursor: pointer;
}

.compte-nav__liens a:hover,
.compte-nav__liens button:hover {
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  text-decoration: none;
}

.compte-nav__liens a:focus-visible,
.compte-nav__liens button:focus-visible,
.menu-compte summary:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* La page en cours est un jeton plein : sur un fond déjà coloré, un simple
   changement de teinte ne se voit pas. */
.compte-nav__liens a[aria-current='page'] {
  background: var(--surface);
  color: var(--color-primary-700);
  font-weight: 600;
}

/* Le numéro d'adhérent est une identité, pas une mention légale : il se lit de
   loin, en gras. */
.compte-nav__identite {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--fs-body);
  font-weight: 700;
  letter-spacing: 0.04em;
  color: #fff;
}

/* ── La recherche, fixe dans la barre ──
   Retour de Jérôme du 2026-08-20 : à n'importe quel moment, sans passer par
   « Le catalogue » (qui a disparu). Une deuxième ligne plutôt qu'entassée
   dans `.compte-nav__inner` — c'est elle qui « élargit un peu la barre du
   haut », comme il le proposait lui-même. */
.compte-nav__recherche {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  max-width: 76rem;
  margin: 0 auto;
  padding: 0 var(--space-6) var(--space-3);
}
/* Retour d'Arnaud du 2026-08-22 : le champ répond maintenant pendant la
   frappe (`.vive`, plus bas) — c'est cette enveloppe qui est le flex item,
   l'input remplit l'enveloppe plutôt que la barre directement. */
.compte-nav__recherche .vive { flex: 1 1 auto; min-width: 0; }
.compte-nav__recherche input {
  width: 100%;
  min-height: 44px;
  padding: 0 var(--space-4);
  border: none;
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.92);
  color: var(--fg-default);
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
}
.compte-nav__recherche input::placeholder { color: var(--fg-muted); }
.compte-nav__recherche input:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.compte-nav__recherche button {
  min-height: 44px;
  padding: 0 var(--space-4);
  border: none;
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.16);
  color: #fff;
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  font-weight: 500;
  cursor: pointer;
}
.compte-nav__recherche button:hover { background: rgba(255, 255, 255, 0.26); }

/* ── La recherche vive : le panneau qui s'ouvre sous le champ ──
   Le fragment vient du serveur (`boutique/partials/recherche_vive.html`) ; ces
   règles ne font que le poser. Il est en `position: absolute` pour ne pas
   pousser la page à chaque frappe — un écran qui saute pendant qu'on tape est
   inutilisable. Posé ici (pas dans `boutique.css`) : la barre de recherche
   qui le déclenche est dans l'en-tête du compte, chargée sur bien plus que
   les seules pages de boutique. */

.vive { position: relative; min-width: 0; }

.vive__panneau {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% + 6px);
  z-index: 25;
  max-height: 60vh;
  overflow-y: auto;
  padding: var(--space-2);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
}
.vive__panneau[hidden] { display: none; }

.vive__liste { list-style: none; margin: 0; padding: 0; }

.vive__ligne a {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 56px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--fg-default);
  text-decoration: none;
}
.vive__ligne a:hover,
.vive__ligne a:focus-visible { background: var(--color-neutral-50); text-decoration: none; outline: none; }
.vive__ligne a:focus-visible { box-shadow: inset 0 0 0 2px var(--color-primary-500); }

.vive__vignette {
  position: relative;
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  overflow: hidden;
  border-radius: var(--radius-sm);
/* ⛔ BLANC, et non le crème habituel — décision d'Arnaud du 01/09/2026.
   Les photos du catalogue viennent de l'ancienne boutique et sont **sur fond
   blanc** : on a renoncé à les détourer (trop inégal sur 1 700 photos, et
   chaque traitement coûtait une génération de WebP). Sur un cadre crème, elles
   forment un rectangle blanc bien visible. Le blanc pur est ici légitime : la
   charte le réserve aux SURFACES, et un cadre d'image en est une — c'est le
   fond de PAGE qui doit rester crème. */
  border: 1px solid var(--border-soft);
  background: var(--surface);
}
/* `position: absolute` : même piège qu'à `.fiche__photo img` — une hauteur en
   pourcentage ne se résout pas dans cette grille `place-items: center`. */
.vive__vignette img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.vive__identite { min-width: 0; flex: 1 1 auto; }
.vive__ugs { font-size: var(--fs-caption); color: var(--fg-subtle); letter-spacing: 0.03em; }
.vive__nom {
  display: block;
  font-weight: 600;
  color: var(--fg-strong);
  /* Un nom long ne pousse pas le prix hors du panneau : il se coupe, lui. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vive__meta {
  display: block;
  font-size: var(--fs-caption);
  color: var(--fg-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vive__droite { flex-shrink: 0; display: flex; align-items: center; gap: var(--space-3); }
.vive__prix { font-weight: 500; color: var(--fg-strong); }

.vive__tout {
  display: block;
  margin-top: var(--space-2);
  padding: var(--space-3);
  border-top: 1px solid var(--border-soft);
  font-size: var(--fs-body-sm);
  font-weight: 600;
  color: var(--color-primary-700);
  text-align: center;
  text-decoration: none;
}
.vive__tout:hover { background: var(--color-primary-50); text-decoration: none; }

.vive__vide { padding: var(--space-4); color: var(--fg-muted); font-size: var(--fs-body-sm); }

/* Sous 620 px, le prix et la pastille passent SOUS le nom. Sur une ligne, ils
   prenaient la moitié des 390 px et il ne restait au produit que « Croquett… »
   — parfois une seule lettre. Vu à l'écran, sur staging. */
@media (max-width: 620px) {
  .vive__ligne a { flex-wrap: wrap; }
  /* Base à ZÉRO, sinon le nom (qui passe à la ligne ici) sert de largeur de
     départ, dépasse la place restante, et c'est la VIGNETTE qui se retrouve
     seule sur sa ligne. */
  .vive__identite { flex: 1 1 0; }
  .vive__droite {
    flex: 1 1 100%;
    /* Aligné sous le texte : 44 px de vignette, plus l'écart. */
    margin-left: calc(44px + var(--space-3));
  }
  /* Le nom se déplie, mais sur DEUX lignes au plus — comme les tuiles du
     catalogue. Au-delà, une seule réponse mangeait la moitié du panneau. */
  .vive__nom {
    white-space: normal;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
  }
}

/* ── Le menu du compte ──
   Un `<details>` natif : il s'ouvre au clic et au clavier sans une ligne de
   JavaScript. Le script ne sert qu'à le refermer quand on clique ailleurs. */

/* `margin-left: auto` : un compte de gestion a huit entrées, la barre passe
   alors sur deux lignes (c'était déjà le cas avant). Le menu reste collé à
   droite sur la ligne où il tombe, au lieu de flotter au milieu de nulle part. */
.menu-compte { position: relative; margin-left: auto; }
.menu-compte summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: 0 var(--space-3);
  border-radius: var(--radius-sm);
  font-size: var(--fs-body-sm);
  font-weight: 500;
  color: rgba(255, 255, 255, 0.92);
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.menu-compte summary::-webkit-details-marker { display: none; }
.menu-compte summary:hover { background: rgba(255, 255, 255, 0.16); color: #fff; }
.menu-compte summary[aria-current='true'] {
  background: var(--surface);
  color: var(--color-primary-700);
  font-weight: 600;
}
.menu-compte__fleche { transition: transform var(--dur-fast) var(--ease-out); }
.menu-compte[open] summary { background: rgba(255, 255, 255, 0.16); color: #fff; }
.menu-compte[open] .menu-compte__fleche { transform: rotate(180deg); }

.menu-compte__panneau {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 40;
  min-width: 15rem;
  padding: var(--space-2);
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
}

.menu-compte__panneau a,
.menu-compte__panneau button {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: 44px;
  padding: 0 var(--space-3);
  border: none;
  background: transparent;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  font-weight: 500;
  color: var(--fg-default);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.menu-compte__panneau a:hover,
.menu-compte__panneau button:hover { background: var(--color-neutral-100); color: var(--fg-strong); text-decoration: none; }
.menu-compte__panneau a[aria-current='page'] { background: var(--color-primary-50); color: var(--color-primary-700); }
/* La déconnexion est une action, pas une page : un filet la sépare des trois
   écrans du compte. */
.menu-compte__panneau form {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--border-soft);
}
.menu-compte__panneau i { width: 18px; height: 18px; flex-shrink: 0; color: var(--fg-subtle); }

.compte-page { max-width: 76rem; margin: 0 auto; padding: var(--space-10) var(--space-6) var(--space-20); }

.compte-page__entete { display: flex; align-items: flex-end; gap: var(--space-4); flex-wrap: wrap; }
.compte-page__entete h1 { font-size: var(--fs-h2); line-height: var(--lh-h2); }
.compte-page__entete p { color: var(--fg-muted); font-size: var(--fs-body-sm); }

/* ── Cartes ── */

.grille { display: grid; gap: var(--space-5); }
.grille--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grille--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grille--principale { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); align-items: start; }

.carte {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  padding: var(--space-6);
}

.carte--sobre { background: var(--surface-sunk); box-shadow: none; }

.carte__titre {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-subtle);
  margin-bottom: var(--space-4);
}

.valeur {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-h3);
  font-weight: 500;
  color: var(--fg-strong);
  letter-spacing: -0.01em;
}

.valeur--absente { font-size: var(--fs-h5); color: var(--fg-subtle); }

.mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

.note { font-size: var(--fs-caption); line-height: 1.5; color: var(--fg-subtle); }
.note--avertissement { color: var(--color-warning-700); }

.paire { display: flex; justify-content: space-between; gap: var(--space-4); padding: var(--space-3) 0; border-bottom: 1px solid var(--border-soft); }
.paire:last-child { border-bottom: none; }
.paire dt { font-size: var(--fs-body-sm); color: var(--fg-muted); }
.paire dd { margin: 0; font-size: var(--fs-body-sm); font-weight: 500; color: var(--fg-strong); text-align: right; }

/* ── Badges ── */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  font-size: var(--fs-caption);
  font-weight: 600;
  background: var(--color-neutral-100);
  color: var(--fg-default);
  white-space: nowrap;
}

.badge--succes { background: var(--color-success-50); color: var(--color-success-700); }
.badge--attente { background: var(--color-warning-50); color: var(--color-warning-700); }
.badge--info { background: var(--color-info-50); color: var(--color-info-700); }
.badge--neutre { background: var(--color-neutral-100); color: var(--fg-muted); }
.badge--primaire { background: var(--color-primary-50); color: var(--color-primary-700); }
/* Le seul badge à fond plein : « Bio » n'est pas un état (stock, quota) comme
   les autres, c'est un choix de l'adhérent à repérer d'un coup d'œil — un
   même ton pastel que « En stock » se serait perdu à côté. L'icône Lucide
   remplace la pastille : jamais d'emoji dans l'interface. */
.badge--bio {
  background: var(--color-accent-600);
  color: var(--color-neutral-0);
  font-weight: 700;
}
.badge--bio svg { width: 12px; height: 12px; stroke-width: 2.25; }

/* ── Tableau d'historique ── */

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

.tableau th {
  text-align: left;
  padding: var(--space-3) var(--space-4);
  background: var(--surface-sunk);
  border-bottom: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-subtle);
  white-space: nowrap;
}

.tableau td {
  padding: var(--space-4);
  border-bottom: 1px solid var(--border-soft);
  font-size: var(--fs-body-sm);
  color: var(--fg-default);
  vertical-align: middle;
}

.tableau tr:last-child td { border-bottom: none; }
.tableau .nombre { text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

.defilant { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--surface); }

/* ── Formulaires ── */

.formulaire { display: flex; flex-direction: column; gap: var(--space-5); }
.formulaire__grille { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-5); }

.champ { display: flex; flex-direction: column; gap: 6px; }
.champ--large { grid-column: 1 / -1; }

.champ > label {
  font-size: var(--fs-label);
  font-weight: 500;
  color: var(--fg-default);
}

/* ⚠️ **Corrigé à la racine, pas type par type** (même famille que le piège
   n° 60 et que DEC-059). L'énumération `text · email · tel · password`
   laissait sans habillage tout ce qui est arrivé depuis : `number` aux
   encaissements, `date` et `time` aux créneaux du drive — champs de 19 px de
   haut, sans bordure, sous le plancher tactile de 44 px. Un champ qu'on
   ajoutera demain serait le suivant.

   La règle décrit donc ce qu'elle veut vraiment : **tout champ de saisie**,
   sauf la case et le bouton radio, qui ne sont pas des boîtes de texte et
   n'ont ni à prendre toute la largeur ni à faire 44 px de haut. */
.champ input:not([type='checkbox']):not([type='radio']):not([type='hidden']),
.champ select,
.champ textarea {
  width: 100%;
  min-height: 44px;
  padding: 11px 14px;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  color: var(--fg-strong);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  outline: none;
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}

.champ input:focus,
.champ select:focus,
.champ textarea:focus {
  border-color: var(--color-primary-400);
  box-shadow: var(--focus-ring);
}

.champ--erreur input,
.champ--erreur select { border-color: var(--color-error-500); }

.champ__aide { font-size: var(--fs-caption); line-height: 1.5; color: var(--fg-subtle); }
.champ__erreur { font-size: var(--fs-caption); line-height: 1.5; color: var(--color-error-700); font-weight: 500; }

/* ⚠️ **La cible tactile d'une case, corrigée à la racine** (lot 14).

   Le plancher tactile du projet est de 44 px depuis le lot 4, et la coche de
   ce kit en fait 18. Le piège n° 69 l'avait relevé sur les créneaux du drive
   et corrigé LÀ, au cas par cas, avec `label.cible-tactile` — donc il est
   revenu au premier écran neuf qui a repris `.champ--case` : la fiche produit
   en porte cinq cases, mesurées à 18 px sur un écran de 375.

   La correction tient en une ligne, et elle vaut pour TOUS les écrans qui
   emploient ce kit : le `<label>` est lié par `for=`, donc **toute sa boîte**
   bascule la case. Lui donner 44 px de haut fait de lui la cible, sans
   déplacer la coche ni changer un seul gabarit. La marge de la coche la
   recentre sur la première ligne du libellé. */
.champ--case { flex-direction: row; align-items: flex-start; gap: var(--space-3); }
.champ--case input { margin-top: 13px; width: 18px; height: 18px; accent-color: var(--color-primary-500); flex-shrink: 0; }
.champ--case label {
  display: flex;
  align-items: center;
  min-height: 44px;
  font-size: var(--fs-body-sm);
  font-weight: 400;
  color: var(--fg-default);
  line-height: 1.5;
  cursor: pointer;
}

/* ── Boutons ── */

.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: 0 var(--space-5);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-size: var(--fs-body-sm);
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}

.bouton--principal { background: var(--color-primary-500); color: #fff; }
.bouton--principal:hover { background: var(--color-primary-600); color: #fff; text-decoration: none; }

.bouton--discret { background: var(--surface); border-color: var(--border-strong); color: var(--fg-strong); }
.bouton--discret:hover { background: var(--color-neutral-50); text-decoration: none; }

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

.lien-sobre { color: var(--color-primary-700); font-weight: 600; text-decoration: none; }
.lien-sobre:hover { text-decoration: underline; }

/* Un bouton qui se lit comme un lien. La déconnexion est un POST partout dans
   ce projet — `LogoutView` refuse le GET depuis Django 4.1 —, et l'écran de
   vérification n'a pas de barre de compte où loger son formulaire : il fallait
   donc un bouton qui n'annonce pas une action lourde.

   Il garde le plancher tactile de 44 px du projet (lot 4) : la boîte est haute,
   le texte reste un lien. Une sortie qu'on rate au doigt sur un écran sans
   autre issue, c'est la même chose qu'une sortie absente. */
.lien-sobre--bouton {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0;
  border: none;
  background: none;
  font-family: inherit;
  font-size: inherit;
  cursor: pointer;
}

/* Le formulaire n'est là que pour porter la méthode : il ne doit pas ajouter
   d'espace au-dessus de ce qui reste une ligne de note. */
.acces__sortie { margin: 0; }

/* ── Messages ── */

.messages { display: flex; flex-direction: column; gap: var(--space-3); margin-bottom: var(--space-6); }

/*
 * ⚠️ `.message` porte une PHRASE, donc elle coule — elle ne se dispose pas.
 *
 * Elle était `display: flex; gap: space-3`, ce qui n'a de sens que pour « une
 * icône, puis du texte ». Aucun `.message` du projet ne porte d'icône, et le
 * flex a coûté deux fois :
 *
 *   * piège n° 78 (lot 18) — trois enfants **sortaient de l'écran**, 454 px
 *     pour 375 ;
 *   * relevé de nouveau au lot 17, sur la porte du back-office : cinq enfants
 *     (« Vous êtes connecté sous », un `<span class="mono">`, la suite, un
 *     `<a>`, la fin) deviennent **cinq colonnes**, chacune enroulant son bout
 *     de phrase. La boîte ne déborde pas — elle est simplement illisible, ce
 *     qui se voit encore moins.
 *
 * La cause est la même les deux fois : un conteneur flex traite chaque
 * fragment de texte comme une colonne. Corriger l'instance (envelopper la
 * phrase dans un `<div>`) aurait laissé la règle mordre au gabarit suivant —
 * c'est DEC-059 et DEC-061, et ça fait la troisième fois.
 */
.message {
  display: block;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--surface);
  font-size: var(--fs-body-sm);
  line-height: 1.55;
}

.message--success { background: var(--color-success-50); border-color: transparent; color: var(--color-success-700); }
.message--warning { background: var(--color-warning-50); border-color: transparent; color: var(--color-warning-700); }
.message--error { background: var(--color-error-50); border-color: transparent; color: var(--color-error-700); }
.message--info { background: var(--color-info-50); border-color: transparent; color: var(--color-info-700); }

.rappel {
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  background: var(--color-warning-50);
  color: var(--color-warning-700);
  font-size: var(--fs-body-sm);
  line-height: 1.55;
}

/* ── Coupures ── */

@media (max-width: 900px) {
  .acces { grid-template-columns: 1fr; min-height: auto; }
  .acces__panneau { padding: var(--space-10) var(--space-5); }
  /* Le panneau de marque passe sous le formulaire : sur un téléphone, on
     veut le champ de saisie tout de suite, pas l'argumentaire. */
  .acces__marque { order: 2; padding: var(--space-10) var(--space-5); }
  .acces__accroche { font-size: var(--fs-h3); }
  .grille--principale,
  .grille--2,
  .grille--3 { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 620px) {
  .compte-page { padding: var(--space-6) var(--space-4) var(--space-16); }
  .compte-nav__inner { padding: var(--space-2) var(--space-4); gap: var(--space-2); }
  .compte-nav__recherche { padding: 0 var(--space-4) var(--space-3); }
  .compte-nav__logo img { height: 32px; }
  .compte-nav__identite { order: 2; font-size: var(--fs-body-sm); }
  .compte-nav__espace { order: 2; }
  /* Le menu reste sur la première ligne, à côté du numéro d'adhérent : il ne
     descend PAS dans la bande qui défile, où son panneau serait rogné. */
  .menu-compte { order: 3; }
  .menu-compte summary { padding: 0 var(--space-2); }
  .menu-compte__intitule { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .menu-compte__panneau { min-width: 13.5rem; }
  /* Depuis que la boutique est entrée dans la barre (lot 4), les liens
     empilés mangeaient la moitié d'un écran de téléphone avant même le
     contenu. Ils défilent maintenant sur une seule ligne, comme la barre des
     rayons — et gardent leurs 44 px de hauteur de cible. */
  .compte-nav__liens {
    order: 4;
    width: 100%;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    gap: 0;
  }
  .compte-nav__liens::-webkit-scrollbar { height: 0; }
  .compte-nav__liens a,
  .compte-nav__liens button { flex-shrink: 0; white-space: nowrap; }
  .compte-page__entete h1 { font-size: var(--fs-h3); }
  .formulaire__grille { grid-template-columns: minmax(0, 1fr); }
  .carte { padding: var(--space-5); }
  .valeur { font-size: var(--fs-h4); }
  /* Sur un téléphone, 12 px ne se lit pas à 70 ans. Les textes d'appoint
     remontent à 14 px : c'est le plancher que fixe le brief d'accessibilité. */
  .note,
  .champ__aide,
  .champ__erreur { font-size: var(--fs-body-sm); }
}

/* ── L'œil des champs de mot de passe ───────────────────────────────────────
   Le bouton est rendu masqué par le serveur et démasqué par le script : sans
   JavaScript, il n'apparaît pas et le champ reste utilisable tel quel.
   Cible tactile 44 px, le plancher du projet depuis le lot 4.                */

.champ__mdp { position: relative; display: block; }
.champ__mdp input { width: 100%; padding-right: 52px; }

.champ__oeil {
  position: absolute;
  top: 50%;
  right: 4px;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  display: inline-grid;
  place-items: center;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--fg-subtle);
  cursor: pointer;
}
.champ__oeil:hover { color: var(--fg-default); }
.champ__oeil:focus-visible { outline: 2px solid var(--color-primary-500); outline-offset: -2px; }
.champ__oeil svg { width: 18px; height: 18px; }
.champ__oeil[hidden] { display: none; }

/* Les deux icônes sont posées ensemble ; `aria-pressed` décide laquelle se voit. */
.champ__oeil .champ__oeil-off,
.champ__oeil[aria-pressed="true"] .champ__oeil-on { display: none; }
.champ__oeil[aria-pressed="true"] .champ__oeil-off { display: inline-grid; }
.champ__oeil[aria-pressed="true"] { color: var(--color-primary-600); }
