/* Système de design de la boutique Tenzen Arcade.
 *
 * Pas de framework : une page SSR de vitrine n'a besoin ni d'un runtime CSS, ni d'un
 * bundler, et la spec (§ Stack) exclut l'un comme l'autre. Ce qui suit est donc écrit à
 * la main, dans cet ordre : jetons, base, typographie, composants, grilles, back-office.
 *
 * Inspiration (spec § Inspiration ergonomique) : la lisibilité d'état de Back Market
 * (un grade, un badge, un seul CTA), la grille de cartes de Vinted, la sobriété d'Apple
 * (beaucoup de blanc, une hiérarchie typographique qui fait tout le travail).
 *
 * Le thème sombre ne redéfinit QUE des jetons, jamais des règles : une couleur qui
 * n'existerait que dans le bloc @media serait absente en clair, et inversement.
 */

/* ── Jetons ──────────────────────────────────────────────────────────────────── */

:root {
  /* Neutres. La boutique est presque entièrement construite dessus : l'accent ne sert
     qu'aux actions, jamais au décor. */
  --blanc: #ffffff;
  --fond: #fbfaf8;
  --fond-surface: #ffffff;
  --fond-attenue: #f2f0ec;
  --fond-inverse: #16181d;
  --bordure: #e4e1db;
  --bordure-forte: #cfcbc3;
  --texte: #1c1f26;
  --texte-secondaire: #5f6672;
  --texte-attenue: #8a909c;
  --texte-inverse: #f7f6f4;

  /* Accent Tenzen, repris du portail (#2c3e56 / #3877bd) pour que la boutique et le
     back-office restent de la même famille que le reste de la flotte. */
  --accent: #2c3e56;
  --accent-clair: #3877bd;
  --accent-contraste: #ffffff;
  --accent-doux: #eef3f9;

  /* États. Le vert n'est jamais « disponible » seul : il accompagne un mot. */
  --succes: #1f6b3f;
  --succes-doux: #e7f3ec;
  --alerte: #8a5300;
  --alerte-doux: #fdf2e0;
  --erreur: #a32724;
  --erreur-doux: #fbeceb;
  --info: #2f5d8a;
  --info-doux: #eaf1f8;

  /* Grades d'état d'une borne (spec § Inspiration ergonomique). Quatre teintes qui se
     lisent aussi en niveaux de gris : la saturation baisse en même temps que le grade,
     de sorte que le classement reste perceptible sans distinguer les couleurs. */
  --grade-excellent: #1f6b3f;
  --grade-excellent-doux: #e6f2ea;
  --grade-tres-bon: #2f6f86;
  --grade-tres-bon-doux: #e7f1f5;
  --grade-bon: #8a5300;
  --grade-bon-doux: #fbf1de;
  --grade-correct: #6b6257;
  --grade-correct-doux: #f1efea;

  /* Typographie : pile système. Aucune police n'est téléchargée — c'est une page de
     vente, la première image doit arriver avant la première fonte. */
  --police: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue',
    Arial, 'Noto Sans', sans-serif;
  --police-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;

  /* Échelle typographique fluide : la même règle sert du téléphone au 27 pouces, sans
     point de rupture dédié à la taille du texte. */
  --t-xs: 0.75rem;
  --t-s: 0.8125rem;
  --t-m: 0.9375rem;
  --t-l: 1.0625rem;
  --t-xl: clamp(1.25rem, 0.9rem + 1.2vw, 1.6rem);
  --t-2xl: clamp(1.6rem, 1.1rem + 2vw, 2.4rem);
  --t-3xl: clamp(2rem, 1.2rem + 3.4vw, 3.4rem);

  /* Espacement : une seule suite, pour que les marges se composent sans arbitrage. */
  --e-1: 0.25rem;
  --e-2: 0.5rem;
  --e-3: 0.75rem;
  --e-4: 1rem;
  --e-5: 1.5rem;
  --e-6: 2rem;
  --e-7: 3rem;
  --e-8: 4.5rem;

  --rayon-s: 6px;
  --rayon-m: 10px;
  --rayon-l: 16px;
  --rayon-rond: 999px;

  --ombre-s: 0 1px 2px rgba(20, 22, 28, 0.06);
  --ombre-m: 0 2px 8px rgba(20, 22, 28, 0.07), 0 1px 2px rgba(20, 22, 28, 0.05);
  --ombre-l: 0 12px 32px rgba(20, 22, 28, 0.12);

  --largeur: 1180px;
  --largeur-etroite: 660px;
  --entete-hauteur: 68px;
}

/* Thème sombre : redéfinition de jetons uniquement. Les ombres deviennent des halos —
   une ombre portée noire est invisible sur un fond noir, la profondeur passe donc par
   des bordures plus claires. */
@media (prefers-color-scheme: dark) {
  :root {
    --blanc: #ffffff;
    --fond: #101216;
    --fond-surface: #181b21;
    --fond-attenue: #1f232b;
    --fond-inverse: #f7f6f4;
    --bordure: #2b303a;
    --bordure-forte: #3d4450;
    --texte: #eceef2;
    --texte-secondaire: #a2a9b6;
    --texte-attenue: #79808d;
    --texte-inverse: #16181d;

    --accent: #cfe0f4;
    --accent-clair: #6fa8e8;
    --accent-contraste: #10161f;
    --accent-doux: #1b2635;

    --succes: #6dd39a;
    --succes-doux: #14261c;
    --alerte: #e0ac5c;
    --alerte-doux: #2a2113;
    --erreur: #f08b86;
    --erreur-doux: #2c1817;
    --info: #8bb8e6;
    --info-doux: #16212c;

    --grade-excellent: #6dd39a;
    --grade-excellent-doux: #14261c;
    --grade-tres-bon: #7cc0d8;
    --grade-tres-bon-doux: #132530;
    --grade-bon: #e0ac5c;
    --grade-bon-doux: #2a2113;
    --grade-correct: #b3aa9c;
    --grade-correct-doux: #23211d;

    --ombre-s: 0 1px 2px rgba(0, 0, 0, 0.5);
    --ombre-m: 0 2px 10px rgba(0, 0, 0, 0.55);
    --ombre-l: 0 14px 36px rgba(0, 0, 0, 0.65);
  }
}

/* ── Base ────────────────────────────────────────────────────────────────────── */

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

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

/* Un visiteur qui a demandé moins d'animation n'en reçoit aucune : ni défilement animé,
   ni transition. Réglage d'accessibilité, pas de confort. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--fond);
  color: var(--texte);
  font-family: var(--police);
  font-size: var(--t-m);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

img,
video { max-width: 100%; height: auto; display: block; }

a { color: inherit; text-decoration: none; }
a:hover { text-decoration: underline; }

/* Un anneau de focus visible partout, y compris sur les boutons : la boutique se
   parcourt entièrement au clavier, jusqu'au paiement. */
:focus-visible {
  outline: 2px solid var(--accent-clair);
  outline-offset: 2px;
  border-radius: var(--rayon-s);
}

button,
input,
select,
textarea { font: inherit; color: inherit; }

/* ── Typographie ─────────────────────────────────────────────────────────────── */

h1, h2, h3, h4 {
  margin: 0 0 var(--e-3);
  line-height: 1.2;
  letter-spacing: -0.015em;
  font-weight: 640;
  text-wrap: balance;
}

h1 { font-size: var(--t-2xl); }
h2 { font-size: var(--t-xl); }
h3 { font-size: var(--t-l); }

p { margin: 0 0 var(--e-4); }
p:last-child { margin-bottom: 0; }

.texte-secondaire { color: var(--texte-secondaire); }
.texte-petit { font-size: var(--t-s); }
.texte-mono { font-family: var(--police-mono); font-size: var(--t-s); }

/* ── Mise en page ────────────────────────────────────────────────────────────── */

.contenu {
  flex: 1;
  width: 100%;
  max-width: var(--largeur);
  margin: 0 auto;
  padding: var(--e-6) var(--e-4) var(--e-8);
}

.section { margin: 0 0 var(--e-7); }
.section:last-child { margin-bottom: 0; }
.section-etroite { max-width: var(--largeur-etroite); margin-inline: auto; text-align: center; }

.section-titre {
  font-size: var(--t-xl);
  margin-bottom: var(--e-5);
}

/* Le lien d'évitement n'apparaît qu'au clavier : premier arrêt de tabulation de chaque
   page, invisible à la souris. */
.saut-contenu {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: var(--e-3) var(--e-4);
  background: var(--accent);
  color: var(--accent-contraste);
  border-radius: 0 0 var(--rayon-m) 0;
}
.saut-contenu:focus { left: 0; }

/* ── En-tête ─────────────────────────────────────────────────────────────────── */

.entete {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--fond-surface) 88%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--bordure);
}

.entete-barre {
  max-width: var(--largeur);
  margin: 0 auto;
  min-height: var(--entete-hauteur);
  padding: var(--e-2) var(--e-4);
  display: flex;
  align-items: center;
  gap: var(--e-5);
  flex-wrap: wrap;
}

.marque {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  flex-shrink: 0;
}
.marque:hover { text-decoration: none; }
.marque-logo { width: auto; height: 34px; }
.marque-texte { display: flex; flex-direction: column; line-height: 1.15; }
.marque-nom { font-weight: 660; letter-spacing: -0.02em; }
.marque-baseline {
  font-size: var(--t-xs);
  color: var(--texte-secondaire);
  /* Une accroche n'a pas de place sur un téléphone : le nom suffit. */
  display: none;
}

.nav {
  display: flex;
  gap: var(--e-5);
  flex: 1;
  font-size: var(--t-m);
}
.nav a {
  color: var(--texte-secondaire);
  padding: var(--e-1) 0;
  border-bottom: 2px solid transparent;
}
.nav a:hover { color: var(--texte); text-decoration: none; }
.nav a[aria-current] { color: var(--texte); border-bottom-color: var(--accent-clair); }

.entete-actions {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  margin-left: auto;
}

.langues {
  display: inline-flex;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-rond);
  overflow: hidden;
}
.langue {
  padding: var(--e-1) var(--e-3);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--texte-secondaire);
}
.langue:hover { background: var(--fond-attenue); text-decoration: none; }
.langue-active { background: var(--accent); color: var(--accent-contraste); }
.langue-active:hover { background: var(--accent); }

.lien-discret { color: var(--texte-secondaire); font-size: var(--t-m); }
.lien-discret:hover { color: var(--texte); }

.pastille {
  display: inline-block;
  min-width: 1.35em;
  padding: 0 0.35em;
  border-radius: var(--rayon-rond);
  background: var(--accent-clair);
  color: var(--blanc);
  font-size: var(--t-xs);
  font-weight: 700;
  text-align: center;
}

@media (min-width: 60rem) {
  .marque-baseline { display: block; }
}

@media (max-width: 46rem) {
  .nav {
    order: 3;
    width: 100%;
    flex: none;
    gap: var(--e-4);
    overflow-x: auto;
    padding-bottom: var(--e-1);
  }
  .entete-actions { margin-left: auto; }
}

/* ── Bandeau d'accueil ───────────────────────────────────────────────────────── */

.bandeau {
  padding: var(--e-7) 0 var(--e-6);
  max-width: 46rem;
}
.bandeau-titre {
  font-size: var(--t-3xl);
  letter-spacing: -0.03em;
  margin-bottom: var(--e-4);
}
.bandeau-texte {
  font-size: var(--t-l);
  color: var(--texte-secondaire);
  max-width: 38rem;
}
.bandeau-actions { display: flex; gap: var(--e-3); flex-wrap: wrap; margin-top: var(--e-5); }

/* ── Grilles ─────────────────────────────────────────────────────────────────── */

/* `auto-fill` plutôt que des points de rupture comptés : la grille se réorganise selon
   la place réelle, y compris dans une colonne étroite d'une fiche produit. */
.grille {
  display: grid;
  gap: var(--e-4);
  list-style: none;
  margin: 0;
  padding: 0;
}
.grille-2 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 22rem), 1fr)); }
.grille-3 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); }
.grille-4 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 14rem), 1fr)); }

/* ── Cartes ──────────────────────────────────────────────────────────────────── */

.carte {
  background: var(--fond-surface);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-l);
  padding: var(--e-5);
  box-shadow: var(--ombre-s);
}
.carte-titre { font-size: var(--t-l); margin-bottom: var(--e-2); }
.carte-texte { color: var(--texte-secondaire); font-size: var(--t-m); margin: 0; }

.carte-vide {
  text-align: center;
  padding: var(--e-8) var(--e-5);
  border-style: dashed;
  box-shadow: none;
  background: transparent;
}
.carte-vide h2 { color: var(--texte); }
.carte-vide p { color: var(--texte-secondaire); margin: 0; }

/* Carte de borne : une pièce, une photo, un grade. L'ombre ne se lève qu'au survol —
   au repos, la grille doit rester plate et lisible. */
.carte-borne {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 0;
  transition: box-shadow 0.18s ease, transform 0.18s ease, border-color 0.18s ease;
}
.carte-borne:hover {
  box-shadow: var(--ombre-l);
  border-color: var(--bordure-forte);
  transform: translateY(-2px);
}
.carte-borne a:hover { text-decoration: none; }

.carte-visuel {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--fond-attenue);
  overflow: hidden;
}
.carte-visuel img { width: 100%; height: 100%; object-fit: cover; }
.carte-visuel .badge { position: absolute; top: var(--e-3); left: var(--e-3); }

/* Le `gap` de la colonne fait tout l'espacement : les marges par défaut des <p> s'y
   ajouteraient et donneraient des interlignes inégaux d'une ligne à l'autre. */
.carte-corps { padding: var(--e-4); display: flex; flex-direction: column; gap: var(--e-2); flex: 1; }
.carte-corps > p,
.carte-corps > h3 { margin: 0; }
.carte-modele { font-weight: 620; letter-spacing: -0.01em; }
.carte-ref { font-family: var(--police-mono); font-size: var(--t-xs); color: var(--texte-attenue); }
.carte-prix { margin-top: auto; display: flex; align-items: baseline; gap: var(--e-2); }
.prix { font-size: var(--t-xl); font-weight: 660; letter-spacing: -0.02em; }
.prix-barre { color: var(--texte-attenue); text-decoration: line-through; font-size: var(--t-m); }
.prix-mention { font-size: var(--t-xs); color: var(--texte-secondaire); }

/* Grille du catalogue et de la mise en avant. Ici les paliers sont COMPTÉS (1, 2, 3 puis
   4 colonnes) et non laissés à `auto-fill` comme les grilles génériques : une carte de
   borne porte une photo en 4/3, et c'est le nombre de colonnes qui décide de la taille de
   cette photo. Laisser la grille se remplir seule donnerait des vignettes de 14 rem sur
   un écran large — trop petites pour juger d'un état, qui est tout l'objet de la page. */
.grille-bornes { grid-template-columns: 1fr; }
@media (min-width: 34rem) { .grille-bornes { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 56rem) { .grille-bornes { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 84rem) { .grille-bornes { grid-template-columns: repeat(4, 1fr); } }

/* Le lien du titre couvre toute la carte, sans imbriquer l'image et le prix DANS le lien :
   un lecteur d'écran annonce alors « Astro City NAC 14 » et non le contenu entier de la
   carte. `position: relative` sur la carte borne la zone cliquable. */
.carte-borne { position: relative; }
.carte-lien::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
}
/* L'anneau de focus doit se voir sur la CARTE, pas sur les quelques pixels du titre :
   sans cela, la navigation au clavier dans une grille de 24 cartes est illisible. */
.carte-lien:focus-visible { outline: none; }
.carte-borne:has(.carte-lien:focus-visible) {
  outline: 2px solid var(--accent-clair);
  outline-offset: 2px;
}

/* Faute de photo : un aplat neutre plutôt qu'une image cassée (§ modes dégradés). */
.carte-visuel-vide {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: var(--texte-attenue);
  font-size: var(--t-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: repeating-linear-gradient(
    45deg, var(--fond-attenue), var(--fond-attenue) 10px, var(--fond) 10px, var(--fond) 20px
  );
}

.carte-etats { display: flex; align-items: center; gap: var(--e-2); flex-wrap: wrap; margin: 0; }
/* « Exemplaire unique » n'est pas un badge : c'est vrai de TOUTES les bornes. En faire
   une pastille colorée sur chaque carte ne dirait plus rien — mention discrète, donc. */
.etiquette-unique {
  font-size: var(--t-xs);
  color: var(--texte-secondaire);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.section-suite { margin-top: var(--e-5); }

/* ── Badges ──────────────────────────────────────────────────────────────────── */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--e-1);
  padding: 0.2em 0.65em;
  border-radius: var(--rayon-rond);
  font-size: var(--t-xs);
  font-weight: 640;
  letter-spacing: 0.01em;
  white-space: nowrap;
  border: 1px solid transparent;
}

/* Les badges de grade portent une bordure de la même teinte que leur texte : sur une
   photo claire, un aplat pâle seul ne se détacherait pas. */
.badge-grade-excellent { background: var(--grade-excellent-doux); color: var(--grade-excellent); border-color: color-mix(in srgb, var(--grade-excellent) 30%, transparent); }
.badge-grade-tres_bon  { background: var(--grade-tres-bon-doux); color: var(--grade-tres-bon); border-color: color-mix(in srgb, var(--grade-tres-bon) 30%, transparent); }
.badge-grade-bon       { background: var(--grade-bon-doux); color: var(--grade-bon); border-color: color-mix(in srgb, var(--grade-bon) 30%, transparent); }
.badge-grade-correct   { background: var(--grade-correct-doux); color: var(--grade-correct); border-color: color-mix(in srgb, var(--grade-correct) 30%, transparent); }

.badge-remise { background: var(--alerte-doux); color: var(--alerte); border-color: color-mix(in srgb, var(--alerte) 30%, transparent); }
.badge-reservee { background: var(--fond-attenue); color: var(--texte-secondaire); border-color: var(--bordure-forte); }
.badge-vendue { background: var(--fond-inverse); color: var(--texte-inverse); }
.badge-succes { background: var(--succes-doux); color: var(--succes); border-color: color-mix(in srgb, var(--succes) 30%, transparent); }
.badge-info { background: var(--info-doux); color: var(--info); border-color: color-mix(in srgb, var(--info) 30%, transparent); }
.badge-erreur { background: var(--erreur-doux); color: var(--erreur); border-color: color-mix(in srgb, var(--erreur) 30%, transparent); }

/* ── Boutons ─────────────────────────────────────────────────────────────────── */

.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  padding: 0.65rem 1.15rem;
  border: 1px solid transparent;
  border-radius: var(--rayon-m);
  font-size: var(--t-m);
  font-weight: 600;
  cursor: pointer;
  text-align: center;
  /* 44 px de haut : la cible tactile minimale recommandée, tenue même sur le bouton
     « petit » d'un en-tête. */
  min-height: 2.75rem;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.bouton:hover { text-decoration: none; }
.bouton:disabled,
.bouton[aria-disabled='true'] { opacity: 0.5; cursor: not-allowed; }

.bouton-primaire { background: var(--accent); color: var(--accent-contraste); }
.bouton-primaire:hover { background: color-mix(in srgb, var(--accent) 85%, var(--fond-inverse)); }

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

.bouton-fantome { background: transparent; color: var(--texte-secondaire); }
.bouton-fantome:hover { background: var(--fond-attenue); color: var(--texte); }

.bouton-danger { background: var(--erreur-doux); color: var(--erreur); border-color: color-mix(in srgb, var(--erreur) 35%, transparent); }
.bouton-danger:hover { background: color-mix(in srgb, var(--erreur-doux) 80%, var(--erreur)); }

.bouton-petit { padding: 0.35rem 0.75rem; font-size: var(--t-s); min-height: 2.25rem; }
.bouton-bloc { width: 100%; }

/* ── Formulaires ─────────────────────────────────────────────────────────────── */

.champ { display: flex; flex-direction: column; gap: var(--e-2); margin-bottom: var(--e-4); }
.champ > label { font-size: var(--t-s); font-weight: 600; color: var(--texte-secondaire); }
.champ-aide { font-size: var(--t-xs); color: var(--texte-attenue); }
.champ-erreur { font-size: var(--t-s); color: var(--erreur); }

input[type='text'],
input[type='email'],
input[type='tel'],
input[type='number'],
input[type='search'],
input[type='password'],
select,
textarea {
  width: 100%;
  padding: 0.6rem 0.75rem;
  background: var(--fond-surface);
  border: 1px solid var(--bordure-forte);
  border-radius: var(--rayon-m);
  min-height: 2.75rem;
}
textarea { min-height: 8rem; resize: vertical; line-height: 1.5; }

input:focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--accent-clair);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-clair) 22%, transparent);
}

/* `[aria-invalid]` plutôt qu'une classe : l'état est déjà porté pour les lecteurs
   d'écran, il n'a pas à être répété en classe CSS. */
input[aria-invalid='true'],
select[aria-invalid='true'],
textarea[aria-invalid='true'] { border-color: var(--erreur); }

.champ-inline { display: flex; align-items: flex-start; gap: var(--e-3); flex-direction: row; }
.champ-inline input[type='checkbox'],
.champ-inline input[type='radio'] { width: 1.15rem; height: 1.15rem; min-height: 0; margin-top: 0.25rem; flex: none; }
.champ-inline label { font-weight: 400; color: var(--texte); }

fieldset { border: 1px solid var(--bordure); border-radius: var(--rayon-m); padding: var(--e-4); margin: 0 0 var(--e-4); }
legend { padding: 0 var(--e-2); font-size: var(--t-s); font-weight: 600; color: var(--texte-secondaire); }

.actions-formulaire { display: flex; gap: var(--e-3); flex-wrap: wrap; margin-top: var(--e-5); }

/* ── Messages ────────────────────────────────────────────────────────────────── */

.flashes { display: flex; flex-direction: column; gap: var(--e-2); margin-bottom: var(--e-5); }
.flash {
  margin: 0;
  padding: var(--e-3) var(--e-4);
  border-radius: var(--rayon-m);
  border: 1px solid transparent;
  font-size: var(--t-m);
}
.flash-etiquette { font-weight: 660; margin-right: var(--e-2); }
.flash-succes { background: var(--succes-doux); color: var(--succes); border-color: color-mix(in srgb, var(--succes) 25%, transparent); }
.flash-erreur { background: var(--erreur-doux); color: var(--erreur); border-color: color-mix(in srgb, var(--erreur) 25%, transparent); }
.flash-info { background: var(--info-doux); color: var(--info); border-color: color-mix(in srgb, var(--info) 25%, transparent); }

.erreur-code {
  font-family: var(--police-mono);
  font-size: var(--t-3xl);
  color: var(--texte-attenue);
  margin: 0 0 var(--e-2);
}

/* ── Catalogue à facettes ────────────────────────────────────────────────────── */

/* Deux colonnes — filtres à gauche, résultats à droite — au-dessus de 900 px (56,25 rem),
   une seule en dessous, où les filtres deviennent un accordéon replié par le `<details>`
   du gabarit. La grille nommée évite d'avoir à réordonner le DOM : l'ordre de lecture
   (titre, nombre de résultats, filtres, résultats) est déjà le bon au clavier comme au
   lecteur d'écran. */
.catalogue {
  display: grid;
  gap: var(--e-5);
  grid-template-areas:
    'entete'
    'filtres'
    'resultats';
}
.catalogue-entete { grid-area: entete; }
.catalogue-filtres { grid-area: filtres; }
.catalogue-resultats { grid-area: resultats; min-width: 0; }

@media (min-width: 56.25rem) {
  .catalogue {
    grid-template-columns: 16rem minmax(0, 1fr);
    grid-template-areas:
      'entete entete'
      'filtres resultats';
    gap: var(--e-5) var(--e-6);
  }
}

.catalogue-titre { margin-bottom: var(--e-1); }
.catalogue-compte { color: var(--texte-secondaire); font-size: var(--t-s); margin: 0; }

/* Le panneau suit le défilement d'une longue page de résultats, sans jamais dépasser la
   fenêtre : au-delà, c'est lui qui défile. */
@media (min-width: 56.25rem) {
  .facettes {
    position: sticky;
    top: calc(var(--entete-hauteur) + var(--e-4));
    max-height: calc(100vh - var(--entete-hauteur) - var(--e-6));
    overflow-y: auto;
  }
  /* Au-dessus de 900 px il n'y a plus d'accordéon : le sommaire disparaît et le panneau
     est ouvert quoi qu'il arrive. Les DEUX propriétés sont nécessaires — les navigateurs
     masquent le contenu d'un `<details>` fermé tantôt par `display`, tantôt par
     `content-visibility`. Sans cela, un panneau replié sur mobile resterait invisible
     après un simple élargissement de la fenêtre, sommaire compris. */
  .facettes-sommaire { display: none; }
  .facettes-repli:not([open]) .facettes-corps {
    display: block;
    content-visibility: visible;
  }
}

.facettes-sommaire {
  cursor: pointer;
  padding: var(--e-3) var(--e-4);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-m);
  background: var(--fond-surface);
  font-weight: 620;
}
.facettes-corps { display: flex; flex-direction: column; gap: var(--e-5); padding-top: var(--e-4); }

.facette { border: 0; margin: 0; padding: 0; }
.facette-titre {
  padding: 0;
  margin-bottom: var(--e-3);
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--texte-attenue);
}
.facette-valeurs { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--e-1); }
.facette-valeur label {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  padding: var(--e-1) var(--e-2);
  border-radius: var(--rayon-s);
  cursor: pointer;
}
.facette-valeur label:hover { background: var(--fond-attenue); }
/* 1,05 rem : une case à cocher à la taille par défaut est sous les 24 px recommandés pour
   une cible tactile — c'est le padding du label qui complète la zone. */
.facette-valeur input[type='checkbox'] { width: 1.05rem; height: 1.05rem; flex: none; margin: 0; }
.facette-libelle { flex: 1; }
.facette-nb { color: var(--texte-attenue); font-size: var(--t-xs); font-variant-numeric: tabular-nums; }

.facette-prix { display: flex; gap: var(--e-3); }
.facette-prix-champ { display: flex; flex-direction: column; gap: var(--e-1); flex: 1; min-width: 0; }
.facette-prix-champ span { font-size: var(--t-xs); color: var(--texte-secondaire); }
.facette-prix-champ input { width: 100%; }

.facettes-actions { display: flex; flex-direction: column; gap: var(--e-2); }

/* Le tri est un formulaire à part (un <select> ne se soumet pas sans JavaScript) :
   il s'aligne à droite des résultats, au-dessus de la grille. */
.catalogue-tri {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  flex-wrap: wrap;
  justify-content: flex-end;
  margin-bottom: var(--e-4);
  font-size: var(--t-s);
}
.catalogue-tri label { color: var(--texte-secondaire); }

.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-3);
  flex-wrap: wrap;
  margin-top: var(--e-6);
}
.pagination-pages {
  list-style: none;
  display: flex;
  gap: var(--e-1);
  margin: 0;
  padding: 0;
  flex-wrap: wrap;
}
.pagination-page {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 2.25rem;
  min-height: 2.25rem;
  padding: 0 var(--e-2);
  border-radius: var(--rayon-s);
  font-variant-numeric: tabular-nums;
  color: var(--texte-secondaire);
}
a.pagination-page:hover { background: var(--fond-attenue); color: var(--texte); text-decoration: none; }
.pagination-actuelle { background: var(--accent); color: var(--accent-contraste); font-weight: 620; }

/* ── Réassurance ─────────────────────────────────────────────────────────────── */

.reassurance .carte { background: transparent; box-shadow: none; }

/* ── Fiche d'une borne ───────────────────────────────────────────────────────── */

/* Deux colonnes au-delà de 900 px : la galerie et le corps à gauche, la colonne d'achat
   à droite. La grille est NOMMÉE pour la même raison que celle du catalogue — l'ordre du
   DOM (titre, galerie, achat, corps) est déjà l'ordre de lecture, et le mettre en colonnes
   ne doit pas obliger à le réécrire. Sur mobile, l'achat vient donc juste après la
   galerie, avant le rapport : c'est là qu'on décide. */
.fiche {
  display: grid;
  gap: var(--e-5);
  grid-template-areas:
    'entete'
    'visuel'
    'achat'
    'corps';
}
.fiche-entete { grid-area: entete; }
.fiche-visuel { grid-area: visuel; min-width: 0; }
.fiche-achat { grid-area: achat; min-width: 0; }
.fiche-corps { grid-area: corps; min-width: 0; }

@media (min-width: 56.25rem) {
  .fiche {
    grid-template-columns: minmax(0, 1fr) 21rem;
    grid-template-areas:
      'entete achat'
      'visuel achat'
      'corps achat';
    gap: var(--e-5) var(--e-6);
    align-items: start;
  }
  /* La promesse d'Apple, § Inspiration ergonomique : sur une fiche longue, le prix et le
     bouton restent sous les yeux pendant qu'on lit le rapport de test. `top` tient compte
     de l'en-tête, elle-même collante — sans quoi la colonne se glisserait dessous. */
  .fiche-achat {
    position: sticky;
    top: calc(var(--entete-hauteur) + var(--e-4));
    max-height: calc(100vh - var(--entete-hauteur) - var(--e-6));
    overflow-y: auto;
  }
}

.fil-ariane { font-size: var(--t-s); color: var(--texte-secondaire); margin-bottom: var(--e-4); }
.fil-ariane ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: var(--e-2); }
/* Le séparateur est décoratif : `content` d'un pseudo-élément, jamais un caractère du
   document — un lecteur d'écran n'a pas à énoncer « barre oblique » entre deux liens. */
.fil-ariane li + li::before { content: '›'; margin-right: var(--e-2); color: var(--texte-attenue); }
.fil-ariane a { color: var(--texte-secondaire); }
.fil-ariane a:hover { color: var(--texte); }

.avis-traduction {
  background: var(--info-doux);
  color: var(--info);
  border: 1px solid color-mix(in srgb, var(--info) 25%, transparent);
  border-radius: var(--rayon-m);
  padding: var(--e-3) var(--e-4);
  font-size: var(--t-s);
  margin-bottom: var(--e-4);
}

.fiche-titre { font-size: var(--t-2xl); letter-spacing: -0.02em; margin: 0 0 var(--e-2); }
.fiche-sous-titre { display: flex; align-items: center; gap: var(--e-3); flex-wrap: wrap; margin: 0; }
.fiche-ref { font-family: var(--police-mono); font-size: var(--t-s); color: var(--texte-secondaire); }

/* ── Galerie ─────────────────────────────────────────────────────────────────── */

/* Carrousel SANS JavaScript : les diapositives sont côte à côte dans un conteneur à
   défilement horizontal, et les vignettes sont des liens vers leurs ancres. `scroll-snap`
   fait le reste — le navigateur cale la diapositive, le lien la fait défiler.
   `scroll-behavior: smooth` rend le saut lisible ; il est neutralisé plus bas pour qui
   demande moins d'animation. */
.galerie-scene {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  gap: var(--e-2);
  border-radius: var(--rayon-l);
  background: var(--fond-attenue);
}
.galerie-scene:focus-visible { outline: 2px solid var(--accent-clair); outline-offset: 3px; }
.galerie-vue {
  flex: 0 0 100%;
  scroll-snap-align: center;
  margin: 0;
  min-width: 0;
  /* La diapositive est ancrée : elle doit s'arrêter SOUS l'en-tête collante quand on
     clique une vignette, pas derrière elle. */
  scroll-margin-top: calc(var(--entete-hauteur) + var(--e-4));
}
/* Rapport 4/3 imposé : les photos d'atelier n'ont pas toutes le même cadrage, et une
   galerie dont la hauteur change à chaque diapositive fait sauter toute la page. */
.galerie-media {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: contain;
  background: var(--fond-attenue);
}
.galerie-legende {
  padding: var(--e-2) var(--e-3);
  font-size: var(--t-s);
  color: var(--texte-secondaire);
  text-align: center;
}

.galerie-vignettes { margin-top: var(--e-3); }
.galerie-vignettes ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: var(--e-2);
  overflow-x: auto;
}
.galerie-vignette {
  display: block;
  width: 5.5rem;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-s);
  overflow: hidden;
  background: var(--fond-attenue);
}
.galerie-vignette:hover { border-color: var(--bordure-forte); }
.galerie-vignette:focus-visible { outline: 2px solid var(--accent-clair); outline-offset: 2px; }
.galerie-vignette img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.galerie-vignette-video {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 3;
  font-size: var(--t-xs);
  color: var(--texte-secondaire);
}
.galerie-vide {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 4 / 3;
  border-radius: var(--rayon-l);
  background: var(--fond-attenue);
  color: var(--texte-attenue);
  font-size: var(--t-s);
}

/* ── Colonne d'achat ─────────────────────────────────────────────────────────── */

.fiche-achat {
  background: var(--fond-surface);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-l);
  box-shadow: var(--ombre-s);
  padding: var(--e-5);
}
.fiche-prix { display: flex; align-items: baseline; gap: var(--e-2); flex-wrap: wrap; margin: 0; }
.prix-grand { font-size: var(--t-2xl); }
.fiche-prix-ht { font-size: var(--t-s); margin: var(--e-1) 0 var(--e-4); }
.fiche-grade { margin: 0 0 var(--e-4); }

.fiche-score { margin-bottom: var(--e-4); }
.fiche-score-ligne {
  display: flex;
  justify-content: space-between;
  gap: var(--e-3);
  margin: 0 0 var(--e-2);
  font-size: var(--t-s);
  color: var(--texte-secondaire);
}
.fiche-score-ligne strong { color: var(--texte); font-variant-numeric: tabular-nums; }

/* Rappel visuel d'un chiffre déjà écrit à côté : la barre est `aria-hidden` dans les
   gabarits, elle ne porte donc aucune information à elle seule. */
.barre {
  height: 6px;
  border-radius: var(--rayon-rond);
  background: var(--fond-attenue);
  overflow: hidden;
}
.barre-grande { height: 10px; }
.barre-remplie { display: block; height: 100%; background: var(--accent-clair); border-radius: inherit; }

.fiche-remise {
  background: var(--alerte-doux);
  border-radius: var(--rayon-m);
  padding: var(--e-3);
  margin-bottom: var(--e-4);
}
.fiche-remise p { margin: 0; }
.fiche-remise p + p { margin-top: var(--e-2); color: var(--alerte); }

.fiche-cta { margin: 0 0 var(--e-3); }
/* Un refus d'achat n'est pas une erreur : ni rouge, ni alarmant. Le ton reste neutre,
   c'est le texte qui informe. */
.fiche-indispo {
  background: var(--fond-attenue);
  border-radius: var(--rayon-m);
  padding: var(--e-3) var(--e-4);
  text-align: center;
  font-weight: 600;
}

.fiche-pays {
  margin-top: var(--e-5);
  padding-top: var(--e-4);
  border-top: 1px solid var(--bordure);
}
.fiche-pays label { display: block; font-size: var(--t-s); font-weight: 600; color: var(--texte-secondaire); margin-bottom: var(--e-2); }
.fiche-pays-champ { display: flex; gap: var(--e-2); }
.fiche-pays-champ select { flex: 1; min-width: 0; }

/* ── Sections de la fiche ────────────────────────────────────────────────────── */

.fiche-section { scroll-margin-top: calc(var(--entete-hauteur) + var(--e-4)); }
.fiche-section-aide { margin-top: calc(var(--e-4) * -1); margin-bottom: var(--e-5); font-size: var(--t-s); }

.texte-riche > :first-child { margin-top: 0; }
.texte-riche > :last-child { margin-bottom: 0; }
.texte-riche ul { padding-left: var(--e-5); }

.rapport-etape + .rapport-etape { margin-top: var(--e-5); }
.rapport-etape-titre { font-size: var(--t-s); text-transform: uppercase; letter-spacing: 0.06em; color: var(--texte-attenue); margin-bottom: var(--e-3); }
.rapport-constats { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--e-3); }
.rapport-constat {
  background: var(--fond-surface);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-m);
  padding: var(--e-3) var(--e-4);
}
.rapport-constat-tete { display: flex; align-items: baseline; gap: var(--e-3); flex-wrap: wrap; margin-bottom: var(--e-2); }
.rapport-constat-libelle { font-weight: 620; }
.rapport-constat-valeur { color: var(--texte-secondaire); }
.rapport-constat-score { margin-left: auto; font-size: var(--t-s); color: var(--texte-attenue); font-variant-numeric: tabular-nums; }
.rapport-constat-commentaire { margin: var(--e-2) 0 0; color: var(--texte-secondaire); font-size: var(--t-m); }

.fiche-definitions { display: grid; grid-template-columns: auto 1fr; gap: var(--e-2) var(--e-5); margin: 0; }
.fiche-definitions dt { color: var(--texte-secondaire); font-size: var(--t-s); }
.fiche-definitions dd { margin: 0; }

.fiche-livraison-tarif { font-weight: 620; margin: 0 0 var(--e-2); }

/* Le défilement animé de la galerie est un confort, pas une information : il disparaît
   pour qui demande moins d'animation, sans que les liens d'ancre cessent de fonctionner. */
@media (prefers-reduced-motion: reduce) {
  .galerie-scene { scroll-behavior: auto; }
}

/* ── Pied de page ────────────────────────────────────────────────────────────── */

.pied {
  margin-top: auto;
  border-top: 1px solid var(--bordure);
  background: var(--fond-attenue);
  padding: var(--e-7) var(--e-4) var(--e-5);
  font-size: var(--t-s);
}
.pied-colonnes {
  max-width: var(--largeur);
  margin: 0 auto var(--e-6);
  display: grid;
  gap: var(--e-5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
}
.pied-titre { font-size: var(--t-s); text-transform: uppercase; letter-spacing: 0.06em; color: var(--texte-attenue); margin-bottom: var(--e-3); }
.pied-colonne ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--e-2); }
.pied-colonne a { color: var(--texte-secondaire); }
.pied-colonne a:hover { color: var(--texte); }
.pied-bas {
  max-width: var(--largeur);
  margin: 0 auto;
  padding-top: var(--e-4);
  border-top: 1px solid var(--bordure);
  color: var(--texte-attenue);
  display: flex;
  justify-content: space-between;
  gap: var(--e-4);
  flex-wrap: wrap;
}
.pied-bas p { margin: 0; }

/* ── Back-office ─────────────────────────────────────────────────────────────── */

/* Écran d'outil : plus dense que la vitrine, sans largeur maximale — les tableaux de
   commandes et de candidates ont besoin de toute la fenêtre. */
.admin-entete {
  display: flex;
  align-items: center;
  gap: var(--e-5);
  flex-wrap: wrap;
  padding: var(--e-3) var(--e-5);
  background: var(--fond-surface);
  border-bottom: 1px solid var(--bordure);
}
.admin-marque { font-size: var(--t-l); }
.admin-marque:hover { text-decoration: none; }
.admin-nav { display: flex; gap: var(--e-4); flex: 1; overflow-x: auto; font-size: var(--t-m); }
.admin-nav a { color: var(--texte-secondaire); white-space: nowrap; padding: var(--e-1) 0; border-bottom: 2px solid transparent; }
.admin-nav a:hover { color: var(--texte); text-decoration: none; }
.admin-nav a[aria-current] { color: var(--texte); border-bottom-color: var(--accent-clair); }
.admin-actions { display: flex; align-items: center; gap: var(--e-3); margin-left: auto; }
.admin-utilisateur { font-size: var(--t-s); color: var(--texte-secondaire); }
.admin-deconnexion { margin: 0; }
.admin-contenu { flex: 1; padding: var(--e-5); }

/* Un tableau large ne doit JAMAIS élargir la page : il défile dans son propre cadre. */
.tableau-cadre {
  overflow-x: auto;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-m);
  background: var(--fond-surface);
}

table.tableau {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-s);
}
table.tableau th,
table.tableau td {
  padding: var(--e-3) var(--e-4);
  text-align: left;
  border-bottom: 1px solid var(--bordure);
  vertical-align: top;
  white-space: nowrap;
}
table.tableau th {
  position: sticky;
  top: 0;
  background: var(--fond-attenue);
  font-size: var(--t-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--texte-secondaire);
  font-weight: 640;
}
table.tableau tbody tr:last-child td { border-bottom: 0; }
table.tableau tbody tr:hover { background: var(--fond-attenue); }
table.tableau .cellule-libre { white-space: normal; min-width: 16rem; }
table.tableau .cellule-nombre { text-align: right; font-variant-numeric: tabular-nums; }

.admin-vide { padding: var(--e-7); text-align: center; color: var(--texte-secondaire); }

.admin-titre { font-size: var(--t-xl); letter-spacing: -0.02em; margin: 0 0 var(--e-5); }

/* Les quatre compteurs du tableau de bord. Chacun est un LIEN : un chiffre qu'on ne peut
   pas ouvrir oblige à retrouver l'écran correspondant dans la barre. */
.admin-compteurs {
  list-style: none;
  margin: 0 0 var(--e-6);
  padding: 0;
  display: grid;
  gap: var(--e-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}
.compteur {
  display: block;
  padding: var(--e-4) var(--e-5);
  background: var(--fond-surface);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-m);
  color: inherit;
}
.compteur:hover { border-color: var(--bordure-forte); text-decoration: none; }
.compteur-valeur {
  margin: 0;
  font-size: var(--t-3xl);
  font-weight: 660;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.compteur-libelle { margin: 0; font-size: var(--t-s); color: var(--texte-secondaire); }

/* Deux colonnes tant que la fenêtre le permet, une seule ensuite : le formulaire d'une
   fiche et ce qu'en disent les voisins se lisent côte à côte. */
.admin-colonnes {
  display: grid;
  gap: var(--e-4);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
  margin-bottom: var(--e-6);
}

.admin-definitions { display: grid; grid-template-columns: auto 1fr; gap: var(--e-2) var(--e-4); margin: 0; }
.admin-definitions dt { font-size: var(--t-s); color: var(--texte-secondaire); }
.admin-definitions dd { margin: 0; }

.admin-medias { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--e-2); }
.admin-medias li { display: flex; align-items: center; gap: var(--e-3); flex-wrap: wrap; }

/* Édition d'une fiche : une ligne de média porte trois contrôles, son identifiant et sa
   qualification. Elle respire donc plus qu'une simple ligne de lecture, et se sépare de
   la suivante — sans quoi on ne voit plus quelle case appartient à quelle photo. */
.admin-medias-edition li {
  gap: var(--e-4);
  padding: var(--e-3) 0;
  border-bottom: 1px solid var(--bordure);
}
.admin-medias-edition li:last-child { border-bottom: 0; }
.admin-medias-edition .champ-inline { margin: 0; align-items: center; }
/* Un rang tient en deux chiffres : un champ pleine largeur pousserait tout le reste
   hors de l'écran. */
.champ-rang { width: 4.5rem; min-height: 2.25rem; padding: 0.25rem 0.5rem; }
/* Les flèches ▲▼ sont ajoutées par /static/app.js ; sans JavaScript, ce groupe n'existe
   pas et le champ de rang reste seul maître de l'ordre. */
.admin-reordonner { display: flex; gap: var(--e-1); margin-left: auto; }

/* Les trois actions d'une fiche (publier, rafraîchir, retirer) sont des formulaires
   distincts empilés dans une même carte : sans séparation, les deux boutons se
   toucheraient et l'aide de l'un semblerait porter sur l'autre. */
.action-fiche + .action-fiche {
  margin-top: var(--e-4);
  padding-top: var(--e-4);
  border-top: 1px solid var(--bordure);
}
.action-fiche .champ-aide { margin-top: var(--e-2); }

/* Un commentaire relu se saisit dans le tableau des constats : deux lignes suffisent,
   la cellule ne doit pas devenir une colonne à elle seule. */
table.tableau .cellule-libre textarea { width: 100%; min-width: 14rem; min-height: 0; }

.admin-erreur { max-width: var(--largeur-etroite); margin: var(--e-7) auto; text-align: center; }

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

/* Un en-tête de colonne sans libellé visible (colonne d'actions) doit quand même en
   avoir un pour un lecteur d'écran, sinon la colonne n'a pas de nom. */
.visuellement-cache {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ── Panier (tâche D3) ─────────────────────────────────────────────────────────
   Deux colonnes au-delà de 900 px — les lignes à gauche, le récapitulatif à droite —,
   une seule en dessous, où le récapitulatif SUIT les lignes. C'est l'ordre dans lequel
   on lit un panier : ce qu'il contient, puis ce que cela coûte. L'ordre du DOM est déjà
   le bon, la grille ne fait que mettre en colonnes. */
.panier-titre { margin-bottom: var(--e-5); }
.panier { display: grid; gap: var(--e-5); align-items: start; }
.panier-lignes { min-width: 0; }
.panier-liste { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--e-4); }

.panier-ligne {
  display: grid;
  grid-template-columns: 7.5rem 1fr;
  gap: var(--e-4);
  padding: var(--e-4);
  background: var(--fond-surface);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-m);
  box-shadow: var(--ombre-s);
}
/* Une ligne qui ne partira pas est SIGNALÉE, pas cachée ni grisée : la retirer en
   silence laisserait croire qu'on n'a jamais rien mis dans son panier. Un liseré, pas un
   fond rouge — ce n'est pas une faute du visiteur. */
.panier-ligne-alerte { border-left: 3px solid var(--alerte); }

.panier-ligne-visuel { min-width: 0; }
.panier-ligne-visuel img,
.panier-ligne-visuel .carte-visuel-vide {
  width: 100%;
  /* Même rapport que les vignettes du catalogue : la hauteur ne change pas d'une ligne
     à l'autre, et la page ne saute pas pendant le chargement. */
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--rayon-s);
}
.panier-ligne-corps { min-width: 0; display: flex; flex-direction: column; gap: var(--e-2); }
.panier-ligne-titre { font-size: var(--t-m); margin: 0; }
.panier-ligne-titre a { color: inherit; text-decoration: none; }
.panier-ligne-titre a:hover { text-decoration: underline; }
.panier-ligne-motif {
  margin: 0;
  padding: var(--e-2) var(--e-3);
  background: var(--alerte-doux);
  color: var(--alerte);
  border-radius: var(--rayon-s);
  font-size: var(--t-s);
}
/* Sous 560 px la vignette passerait à deux centimètres de large : la ligne devient une
   seule colonne, image comprise. */
.panier-ligne-fin { grid-column: 2; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--e-2); }
.panier-ligne-fin .carte-prix { margin: 0; }
.panier-ligne-fin form { margin: 0; }

.panier-recap {
  padding: var(--e-5);
  background: var(--fond-surface);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-m);
  box-shadow: var(--ombre-s);
}
.panier-recap-titre { font-size: var(--t-m); margin: 0 0 var(--e-4); }
.panier-totaux { margin: 0 0 var(--e-4); display: flex; flex-direction: column; gap: var(--e-2); }
.panier-total-ligne { display: flex; justify-content: space-between; gap: var(--e-3); }
.panier-total-ligne dt { color: var(--texte-secondaire); }
.panier-total-ligne dd { margin: 0; font-variant-numeric: tabular-nums; }
.panier-total-fort {
  padding-top: var(--e-3);
  border-top: 1px solid var(--bordure);
  font-weight: 700;
  font-size: var(--t-l);
}
.panier-total-fort dt { color: var(--texte); }
/* Aucun bouton désactivé : un bouton grisé invite à cliquer puis ne dit pas pourquoi il
   ne se passe rien. La phrase, elle, dit ce qui manque. */
.panier-bloque {
  padding: var(--e-3);
  background: var(--alerte-doux);
  color: var(--alerte);
  border-radius: var(--rayon-s);
  font-size: var(--t-s);
}
.panier-vide { font-size: var(--t-l); font-weight: 600; }

@media (min-width: 35rem) {
  .panier-ligne { grid-template-columns: 9rem 1fr auto; }
  .panier-ligne-fin {
    grid-column: auto;
    flex-direction: column;
    align-items: flex-end;
    justify-content: space-between;
  }
}

@media (min-width: 56.25rem) {
  .panier { grid-template-columns: minmax(0, 1fr) 20rem; }
}

/* ── Commande (tâche D4) ───────────────────────────────────────────────────────
   Deux colonnes au-delà de 900 px — le formulaire à gauche, le récapitulatif à droite —,
   une seule en dessous.

   Attention à l'ordre : contrairement au panier, le récapitulatif est AVANT le formulaire
   dans le document. En une colonne, l'ordre du document est l'ordre de lecture, et voir
   ce qu'on achète avant de remplir douze champs — et surtout avant le bouton « Valider »
   — est le seul ordre acceptable sur un téléphone. Les zones nommées de la grille le
   remettent à droite sur grand écran, sans toucher au HTML. */
.commander { display: grid; gap: var(--e-5); align-items: start; }
.commander-form { min-width: 0; margin: 0; }
.commander-bloc { margin-bottom: var(--e-5); }
.commander-bloc:last-of-type { margin-bottom: var(--e-4); }

/* Un choix (radio ou case) et son aide. La cible cliquable est le <label> entier, pas la
   pastille de trois millimètres : sur un écran tactile, viser un bouton radio nu est la
   première cause d'abandon d'un formulaire. */
.champ-choix { margin: 0 0 var(--e-4); display: flex; flex-direction: column; gap: var(--e-1); }
.champ-choix > label {
  display: flex;
  align-items: flex-start;
  gap: var(--e-3);
  padding: var(--e-3);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-s);
  cursor: pointer;
}
.champ-choix > label:hover { border-color: var(--bordure-forte); background: var(--fond-attenue); }
.champ-choix input[type='radio'],
.champ-choix input[type='checkbox'] {
  width: 1.15rem;
  height: 1.15rem;
  flex: none;
  margin: 0.1rem 0 0;
  accent-color: var(--accent-clair);
}
/* `:has` n'est qu'un CONFORT : sans lui (navigateur ancien), le choix coché reste
   parfaitement identifiable par la pastille elle-même. */
.champ-choix > label:has(input:checked) { border-color: var(--accent-clair); background: var(--accent-doux); }
.champ-choix .champ-aide { padding-left: calc(1.15rem + var(--e-3) + var(--e-3)); }
.commander-cgv { margin-top: var(--e-5); }

/* Code postal et ville sur une ligne au-delà du téléphone : ils se saisissent ensemble,
   et deux champs pleine largeur pour cinq chiffres allongent le formulaire pour rien. */
.commander-ligne-double { display: grid; gap: var(--e-4); }

.commander-recap-lignes {
  list-style: none;
  margin: 0 0 var(--e-4);
  padding: 0 0 var(--e-4);
  border-bottom: 1px solid var(--bordure);
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
}
.commander-recap-lignes li { display: grid; gap: var(--e-1); }
.commander-recap-titre-ligne { font-weight: 600; }
.commander-recap-lignes .prix { font-variant-numeric: tabular-nums; }

/* Ce qui a été retiré de la commande reste ANNONCÉ, dans le ton d'une information et non
   d'une faute : liseré d'alerte, pas de fond rouge. Même parti pris que la ligne de
   panier indisponible. */
.commander-retirees {
  margin: 0 0 var(--e-5);
  padding: var(--e-4);
  border-left: 3px solid var(--alerte);
  background: var(--alerte-doux);
  border-radius: var(--rayon-s);
  color: var(--alerte);
}
.commander-retirees-titre { font-size: var(--t-m); margin: 0 0 var(--e-2); }
.commander-retirees ul { margin: 0; padding-left: var(--e-5); }

.commander-devis {
  margin: 0 0 var(--e-5);
  padding: var(--e-4);
  background: var(--info-doux);
  border-radius: var(--rayon-m);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e-4);
}

/* ── Confirmation de commande ─────────────────────────────────────────────────
   La référence est l'élément le plus important de la page : c'est elle qui doit être
   recopiée dans le libellé du virement. D'où le cadre, la taille, et la police à chasse
   fixe — un « 0 » et un « O » ne se confondent pas dedans. */
.merci-intro { font-size: var(--t-l); }
.merci-reference {
  margin: var(--e-5) 0;
  padding: var(--e-5);
  background: var(--accent-doux);
  border-radius: var(--rayon-m);
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
}
.merci-reference-etiquette { font-size: var(--t-s); color: var(--texte-secondaire); }
.merci-reference-valeur {
  font-family: var(--police-mono);
  font-size: var(--t-xl);
  letter-spacing: 0.04em;
  overflow-wrap: anywhere;
}
.merci-lignes { list-style: none; margin: 0 0 var(--e-4); padding: 0; display: flex; flex-direction: column; gap: var(--e-2); }
.merci-lignes li { display: grid; gap: var(--e-1); }
.merci-echeance {
  margin: var(--e-5) 0;
  padding: var(--e-3) var(--e-4);
  background: var(--alerte-doux);
  color: var(--alerte);
  border-radius: var(--rayon-s);
}
.merci-virement,
.merci-paypal {
  margin: var(--e-6) 0;
  padding: var(--e-5);
  background: var(--fond-surface);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-m);
  box-shadow: var(--ombre-s);
}
.merci-coordonnees { margin: var(--e-4) 0 0; display: flex; flex-direction: column; gap: var(--e-3); }
.merci-coordonnees dt { font-size: var(--t-s); color: var(--texte-secondaire); }
.merci-coordonnees dd {
  margin: 0;
  font-family: var(--police-mono);
  /* Un IBAN de 27 caractères ne tient pas sur un téléphone : il se coupe plutôt que de
     faire défiler toute la page horizontalement. */
  overflow-wrap: anywhere;
}

@media (min-width: 35rem) {
  .commander-ligne-double { grid-template-columns: 10rem minmax(0, 1fr); }
  .commander-recap-lignes li,
  .merci-lignes li { grid-template-columns: minmax(0, 1fr) auto auto; gap: var(--e-3); align-items: baseline; }
}

@media (min-width: 56.25rem) {
  .commander {
    grid-template-columns: minmax(0, 1fr) 20rem;
    grid-template-areas: 'formulaire recapitulatif';
  }
  .commander-form { grid-area: formulaire; }
  .commander-recap { grid-area: recapitulatif; }
}

/* ── Demande de devis et pages légales (tâche D7) ─────────────────────────────── */

/* Une colonne ÉTROITE et alignée à gauche, pas la `.section-etroite` centrée : ces deux
   surfaces sont du texte long, et un texte long centré ou pleine largeur ne se lit pas.
   ~68 caractères par ligne est la mesure confortable admise en typographie. */
.section-texte,
.page-legale {
  max-width: 44rem;
  margin-inline: auto;
}

.devis-form { margin-top: var(--e-5); }

/* La borne dont parle la demande, rappelée en tête du formulaire : un encadré léger, pas
   une alerte — c'est une information, pas un problème. */
.devis-borne {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--e-2);
  padding: var(--e-3) var(--e-4);
  background: var(--accent-doux);
  border-radius: var(--rayon-m);
}

/* Les pages légales sont hiérarchisées par leurs seuls titres : pas de cadre, pas de
   fond, rien qui distraie d'une lecture qu'on ne fait qu'une fois mais entièrement. */
.page-legale h2 {
  font-size: var(--t-l);
  margin-top: var(--e-6);
  padding-top: var(--e-4);
  border-top: 1px solid var(--bordure);
}
.page-legale h2:first-of-type { margin-top: var(--e-5); }
.page-legale ul { margin: 0 0 var(--e-4); padding-left: var(--e-5); }
.page-legale li { margin-bottom: var(--e-2); }
.page-legale .tableau-cadre { margin-bottom: var(--e-4); }
/* Un tableau de prix se lit mieux sur plusieurs lignes qu'en défilant : la colonne des
   délais est du texte, pas un identifiant. */
.page-legale table.tableau td:last-child,
.page-legale table.tableau th:last-child { white-space: normal; }
.page-legale table.tableau th { position: static; }

/* Ce qui doit ressortir d'un texte juridique : le formulaire de rétractation à recopier,
   et la phrase qui dit qu'une garantie commerciale n'efface pas la garantie légale. */
.page-legale-encadre {
  padding: var(--e-4);
  background: var(--fond-attenue);
  border-left: 3px solid var(--accent-clair);
  border-radius: var(--rayon-s);
}

/* ── Espace client (tâche E2) ─────────────────────────────────────────────────── */

/* Des blocs empilés plutôt qu'un tableau : un historique de commandes se consulte plus
   souvent sur un téléphone que sur un écran large, et un tableau à cinq colonnes y
   défile horizontalement — c'est-à-dire qu'on n'en voit jamais la fin. Chaque commande
   est une carte qui se lit d'un coup d'œil, dans les deux formats. */
.compte-bloc { margin: var(--e-6) 0; }
.compte-bloc h2 {
  font-size: var(--t-l);
  padding-bottom: var(--e-2);
  border-bottom: 1px solid var(--bordure);
}
.compte-definitions { margin: 0; display: flex; flex-direction: column; gap: var(--e-3); }
.compte-definitions dt { font-size: var(--t-s); color: var(--texte-secondaire); }
.compte-definitions dd { margin: 0; }
/* Plusieurs adresses email sur une fiche : l'une sous l'autre, jamais séparées par une
   virgule — une adresse coupée en fin de ligne par une virgule se recopie fausse. */
.compte-email { display: block; overflow-wrap: anywhere; }

.compte-liste { list-style: none; margin: var(--e-4) 0; padding: 0; display: flex; flex-direction: column; gap: var(--e-3); }
.compte-commande {
  padding: var(--e-4);
  background: var(--fond-surface);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-m);
}
.compte-commande-tete { margin: 0; display: flex; flex-wrap: wrap; gap: var(--e-3); align-items: baseline; }
.compte-commande-ref { font-weight: 600; }
.compte-commande-tete .prix { margin-left: auto; }
.compte-commande-etats { margin: var(--e-2) 0 0; display: flex; flex-wrap: wrap; gap: var(--e-2); align-items: center; }
.compte-commande-echeance { margin: var(--e-2) 0 0; color: var(--alerte); }

.compte-ligne,
.compte-transaction,
.compte-expedition,
.compte-facture {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-2) var(--e-3);
  align-items: baseline;
}
.compte-ligne-libelle { flex: 1 1 12rem; }
.compte-ligne .prix,
.compte-transaction .prix,
.compte-facture .prix { margin-left: auto; }
.compte-adresse { margin: 0 0 var(--e-4); line-height: 1.5; }
