/* ============================================================
   DK EVENTS — système de design
   Direction « L'affiche », choisie par le client le 26 septembre 2026
   parmi trois modèles.

   Le site est un miroir de la fête : il ne décore pas, il renvoie.
   Son esthétique s'efface devant les flyers des organisateurs, qui
   sont la seule matière vive de l'écran.

   Six règles, toutes issues de décisions du client :

   1. Fond clair. L'acheteur décide le samedi à seize heures, dehors,
      au soleil. Et un flyer, toujours sombre et saturé, ne brille que
      posé sur du clair.
   2. Un seul cri par écran. Une chose est énorme, tout le reste est
      presque silencieux. La hardiesse partout devient du bruit.
   3. Rond là où on touche, carré là où on regarde. Le pouce cherche
      un bouton qui s'enfonce ; l'œil lit une affiche à angles droits.
   4. Une seule couleur vivante à la fois, celle de l'organisateur
      qu'on regarde. Le cadre est constant, c'est le reflet qui change.
   5. Rien ne bouge sans qu'on le touche. Le mouvement répond à un
      geste, il ne se fait jamais remarquer. Une seule exception,
      décidée par le client le 27 septembre 2026 : le décor du héros
      de l'accueil passe seul en fondu. Il se fige si le visiteur a
      demandé moins de mouvement, et s'arrête quand l'onglet est caché.
   6. Aucun élément décoratif qui ne porte pas d'information.
   ============================================================

   Identite « La Bringue » appliquee le 27 septembre 2026. Les tokens
   ci-dessous ne portent plus de valeur : ils pointent sur ceux de la
   marque, importes juste au-dessus. Les six regles ci-dessus tiennent
   toujours, c'est la matiere qui change.
   ============================================================ */
@import url("brand/tokens.css");

:root{
  /* Le papier de la marque est jaune : c'est le fond de toutes les pages.
     Les cartes, elles, sont en papier creme. */
  --paper:var(--lb-jaune);
  --paper-2:var(--lb-papier);
  --card:var(--lb-papier);

  /* Tout le texte est bleu encre. Mesure : 7,08 sur le jaune,
     10,60 sur le papier. Le secondaire descend a 6,87 et 10,29. */
  --ink:var(--lb-bleu);
  --ink-soft:var(--lb-bleu-doux);
  --ink-mute:var(--lb-bleu-doux);
  --line:var(--lb-bleu);
  --line-fort:var(--lb-bleu);

  /* Le rouge ne porte JAMAIS de texte : 2,72 sur le jaune, 4,08 sur le
     papier. La marque l'interdit et la mesure lui donne raison. Il ne
     sert qu'aux ombres portees, ou il ne se lit pas. Les trois couleurs
     de bouton du site convergent donc sur le bleu, avec le rouge en
     ombre : un seul cri par ecran, comme le veut la regle 2. */
  --accent:var(--lb-bleu);   --accent-o:var(--lb-rouge);
  --vert:var(--lb-bleu);     --vert-o:var(--lb-rouge);
  --violet:var(--lb-bleu);   --violet-o:var(--lb-rouge);

  /* La marque veut des coins peu arrondis, partout les memes. */
  --r-img:var(--lb-radius);
  --r-bloc:var(--lb-radius);
  --r-touche:var(--lb-radius);

  --rythme:clamp(52px,6.5vw,92px);
  --wrap:1180px;
  --press:4px;
  --titre:var(--lb-font-titre);
  --corps:var(--lb-font-texte);
  --info:var(--lb-font-info);
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--paper); color:var(--ink);
  font-family:var(--corps); font-size:17px; line-height:1.55;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4{
  font-family:var(--titre); font-weight:400; line-height:.96; margin:0;
  letter-spacing:-.005em; text-transform:uppercase; text-wrap:balance;
}
p{margin:0}
a{color:inherit}
img,svg{display:block; max-width:100%}
button{font:inherit; color:inherit}
:focus-visible{outline:3px solid var(--accent); outline-offset:3px; border-radius:3px}
.wrap{max-width:var(--wrap); margin-inline:auto; padding-inline:20px}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.mono{font-variant-numeric:tabular-nums}

/* ---------- Bouton : rond, et il s'enfonce ----------
   Sur une mauvaise connexion, l'enfoncement est la seule preuve
   immédiate que le doigt a été entendu. Ce n'est pas un ornement. */
.btn{
  --bg:var(--accent); --sh:var(--accent-o); --fg:#fff;
  display:inline-flex; align-items:center; gap:9px; justify-content:center;
  padding:14px 24px; border:0; border-radius:var(--r-touche);
  background:var(--bg); color:var(--fg); cursor:pointer;
  font-family:var(--titre); font-weight:400; font-size:17px;
  text-transform:uppercase; letter-spacing:.03em;
  box-shadow:0 var(--press) 0 var(--sh);
  transition:transform .07s ease, box-shadow .07s ease, filter .14s ease;
  text-decoration:none; white-space:nowrap;
}
.btn:hover{filter:brightness(1.06)}
.btn:active{transform:translateY(var(--press)); box-shadow:0 0 0 var(--sh)}
.btn[disabled]{opacity:.42; cursor:not-allowed}
.btn[disabled]:active{transform:none; box-shadow:0 var(--press) 0 var(--sh)}
.btn--ink{--bg:var(--ink); --sh:#000; --fg:#fff}
.btn--mint{--bg:var(--vert); --sh:var(--vert-o); --fg:#fff}
.btn--grape{--bg:var(--violet); --sh:var(--violet-o); --fg:#fff}
.btn--ghost{
  --bg:var(--card); --sh:var(--line-fort); --fg:var(--ink);
  box-shadow:0 var(--press) 0 var(--sh), inset 0 0 0 1.5px var(--line-fort);
}
.btn--ghost:active{box-shadow:0 0 0 var(--sh), inset 0 0 0 1.5px var(--line-fort)}
.btn--sm{padding:11px 17px; font-size:15px; --press:3px}
.btn--lg{padding:18px 30px; font-size:20px; --press:5px}
.btn--wide{width:100%}

/* ---------- En-tête ---------- */
header{position:sticky; top:0; z-index:60; padding:12px 0; background:var(--paper)}
header.stuck{border-bottom:1px solid var(--line)}
/* Logo au centre : trois colonnes, les deux côtés de même largeur, pour
   que le logo tombe au milieu quelle que soit la place des voisins. La
   navigation à gauche, lue d'abord ; l'action à droite, dans l'axe du
   décor du héros. L'ordre du document ne change pas : logo, navigation,
   action, comme partout ailleurs. */
.bar{
  display:grid; grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);
  grid-template-areas:"nav logo action"; align-items:center; column-gap:18px;
}
.bar .lb-logo{grid-area:logo}
.bar .nav{grid-area:nav; justify-self:start}
.bar .right{grid-area:action; justify-self:end}
.bar .menu{display:none}
.logo{
  display:flex; align-items:center; gap:9px; text-decoration:none;
  font-family:var(--titre); font-size:23px; letter-spacing:.005em; text-transform:uppercase;
}
.logo .mark{
  width:32px; height:32px; flex:none; border-radius:var(--r-img);
  background:var(--ink); display:grid; place-items:center; color:var(--paper); font-size:15px;
}
.nav{display:flex; gap:2px}
.nav a, .nav-lien{
  padding:11px 14px; text-decoration:none; border-radius:var(--r-touche);
  font-weight:600; font-size:15.5px; color:var(--ink-mute);
  transition:color .14s ease, background .14s ease;
}
.nav a:hover, .nav-lien:hover{color:var(--ink); background:var(--paper-2)}
.nav a[aria-current="page"], .nav-lien[aria-current="page"]{color:var(--ink); background:var(--paper-2)}
.bar .right{display:flex; align-items:center; gap:10px}

/* ---------- Héros ----------
   Deux colonnes, à la manière de DICE, calées sur sa capture : le décor
   occupe 48 % de la colonne du site, au rapport 4:5, collé sous l'en-tête
   et aligné sur le bord droit de la colonne, comme le bouton de l'en-tête.
   Le texte, immobile, porte le seul cri de l'écran et se centre face au
   décor. Le décor est muet (aria-hidden) : il ne dit rien que le texte ne
   dise déjà. */
.hero{
  /* padding nul en haut : la règle générale des sections laissait une
     bande jaune entre l'en-tête et le décor, qui doit coller comme sur DICE. */
  padding:0 20px clamp(32px,5vw,64px);
  max-width:var(--wrap); margin-inline:auto;
  display:grid; grid-template-columns:minmax(0,1fr) 48%; align-items:center;
  column-gap:clamp(24px,3.6vw,52px);
}
.hero-texte{padding-block:24px}
.hero h1{font-size:clamp(34px,4.6vw,66px); line-height:.9}
.hero p.chapo{margin-top:18px; font-size:18px; color:var(--ink-soft); max-width:38ch}
.hero-actions{margin-top:26px; display:flex; gap:12px; flex-wrap:wrap}
.eyebrow{
  display:inline-flex; align-items:center; gap:9px; padding:7px 14px;
  border:1px solid var(--line-fort); border-radius:99px;
  font-weight:700; font-size:13.5px; margin-bottom:18px;
}
.eyebrow .pastille{width:8px; height:8px; border-radius:50%; background:var(--accent)}

/* Le décor. Angles francs, fond sombre uni : le bleu de la marque.
   Sa hauteur ne dépasse jamais 87 % de la fenêtre, la part que DICE lui
   donne ; au-delà, il rétrécit en gardant son rapport. Les scènes sont
   empilées, une seule visible, et l'on passe de l'une à l'autre par une
   coupe franche, comme sur DICE. */
.hero-scene{
  position:relative; overflow:hidden; background:var(--lb-bleu);
  align-self:start; justify-self:end;
  width:min(100%, calc(87vh * .8)); width:min(100%, calc(87svh * .8));
  aspect-ratio:4/5;
}
/* Une scène cachée l'est par l'opacité, sur une couche préparée
   (will-change) : elle reste peinte et revient sans être redessinée.
   Cachée par visibility, le motif de mascottes était repeint en entier
   à chaque retour, et cette image-là prenait 20 à 30 ms de retard. La
   coupe reste franche : aucune transition. */
.hero-slide{position:absolute; inset:0; opacity:0; pointer-events:none; will-change:opacity}
.hero-slide.est-visible{opacity:1}
.hero-slide > img{width:100%; height:100%; object-fit:cover}
/* Le téléphone du décor : un iPhone 17 Pro Max dessiné en CSS, sans
   image ni marque. On imite la forme, pas le logo. Tout se mesure en
   cqw, la largeur de la scène : l'appareil garde ses proportions à
   toutes les tailles. Écran 1320 × 2868, coins concentriques entre
   l'écran, la bordure noire et le cadre en aluminium. Ses coins ronds
   sont ceux d'un objet dessiné : la règle des 6 px ne s'y applique pas.
   Le coloris « Silver » est dans --tel-alu, pour pouvoir en changer. */
:root{
  --tel-alu:#C6C9CE; --tel-alu-clair:#EEF0F2; --tel-alu-sombre:#8C9097;
  --tel-noir:#0A0A0B;
}
.hero-slide--tel{display:grid; place-items:center; background:var(--lb-bleu); container-type:size}
.tel{
  position:relative; width:50cqw; padding:1.05cqw; border-radius:9.6cqw;
  background:linear-gradient(135deg, var(--tel-alu-clair) 0%, var(--tel-alu) 24%, var(--tel-alu-sombre) 50%,
    var(--tel-alu) 72%, var(--tel-alu-clair) 100%);
  box-shadow:
    inset 0 0 0 .16cqw rgba(255,255,255,.6),
    inset 0 0 0 .34cqw rgba(0,0,0,.16),
    0 3.4cqw 5.6cqw -1.2cqw rgba(0,0,0,.55),
    0 1.1cqw 1.8cqw rgba(0,0,0,.32);
}
/* Les boutons de la tranche, en léger relief : à gauche Action et les
   deux volumes, à droite le bouton latéral et, plus bas, la commande de
   l'appareil photo, plus plate. */
.tel-bouton{
  position:absolute; width:.55cqw; border-radius:.3cqw;
  background:linear-gradient(90deg, var(--tel-alu-sombre), var(--tel-alu-clair) 55%, var(--tel-alu));
  box-shadow:0 0 .2cqw rgba(0,0,0,.35);
}
.tel-bouton--action{left:-.42cqw; top:17%; height:4.6%}
.tel-bouton--volume-haut{left:-.42cqw; top:25%; height:8.4%}
.tel-bouton--volume-bas{left:-.42cqw; top:35.4%; height:8.4%}
.tel-bouton--lateral{right:-.42cqw; top:27%; height:12.5%}
.tel-bouton--camera{right:-.28cqw; top:57%; height:7%; width:.38cqw; background:linear-gradient(90deg, var(--tel-alu), var(--tel-alu-sombre))}
.tel-verre{padding:.8cqw; border-radius:8.55cqw; background:var(--tel-noir)}
.tel-ecran{
  position:relative; aspect-ratio:1320/2868; border-radius:7.75cqw; overflow:hidden; background:var(--lb-bleu);
}
/* Un reflet à peine visible sur la vitre, qui ne passe jamais devant
   la lecture : 12 % de blanc au plus, dans l'angle haut. */
.tel-ecran::after{
  content:""; position:absolute; inset:0; z-index:6; pointer-events:none;
  background:linear-gradient(118deg, rgba(255,255,255,.12) 0%, rgba(255,255,255,.04) 20%, rgba(255,255,255,0) 38%);
}
.tel-statut{
  position:absolute; top:0; left:0; right:0; z-index:4; height:6.2%;
  display:flex; align-items:center; justify-content:space-between; padding:0 6.5% 0 10%;
  color:var(--lb-papier); font-weight:700; font-size:2.3cqw; letter-spacing:-.01em;
}
.tel-icones{display:flex; align-items:center; gap:.8cqw}
.tel-icones svg{display:block; height:1.5cqw; width:auto}
.tel-ile{
  position:absolute; top:1.25%; left:50%; z-index:5; transform:translateX(-50%);
  width:28.6%; height:3.9%; border-radius:999px; background:var(--tel-noir);
}
/* La zone sûre : sous l'île, au-dessus de l'indicateur d'accueil. */
.tel-contenu{position:absolute; top:6.6%; bottom:3.3%; left:0; right:0; overflow:hidden}
.tel-accueil{
  position:absolute; bottom:1.1%; left:50%; z-index:5; transform:translateX(-50%);
  width:34%; height:.55%; min-height:3px; border-radius:999px; background:var(--lb-papier);
}
/* L'écran montre evenement.html elle-même, en mode vitrine : un cadre
   large de 375 px, la largeur d'un téléphone, que index.html met à
   l'échelle de l'écran dessiné (transform) et dont il règle la hauteur.
   La barre d'état et l'indicateur d'accueil sont en papier, 10,60 sur le
   bleu : la page d'une fête est sombre en haut. Le cadre ne reçoit aucun
   clic. */
.tel-cadre{
  display:block; width:375px; border:0; background:var(--lb-bleu);
  transform-origin:0 0; pointer-events:none;
}

/* ---------- Recherche et quartiers ---------- */
.recherche{
  display:flex; align-items:center; gap:12px; background:var(--card);
  border:1px solid var(--line-fort); border-radius:var(--r-touche); padding:4px 18px;
}
.recherche input{flex:1; min-width:0; border:0; background:none; font:inherit; font-size:16.5px; color:var(--ink); padding:13px 0}
.recherche input::placeholder{color:var(--ink-mute)}
.recherche input:focus{outline:none}
.quartiers{display:flex; gap:8px; overflow-x:auto; padding:14px 0 4px; scrollbar-width:none}
.quartiers::-webkit-scrollbar{display:none}
.quartier{
  flex:none; padding:11px 17px; border-radius:99px; cursor:pointer;
  border:1px solid var(--line-fort); background:var(--card); color:var(--ink-soft);
  font-weight:700; font-size:14.5px;
  transition:background .12s ease, color .12s ease, border-color .12s ease;
}
.quartier:hover{color:var(--ink)}
.quartier[aria-pressed="true"]{background:var(--ink); color:var(--paper); border-color:var(--ink)}
.compte{font-size:14.5px; color:var(--ink-mute); margin-top:12px}

/* ---------- Les tranches de temps ----------
   Chaque tranche est une balise <section> (index.html) : sans cette remise
   à zéro, la règle générale « section{padding-block:var(--rythme)} » lui
   ajoute 92 px en haut et en bas en plus de sa propre marge, ce qui creusait
   un vide sous chaque carte. L'espacement entre tranches reste porté par
   margin-top ci-dessous, pas par le padding des sections. */
.tranche{margin-top:clamp(28px,3.6vw,44px); padding-block:0}
.tranche:first-child{margin-top:18px}
.tranche-titre{
  display:flex; align-items:center; gap:11px;
  font-size:clamp(21px,2.6vw,28px); margin-bottom:12px;
}

/* ---------- Les cartes publiques (programme.html, « Ce soir » de l'accueil) ----------
   Demande du client du 29 septembre 2026, d'après une billetterie
   sénégalaise : l'affiche en fond, un dégradé sombre qui monte du bas et le
   texte posé dessus. Toute la carte est un seul lien.
   UNE SEULE TAILLE, partout (demande du 30 septembre 2026 : 255 × 170 était
   trop petit, la carte vedette de 1140 × 489 trop grande). Mesurée le
   30 septembre à 1440 px : DICE 4 colonnes de 264 px (image carrée),
   Xceed 273 px, Fever 308 px, Shotgun 3 de 389 px. D'où 4 colonnes dans la
   colonne de 1140 px du site, soit 273 px, en 4:5 (273 × 341) : le format
   d'une affiche, qui se voit sans recadrage brutal. Au-delà de 1440 px la
   colonne ne s'élargit pas : les cartes gardent leur taille.
   Colonnes : 4 à partir de 1200 px, 3 dès 900 px, 2 dès 600 px, 1 en
   dessous (à 375 px, une carte de 335 × 419). Avec une ou deux fêtes,
   les cartes gardent cette taille, alignées à gauche sous leur titre.
   ÉCARTS ASSUMÉS À BRAND.md, voulus par le client, au même titre que le
   dégradé de la page d'une fête : le dégradé (la marque veut des aplats),
   le texte papier sur l'image, le rayon de 12 px (la marque unifie à 6 px)
   et l'ombre douce au lieu de la bordure de 3 px.
   Le bleu nuit du dégradé est --lb-bleu mêlé à 45 % de noir. Le rouge ne
   porte rien. */
.grille{display:grid; grid-template-columns:minmax(0,1fr); gap:16px}
@media (min-width:600px){ .grille{grid-template-columns:repeat(2,minmax(0,1fr))} }
@media (min-width:900px){ .grille{grid-template-columns:repeat(3,minmax(0,1fr))} }
@media (min-width:1200px){ .grille{grid-template-columns:repeat(4,minmax(0,1fr))} }
.carte{
  --nuit:color-mix(in oklab, var(--lb-bleu) 55%, #000);
  /* --zone : la hauteur où vit le texte (date, deux lignes de titre,
     pastilles). Le dégradé y reste à 95 % de nuit au moins. */
  --zone:118px;
  position:relative; display:block; overflow:hidden; isolation:isolate;
  aspect-ratio:4/5; border-radius:12px;
  background:var(--nuit); color:var(--lb-papier); text-decoration:none;
  box-shadow:0 6px 18px rgba(0,0,0,.22), 0 1px 3px rgba(0,0,0,.18);
  transition:transform .12s ease, box-shadow .12s ease;
}
.carte:hover{transform:translateY(-2px); box-shadow:0 10px 24px rgba(0,0,0,.28), 0 2px 4px rgba(0,0,0,.18)}
/* Le focus : un anneau de 3 px en --accent (bleu sur le jaune de
   l'accueil, 7,08 ; jaune sur le bleu du programme, 7,08), détaché. */
.carte:focus-visible{outline:3px solid var(--accent); outline-offset:3px}
.carte-fond{position:absolute; inset:0; z-index:-2}
.carte-fond img{width:100%; height:100%; object-fit:cover; display:block}
/* Sans affiche : la couleur de l'organisateur et son nom en grand, dans
   l'encre mesurée de sa teinte (PALETTE.fg), en haut à gauche, trois
   lignes au plus, toujours au-dessus du dégradé. */
.carte-orga{
  position:absolute; left:16px; right:16px; top:16px;
  font-family:var(--titre); font-size:26px; line-height:1.05;
  overflow:hidden; display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:3;
}
/* Le dégradé : presque plein (97 à 95 %) sur toute la zone du texte, puis
   transparent vers le milieu de la carte : le haut montre l'affiche.
   Le texte ne monte jamais au-dessus de --zone (titre sur deux lignes au
   plus) : le pire pixel sous le texte, sur une affiche blanche, reste à
   95 % de nuit. Mesuré le 30 septembre sur des affiches blanche, jaune
   pâle et pastel : papier 15,2 au pire sous la date et le titre, 10,6
   dans une pastille (sur son voile papier). */
.carte::after{
  content:''; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:linear-gradient(to top,
    color-mix(in oklab, var(--nuit) 97%, transparent) 0%,
    color-mix(in oklab, var(--nuit) 95%, transparent) var(--zone),
    transparent max(55%, calc(var(--zone) + 70px)));
}
.carte-texte{
  position:absolute; left:0; right:0; bottom:0; padding:0 14px 14px;
  display:flex; flex-direction:column; gap:3px; min-width:0;
}
.carte-date{
  font-family:var(--info); font-size:13px; line-height:1.25; font-weight:700; letter-spacing:.06em;
  text-transform:lowercase; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
/* Archivo gras, deux lignes au plus : le titre se lit en entier dans la
   plupart des cas. Bungee, essayée, coupait après huit lettres. */
.carte-titre{
  font-family:var(--corps); font-weight:800; font-size:19px; line-height:1.2;
  text-transform:none; letter-spacing:0; color:inherit; text-shadow:none;
  overflow:hidden; overflow-wrap:anywhere;
  display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2;
}
.carte-pastilles{display:flex; gap:6px; margin-top:4px; min-width:0}
.carte-pastille{
  display:inline-flex; align-items:center; gap:4px; min-width:0; flex:0 1 auto;
  height:24px; padding:0 8px 0 6px; border-radius:999px;
  background:rgba(251,243,223,.14); box-shadow:inset 0 0 0 1px rgba(251,243,223,.38);
  font-size:13px; font-weight:700; line-height:1.25; white-space:nowrap;
}
.carte-pastille:last-child{flex:none}
.carte-pastille span{overflow:hidden; text-overflow:ellipsis}
.carte-pastille svg{width:14px; height:14px; flex:none; fill:currentColor}
/* L'étiquette, en haut à droite : son propre fond papier, texte bleu
   (10,60), quelle que soit l'affiche ; « Complet » en jaune (7,08). */
.carte-etiquette{
  position:absolute; top:12px; right:12px; padding:4px 9px; border-radius:999px;
  background:var(--lb-papier); color:var(--lb-bleu);
  font-family:var(--info); font-size:12px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  box-shadow:0 1px 4px rgba(0,0,0,.3);
}
.carte-etiquette--complet{background:var(--lb-jaune)}
/* Avec une étiquette, le nom de l'organisateur passe dessous. */
.carte:has(.carte-etiquette) .carte-orga{top:52px}
.vide{padding:40px 18px; text-align:center; color:var(--ink-mute)}

/* ---------- Sections ---------- */
section{padding-block:var(--rythme)}
section.serre{padding-block:clamp(28px,3.4vw,46px)}
.titre-sec{display:flex; align-items:baseline; gap:14px; flex-wrap:wrap; margin-bottom:8px}
.titre-sec h2{font-size:clamp(24px,3.2vw,36px)}
.titre-sec p{color:var(--ink-soft); font-size:16px}

/* ---------- Page d'une fête ----------
   Ici on ne compare plus, on regarde : le flyer prend toute la place,
   sans voile ni recadrage, et le cri est le nom de la fête. */
.fil{padding:18px 0 4px; font-size:14px; color:var(--ink-mute)}
.fil a{display:inline-block; padding:10px 6px; margin:-10px -6px; text-decoration:none; border-radius:var(--r-img)}
.fil a:hover{color:var(--accent)}
.visuel{
  border-radius:var(--r-img); overflow:hidden; aspect-ratio:4/5;
}
/* Une affiche remplit son cadre sans se déformer. Sans cette règle,
   object-fit vaut fill : une photo au format paysage serait écrasée
   dans le rapport 4/5 du cadre. */
.art img, .visuel img{width:100%; height:100%; object-fit:cover}
.ev-info h1{font-size:clamp(34px,5vw,58px); line-height:.9; margin-bottom:16px}
.puce-info{
  display:inline-flex; align-items:center; padding:5px 13px; border-radius:99px;
  font-size:12.5px; font-weight:700; margin:0 7px 14px 0;
}
.puce-info--pale{background:var(--paper-2); color:var(--ink-soft)}

.orga-bloc{
  display:flex; align-items:center; gap:13px; margin-top:24px; padding:13px 15px;
  background:var(--card); border:1px solid var(--line); border-radius:var(--r-bloc);
  text-decoration:none; color:inherit; transition:border-color .12s ease;
}
.orga-bloc:hover{border-color:var(--line-fort)}
/* Le fond ET l'encre viennent tous deux du script, par couleurDe() et
   encreSur() : le blanc en dur tombait à 1,54 sur le jaune de la
   palette. L'encre du site sert de repli, pour qu'une panne de script
   laisse du lisible plutôt que du blanc sur du papier. */
.initiales{
  width:46px; height:46px; border-radius:var(--r-img); flex:none; display:grid; place-items:center;
  font-family:var(--titre); font-weight:400; font-size:18px; color:var(--ink);
}
.orga-bloc b{display:block; font-size:16px; font-family:var(--titre); font-weight:400; text-transform:uppercase}
.orga-bloc small{color:var(--ink-mute); font-size:13px}
.orga-bloc .fleche-l{margin-left:auto; color:var(--ink-mute); font-size:21px}

/* ---------- Compteur − n + ---------- */
.compteur{display:flex; align-items:center; gap:3px; flex:none}
.compteur button{
  width:42px; height:42px; border-radius:var(--r-touche); border:1px solid var(--line-fort);
  cursor:pointer; font-size:19px; background:var(--card); color:var(--ink);
  box-shadow:0 3px 0 var(--line-fort); transition:transform .07s ease, box-shadow .07s ease;
}
.compteur button:active{transform:translateY(3px); box-shadow:0 0 0 var(--line-fort)}
.compteur button[disabled]{opacity:.3; cursor:not-allowed}
.compteur button[disabled]:active{transform:none; box-shadow:0 3px 0 var(--line-fort)}
.compteur output{width:36px; text-align:center; font-weight:700; font-size:17px; font-variant-numeric:tabular-nums}

/* ---------- La barre d'achat ----------
   Tarif, quantité et bouton au même endroit, dès le premier écran. Sur
   ordinateur elle suit les faits, dans la colonne d'infos ; sous 900 px
   elle se colle en bas de l'écran (voir la fin du fichier). À zéro billet
   le bouton est à contour (bleu sur jaune : 7,08) et invite à choisir :
   jamais de bouton gris qui a l'air en panne. */
.barre-achat{
  display:grid; gap:12px; margin-top:22px; padding:16px;
  background:var(--card); border:var(--lb-bordure); border-radius:var(--r-bloc);
}
.barre-achat[hidden], .barre-ligne[hidden], .compteur-tarif[hidden]{display:none}
.barre-achat fieldset{border:0; padding:0; margin:0; min-width:0}
.barre-achat legend{
  padding:0; margin-bottom:8px; font-family:var(--titre); font-size:13px;
  text-transform:uppercase; letter-spacing:.02em; color:var(--ink-mute);
}
/* Une à trois colonnes selon le nombre de tarifs de la fête (--colonnes,
   posé par la page) ; au-delà de trois, une seconde rangée. */
.choix-tarifs{display:grid; grid-template-columns:repeat(var(--colonnes, 3),minmax(0,1fr)); gap:8px}
.choix-tarif{position:relative; display:block}
.choix-tarif input{position:absolute; inset:0; margin:0; opacity:0; cursor:pointer}
.choix-tarif span{
  display:flex; flex-direction:column; justify-content:center; gap:2px; height:100%;
  min-height:48px; padding:6px 10px; border:2px solid var(--lb-bleu); border-radius:var(--r-touche);
  background:var(--paper-2); color:var(--ink); line-height:1.15; transition:background .12s ease, color .12s ease;
}
.choix-tarif b{font-size:13.5px}
.choix-tarif small{font-family:var(--info); font-size:12px; letter-spacing:.04em}
/* Choisi : bleu plein, texte papier (10,60). Au repos : bleu sur papier (10,60). */
.choix-tarif input:checked + span{background:var(--lb-bleu); color:var(--lb-papier)}
.choix-tarif input:focus-visible + span{outline:3px solid var(--accent); outline-offset:3px}
.barre-ligne{display:flex; align-items:center; gap:12px}
/* Un seul tarif : son nom et son prix, rien à choisir. */
.barre-seul{display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between; gap:4px 12px; margin:0}
.barre-seul[hidden]{display:none}
.barre-seul b{font-family:var(--titre); font-weight:400; font-size:16px; text-transform:uppercase}
.barre-seul .mono{font-weight:700}
.barre-ligne .btn{flex:1; white-space:normal; text-align:center; font-size:17px; padding:14px 18px}
.compteur-tarif{display:flex; align-items:center; gap:3px}
.compteur-tarif button{width:44px; height:44px}
.barre-total{font-size:14px; color:var(--ink-soft)}
.barre-complet{font-family:var(--titre); font-size:18px; text-transform:uppercase}

/* ---------- Le billet, affiché sur la page après la réservation ---------- */
.billet-final{
  max-width:440px; margin:18px auto 0; padding:18px; text-align:left;
  background:var(--card); border:var(--lb-bordure); border-radius:var(--r-bloc);
}
.billet-final h3{font-size:21px; text-transform:uppercase; margin-bottom:6px}
.bf-fait{font-size:15px; color:var(--ink-soft)}
.bf-lignes{list-style:none; margin:14px 0 0; padding:12px 0 0; border-top:2px dashed var(--lb-bleu)}
.bf-lignes li, .bf-total{display:flex; justify-content:space-between; gap:12px; font-size:15.5px; padding:3px 0}
.bf-total{margin-top:6px; padding-top:8px; border-top:2px solid var(--lb-bleu); font-weight:700}
/* Les QR : assez grands pour la caméra d'un téléphone à la porte, un
   seul de front sur téléphone (le billet y fait moins de 360 px). */
.qrs{display:grid; grid-template-columns:repeat(auto-fill,minmax(170px,1fr)); gap:16px; margin-top:16px}
.qrs figure{margin:0}
.qrs figcaption{display:flex; flex-direction:column; gap:2px; margin-top:6px; font-size:13px; color:var(--ink-soft); text-align:center}
.qrs .qr-code{font-size:13px; font-weight:700; color:var(--ink); text-transform:none}
.qrs .qr-passe{font-weight:700; color:var(--ink)}
/* Un vrai QR (reservation.js, SVG) : modules bleus sur papier (10,60),
   la marge claire de quatre modules est dans le dessin. */
.qr{display:block; width:100%; height:auto; aspect-ratio:1/1; border:2px solid var(--lb-bleu); border-radius:2px}
.qr-fond{fill:var(--lb-papier)}
.qr-modules{fill:var(--lb-bleu)}
.qr-absent{
  display:grid; place-items:center; padding:12px; background:var(--lb-papier);
  border-style:dashed; font-size:13px; color:var(--lb-bleu); text-align:center;
}
/* Le statut d'un billet qui ne fait pas (ou plus) entrer : un tampon au
   trait, dans la couleur du texte du billet (bleu sur papier, 10,60).
   Le rouge ne porte jamais de texte. */
.bf-statut{
  display:inline-block; margin:2px 0 8px; padding:3px 12px;
  border:3px solid currentColor; border-radius:var(--lb-radius);
  font-family:var(--titre); font-size:18px; text-transform:uppercase; letter-spacing:.06em;
}
.bf-statut-texte{margin-bottom:6px; font-weight:700; color:var(--ink)}
/* Le bandeau d'un billet de démonstration : bleu plein, texte papier
   (10,60), en tête du billet, pour qu'aucune capture ne passe pour un
   vrai billet. */
.bf-demo{
  display:flex; flex-direction:column; gap:2px; margin:-18px -18px 14px; padding:10px 18px;
  background:var(--lb-bleu); color:var(--lb-papier); border-radius:3px 3px 0 0; font-size:13.5px;
}
.bf-demo b{font-family:var(--titre); font-weight:400; font-size:15px; text-transform:uppercase; letter-spacing:.04em}
.bf-attente{margin-top:16px; padding-top:14px; border-top:2px dashed var(--lb-bleu)}
.bf-attente .btn{margin-top:12px}
.bf-alerte{margin-top:10px; font-weight:700; color:var(--ink)}
.bf-alerte:empty{display:none}
.bf-lien-billet{margin-top:18px; padding-top:14px; border-top:2px dashed var(--lb-bleu)}
/* En tête du billet, juste après la confirmation : le trait passe dessous. */
.bf-lien-premier{margin:0 0 18px; padding:0 0 14px; border-top:0; border-bottom:2px dashed var(--lb-bleu)}
.bf-lien-pourquoi{margin-bottom:10px; font-weight:700; color:var(--ink)}
.bf-copie:focus{outline:none}
.bf-avert{margin-top:8px; font-size:14px; color:var(--ink-soft)}
.bf-copie{margin-top:4px; font-size:14px; font-weight:700; color:var(--ink)}
.bf-copie:empty{display:none}
.bf-lien-champ{
  display:block; width:100%; margin-top:10px; padding:10px 12px; font:inherit; font-size:13px;
  color:var(--lb-bleu); background:var(--lb-papier); border:2px solid var(--lb-bleu); border-radius:var(--lb-radius);
}
.merci-note{max-width:46ch; margin:16px auto 0; color:var(--ink-soft)}
#merci{scroll-margin-top:90px}
#merciTitre:focus{outline:none}
#merciTitre:focus-visible{outline:3px solid var(--accent); outline-offset:6px}

/* ---------- Contenus d'une fête ---------- */
.contenus{display:grid; grid-template-columns:repeat(auto-fill,minmax(152px,1fr)); gap:12px; margin-top:14px}
.media{
  position:relative; aspect-ratio:9/14; border-radius:var(--r-img); overflow:hidden;
  display:grid; place-items:center; border:0; cursor:pointer; padding:0; width:100%;
  background:var(--paper-2);
}
.media.photo{aspect-ratio:1/1}
.media .lect{
  width:44px; height:44px; border-radius:50%; background:rgba(255,255,255,.94);
  display:grid; place-items:center; color:var(--ink); font-size:16px; padding-left:3px;
}
.media .duree{
  position:absolute; right:8px; bottom:8px; padding:3px 8px; border-radius:99px;
  background:rgba(20,16,12,.8); color:#fff; font-size:12px; font-weight:700;
}
.media .etiq{
  position:absolute; left:8px; top:8px; padding:3px 9px; border-radius:99px;
  background:rgba(255,255,255,.94); font-size:12px; font-weight:700; letter-spacing:.04em; text-transform:uppercase;
}
.media-vide{
  padding:24px 16px; text-align:center; color:var(--ink-mute); font-size:14px;
  background:var(--paper-2); border:1px solid var(--line); border-radius:var(--r-bloc);
}

/* ---------- Page d'un organisateur ----------
   Le cri de cet écran est le chiffre du palmarès : c'est lui la preuve. */
.orga-tete{display:flex; gap:18px; align-items:center; flex-wrap:wrap; padding-top:8px}
.orga-tete .initiales{width:76px; height:76px; font-size:29px}
.orga-tete h1{font-size:clamp(30px,4.4vw,50px); line-height:.92}
.orga-tete .bio{color:var(--ink-soft); max-width:54ch; margin-top:9px}
.verifie{
  display:inline-flex; align-items:center; gap:7px; padding:6px 13px; border-radius:99px;
  background:rgba(10,143,102,.13); color:#076B4C; font-weight:700; font-size:13px; margin-top:10px;
}

.passe{background:var(--card); border:1px solid var(--line); border-radius:var(--r-bloc); padding:20px; margin-bottom:18px}
.passe .haut{display:flex; align-items:center; gap:13px; flex-wrap:wrap; margin-bottom:5px}
.passe h3{font-size:21px}
.passe h3 a{text-decoration:none}
.passe .quand{font-size:14px; color:var(--ink-mute)}
.passe .compte-media{font-size:13px; color:var(--ink-mute); margin-top:2px}

/* ---------- Formulaire ---------- */
.champ{display:grid; gap:6px; margin-bottom:17px}
.champ label, .champ .champ-titre{font-family:var(--titre); font-weight:400; font-size:15px; text-transform:uppercase; letter-spacing:.02em}
.champ .aide{font-size:13.5px; color:var(--ink-mute)}
.champ input, .champ select, .champ textarea{
  font:inherit; font-size:16.5px; color:var(--ink); background:var(--card);
  border:1px solid var(--line-fort); border-radius:var(--r-touche);
  padding:13px 15px; width:100%;
}
.champ input:focus, .champ select:focus, .champ textarea:focus{outline:none; border-color:var(--ink)}
.champ textarea{min-height:118px; resize:vertical}
.champ .erreur{color:var(--accent-o); font-size:13.5px; font-weight:700; margin-top:2px}
.champ input[aria-invalid="true"], .champ select[aria-invalid="true"], .champ textarea[aria-invalid="true"]{border-color:var(--accent)}
.duo{display:grid; grid-template-columns:1fr 1fr; gap:15px}
.etape{
  display:inline-flex; align-items:center; gap:9px; padding:7px 14px; border-radius:99px;
  border:1px solid var(--line-fort); font-weight:700; font-size:13px; margin-bottom:16px;
}
.encart{background:var(--card); border:1px solid var(--line); border-radius:var(--r-bloc); padding:24px}
.merci{text-align:center; padding:50px 18px}
.merci .ref{font-family:var(--titre); font-weight:400; font-size:34px; color:var(--accent); margin:12px 0 6px}

/* ---------- Pied ---------- */
footer{background:var(--ink); color:var(--paper); padding-block:clamp(38px,4.5vw,58px) 26px; margin-top:var(--rythme)}
footer a{color:rgba(255,248,240,.74); text-decoration:none}
footer a:hover{color:var(--paper)}
.pied{display:grid; grid-template-columns:1.4fr 1fr 1fr 1fr; gap:32px}
.pied h4{font-size:13.5px; margin-bottom:11px; color:rgba(255,248,240,.58); letter-spacing:.05em}
.pied ul{list-style:none; margin:0; padding:0; display:grid; gap:9px; font-size:15px}
.pied .mot{font-family:var(--titre); font-size:25px; text-transform:uppercase}
.pied .note{color:rgba(255,248,240,.58); font-size:14.5px; margin-top:10px; max-width:38ch}
.bas-pied{margin-top:30px; padding-top:18px; border-top:1px solid rgba(255,248,240,.16); font-size:13.5px; color:rgba(255,248,240,.52)}

/* ---------- Adaptations ---------- */
@media (max-width:900px){
  .pied{grid-template-columns:1fr 1fr}
  /* Sur petit écran le décor passe au-dessus du texte, sur la moitié
     de la hauteur. Le fondu ne change pas. */
  .hero{grid-template-columns:1fr}
  .hero-scene{order:-1; justify-self:center; width:min(100%, calc(60vh * .8)); width:min(100%, calc(60svh * .8))}
  .hero-texte{padding-block:30px 8px}
  /* L'en-tête n'a plus la place de ses trois colonnes : un bouton Menu
     prend la gauche, le logo reste au centre, et la navigation avec
     l'action s'ouvrent dessous, sur toute la largeur. Le bouton est posé
     par enTete() (data.js), qui ajoute aussi avec-menu : sans lui, rien
     ne se replie et les liens restent visibles sous le logo. */
  .bar{grid-template-areas:"menu logo ." "nav nav nav" "action action action"; row-gap:8px}
  .bar .nav{justify-self:stretch; justify-content:center; flex-wrap:wrap}
  .bar .right{justify-self:stretch; justify-content:center}
  .bar .menu{grid-area:menu; justify-self:start; display:inline-flex; min-height:44px}
  header.avec-menu .bar .nav, header.avec-menu .bar .right{display:none}
  header.avec-menu.menu-ouvert .bar .nav{display:flex; flex-direction:column; margin-top:6px}
  header.avec-menu.menu-ouvert .bar .right{display:flex; padding-bottom:6px}
  header.menu-ouvert .bar .right .btn{flex:1}
  /* Trois traits, qui se croisent en X quand le menu est ouvert. */
  .menu-icone{position:relative; width:18px; height:2px; background:currentColor; flex:none}
  .menu-icone::before, .menu-icone::after{
    content:""; position:absolute; left:0; width:18px; height:2px; background:currentColor;
    transition:transform .14s ease, top .14s ease;
  }
  .menu-icone::before{top:-6px}
  .menu-icone::after{top:6px}
  .menu[aria-expanded="true"] .menu-icone{background:transparent}
  .menu[aria-expanded="true"] .menu-icone::before{top:0; transform:rotate(45deg)}
  .menu[aria-expanded="true"] .menu-icone::after{top:0; transform:rotate(-45deg)}
  /* Le menu ouvert tient au-dessus de la page, sans la faire défiler
     derrière lui sur un petit téléphone. */
  header.menu-ouvert{max-height:100vh; max-height:100svh; overflow-y:auto}
}
/* Sous 520 px, le mot « Menu » ne tient plus à côté du logo centré (le
   bouton fait 108 px avec lui, il en faudrait au moins 483 de largeur) : il
   reste lu par les lecteurs d'écran, le bouton devient un carré de 44 px. */
@media (max-width:520px){
  .bar .menu{width:44px; padding:0}
  .bar .menu .menu-texte{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap}
}
@media (max-width:640px){
  body{font-size:16px}
  .duo{grid-template-columns:1fr}
  .pied{grid-template-columns:1fr}
}
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms !important; transition-duration:.01ms !important}
  .btn:active, .compteur button:active{transform:none}
}

/* ============================================================
   IDENTITE « LA BRINGUE »
   Ce que la bascule des tokens ne couvre pas seule : les valeurs qui
   etaient ecrites en dur, les bordures de 3 px voulues par la marque,
   et la troisieme police, reservee aux informations chiffrees.
   ============================================================ */

/* --- Le logo, piste E : tete de la mascotte, LA au-dessus de BRINGUE --- */
.lb-logo{
  display:inline-flex; align-items:center; gap:12px;
  background:var(--lb-bleu); padding:8px 16px; border-radius:var(--lb-radius);
  text-decoration:none;
}
.lb-logo img{width:40px; height:62px}
.lb-logo__texte{display:flex; flex-direction:column; line-height:1}
.lb-logo__la{
  font-family:var(--lb-font-info); font-weight:700; font-size:11px;
  letter-spacing:.4em; color:var(--lb-jaune);
}
.lb-logo__nom{font-family:var(--lb-font-titre); font-size:28px; color:var(--lb-papier)}
@media (max-width:640px){
  .lb-logo{padding:6px 12px; gap:9px}
  .lb-logo img{width:30px; height:47px}
  .lb-logo__nom{font-size:21px}
}

/* --- Les informations chiffrees : dates, prix, references, etiquettes --- */
.mono,
.compteur output, .media .duree,
.merci .ref{
  font-family:var(--info); text-transform:uppercase; letter-spacing:.12em;
}
.merci .ref{letter-spacing:.06em}
.merci .ref{font-size:27px; color:var(--lb-bleu)}

/* --- Les grands titres portent l'ombre rouge de la marque --- */
.hero h1, .ev-info h1, .orga-tete h1{text-shadow:var(--lb-ombre-titre)}
/* Le surlignage est une bande posee sur la hauteur des capitales, pas
   un fond sur toute la boite du mot : Bungee est plus haute que
   l'interligne de 0,9, et un fond plein mangeait la ligne du dessus
   des que le titre passe sur trois lignes. */
.hero h1 .hl{position:relative; z-index:0}
.hero h1 .hl::before{
  content:''; position:absolute; z-index:-1;
  left:-.08em; right:-.08em; top:.22em; bottom:.1em;
  background:var(--lb-papier);
}

/* --- Les surfaces : papier, bordure bleue de 3 px --- */
.encart, .passe, .orga-bloc, .media-vide,
.recherche, .quartier, .champ input, .champ select, .champ textarea,
.eyebrow, .etape{border:var(--lb-bordure)}
.media{border:var(--lb-bordure)}

/* --- Boutons : fond bleu, texte papier, ombre rouge --- */
.btn{--fg:var(--lb-papier)}
.btn--ink{--bg:var(--lb-bleu); --sh:var(--lb-rouge); --fg:var(--lb-papier)}
.btn--mint{--bg:var(--lb-bleu); --sh:var(--lb-rouge); --fg:var(--lb-papier)}
.btn--grape{--bg:var(--lb-bleu); --sh:var(--lb-rouge); --fg:var(--lb-papier)}
.btn--ghost{--bg:var(--lb-papier); --sh:var(--lb-rouge); --fg:var(--lb-bleu)}
/* Bouton à contour : pas de fond, le jaune passe à travers. Bleu sur
   jaune : 7,08. Il garde l'ombre enfoncée, c'est elle qui dit qu'on
   peut appuyer. */
.btn--contour{
  --bg:transparent; --sh:var(--lb-rouge); --fg:var(--lb-bleu);
  box-shadow:0 var(--press) 0 var(--sh), inset 0 0 0 3px var(--lb-bleu);
}
.btn--contour:active{box-shadow:0 0 0 var(--sh), inset 0 0 0 3px var(--lb-bleu)}

/* --- Les valeurs qui etaient ecrites en dur --- */
.media .lect{background:var(--lb-papier); color:var(--lb-bleu)}
.media .duree{background:var(--lb-bleu); color:var(--lb-papier); font-size:12px}
.media .etiq{background:var(--lb-papier); color:var(--lb-bleu)}
.verifie{background:var(--lb-bleu); color:var(--lb-papier)}
.eyebrow .pastille{background:var(--lb-rouge); border:2px solid var(--lb-bleu); width:12px; height:12px}

/* L'erreur ne peut pas etre rouge : 4,08 sur le papier, sous le seuil.
   Le texte reste bleu et gras, c'est la bordure rouge qui crie. */
.champ .erreur{color:var(--lb-bleu)}
.champ input[aria-invalid="true"],
.champ select[aria-invalid="true"],
.champ textarea[aria-invalid="true"]{border-color:var(--lb-rouge)}

/* --- Le pied de page : bleu, texte papier --- */
footer{background:var(--lb-bleu); color:var(--lb-papier)}
/* Sur l'accueil, le pied de page suit directement la section
   « bizarrement simple », sans marge : la marge générale du pied de page
   (--rythme) laissait voir 92 px du jaune de la page entre les deux
   bandeaux bleus. Un seul trait jaune de 3 px les sépare, en bordure du
   pied de page, choix du client (jaune sur bleu : 7,08). */
footer.pied-colle{margin-top:0; border-top:3px solid var(--lb-jaune)}
footer a{color:rgba(251,243,223,.78)}
footer a:hover{color:var(--lb-papier)}
.pied h4{color:rgba(251,243,223,.6)}
.pied .note{color:rgba(251,243,223,.6)}
.bas-pied{border-top:1px solid rgba(251,243,223,.2); color:rgba(251,243,223,.58)}

/* --- La mascotte --- */
.lb-mascotte{display:block; height:auto}
.lb-mascotte--hero{width:clamp(96px,13vw,150px); margin-top:26px}
.lb-mascotte--merci{width:clamp(120px,18vw,180px); margin:0 auto 6px}
/* La tete brulee ne se pose que sur du bleu, la marque y tient. */
.lb-panneau-sombre{
  background:var(--lb-bleu); color:var(--lb-papier);
  border-radius:var(--lb-radius); padding:clamp(28px,5vw,52px) 22px;
}
.lb-panneau-sombre h1{color:var(--lb-papier); text-shadow:var(--lb-ombre-titre)}
.lb-panneau-sombre p{color:rgba(251,243,223,.82)}
.lb-panneau-sombre .lb-mascotte{width:clamp(110px,16vw,160px); margin:0 auto 18px}
.lb-panneau-sombre .btn{--bg:var(--lb-papier); --sh:var(--lb-rouge); --fg:var(--lb-bleu)}

/* --- La barre d'achat sur téléphone : collée en bas, sous le pouce ---
   Elle reste à l'écran pendant qu'on lit la page, on n'a jamais à
   descendre chercher les billets. La liste et son total restent plus bas
   pour qui compare, sans second bouton. La zone de sécurité du bas
   d'écran est respectée, et la page réserve sous son contenu la hauteur
   de la barre, pour qu'elle ne cache jamais le pied de page. */
@media (max-width:900px){
  .barre-achat{
    position:fixed; left:0; right:0; bottom:0; z-index:50; margin:0; gap:8px;
    padding:10px 16px calc(10px + env(safe-area-inset-bottom));
    border-width:3px 0 0; border-radius:0;
    box-shadow:0 -8px 24px rgba(28,43,143,.16);
  }
  /* Chaque ligne compte : la légende reste lue par les lecteurs d'écran,
     le bouton passe en 15 px et tient sur deux lignes au plus. */
  .barre-achat legend{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap}
  /* Les tarifs sur une seule rangée, qui défile au-delà de trois : la
     barre collée garde sa hauteur quel que soit le nombre de tarifs. La
     marge intérieure laisse voir le contour du focus. */
  .choix-tarifs{
    grid-template-columns:none; grid-auto-flow:column; grid-auto-columns:minmax(96px,1fr);
    overflow-x:auto; padding:4px; margin:-4px; scroll-padding-inline:4px;
  }
  .choix-tarif span{min-height:44px; padding:5px 8px}
  .choix-tarif b{font-size:13px}
  .barre-ligne .btn{font-size:15px; padding:12px 14px; letter-spacing:.02em}
  .barre-total{font-size:13px}
  body.avec-barre{padding-bottom:var(--barre-h, 200px)}
}

/* --- Le décor : la rafale et la mascotte finale ---
   Les plans de la vidéo sont dessinés dans un canvas qui prend tout le
   cadre 4:5, comme les images qu'il reçoit. La mascotte « salut » finit
   la boucle sur le papier de la marque, comme celle de DICE sur blanc. */
.hero-film{display:block; width:100%; height:100%}
.hero-slide--papier{display:grid; place-items:center; background:var(--lb-papier)}
.hero-slide--papier img{width:38%; height:auto}

/* ---------- La billetterie, bizarrement simple ----------
   Bandeau bleu de l'accueil, juste après le programme : un titre et
   trois allumettes en autocollant, chacune avec sa phrase. Transposé
   de la maquette V2 (1440 × 660). Les dessins sont muets (aria-hidden),
   les phrases portent l'information. Rien ne bouge.
   Contraste : papier sur bleu, 10,60. Le rouge ne sert qu'à l'ombre
   du titre, comme partout ailleurs. */
.bizarre{
  /* Trois teintes du dessin que la marque ne nomme pas : les veines du
     bois, la joue et la langue, l'ombre de l'autocollant. */
  --bizarre-veine:#D2B47E;
  --bizarre-joue:#FF7A6B;
  --bizarre-ombre:#0E1650;
  position:relative;
  display:flex; flex-direction:column; align-items:center; gap:40px;
  padding:64px 20px;
  background:var(--lb-bleu); color:var(--lb-papier);
}
.bizarre-defs{position:absolute; width:0; height:0; overflow:hidden}
.bizarre-bord{flood-color:var(--lb-papier)}
.bizarre-ombre{flood-color:var(--bizarre-ombre); flood-opacity:.55}
.bizarre h2{
  font-size:clamp(28px,4vw,44px); line-height:1.1; letter-spacing:normal;
  text-align:center; color:var(--lb-papier);
  text-shadow:4px 4px 0 var(--lb-rouge);
}
.bizarre-grille{
  display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:56px;
  width:100%; max-width:1120px; margin:0; padding:0; list-style:none;
}
.bizarre-item{display:flex; flex-direction:column; align-items:center; gap:20px}
/* Le liseré papier et l'ombre de l'autocollant débordent du cadre du
   dessin : on les laisse dépasser plutôt que de les rogner. */
.bizarre-sticker{height:380px; width:auto; max-width:100%; overflow:visible}
.bizarre-item p{
  max-width:300px; text-align:center;
  font-size:19px; line-height:1.4; font-weight:500;
}

/* Couleurs du dessin, toutes par les tokens de la marque. */
.bizarre-sticker .bs-f-jaune{fill:var(--lb-jaune)}
.bizarre-sticker .bs-f-rouge{fill:var(--lb-rouge)}
.bizarre-sticker .bs-f-flamme{fill:var(--lb-flamme)}
.bizarre-sticker .bs-f-papier{fill:var(--lb-papier)}
.bizarre-sticker .bs-f-ciel{fill:var(--lb-ciel)}
.bizarre-sticker .bs-f-bois{fill:var(--lb-bois)}
.bizarre-sticker .bs-f-bleu{fill:var(--lb-bleu)}
.bizarre-sticker .bs-f-joue{fill:var(--bizarre-joue)}
.bizarre-sticker .bs-t-bleu{stroke:var(--lb-bleu)}
.bizarre-sticker .bs-t-papier{stroke:var(--lb-papier)}
.bizarre-sticker .bs-t-ciel{stroke:var(--lb-ciel)}
.bizarre-sticker .bs-t-joue{stroke:var(--bizarre-joue)}
.bizarre-sticker .bs-t-veine{stroke:var(--bizarre-veine)}

/* Sous 900 px, une colonne : les allumettes passent à 240 px de haut,
   et la marge latérale laisse la place au liseré qui déborde. */
@media (max-width:900px){
  .bizarre{padding:48px 20px; gap:32px}
  .bizarre-grille{grid-template-columns:minmax(0,1fr); gap:40px; max-width:420px}
  .bizarre-item{gap:16px}
  .bizarre-sticker{height:240px; max-width:calc(100% - 32px)}
}

/* ---------- Au programme ----------
   programme.html reprend le programme complet de l'accueil (recherche,
   quartiers, tranches, cartes) avec les classes ci-dessus ; l'accueil ne
   garde que « Ce soir » et renvoie ici. Seuls s'ajoutent le titre de la
   page et le lien de l'accueil vers elle. */
.programme-titre{font-size:clamp(30px,4.4vw,46px)}
.programme-chapo{color:var(--ink-soft); font-size:18px; margin-top:14px}
.recherche--programme{margin-top:24px}
.vers-programme{margin-top:clamp(22px,3vw,32px); text-align:center}
.vide--soir{padding-bottom:0}
/* Sur l'accueil, la tranche « Ce soir » est une <section> et en garde
   le rythme vertical : sans ce réglage, le lien flotte à 90 px des cartes. */
.ce-soir .tranche{padding-bottom:0}
/* Avec « Au programme », la navigation compte quatre liens. Chacun tient
   sur une ligne ; entre 901 et 1180 px, à 15,5 px et 14 px de marge, ils
   ne tiendraient plus dans leur colonne et passeraient sous le logo. On
   les resserre, sans toucher à leur hauteur de 40 px et plus. */
.nav a{white-space:nowrap}
/* La cible de 40 px ne dépend plus de la marge : même forme que .nav-lien. */
.nav a{display:inline-flex; align-items:center; min-height:40px}
@media (min-width:901px) and (max-width:1180px){
  .bar{column-gap:12px}
  .nav{gap:0}
  .nav a{padding-inline:6px; font-size:14px}
}

/* --- « Aide » à droite du logo ---
   Demande du client : Aide quitte la navigation de gauche et passe dans
   la colonne de droite, avant le bouton. Il garde l'allure d'un lien de
   navigation (.nav-lien reprend .nav a) et se resserre comme eux entre
   901 et 1180 px. Dans le menu mobile ouvert, la colonne de droite se
   range sous les autres liens : Sortir, Au programme, Organisateurs,
   Aide, puis le bouton sur toute la largeur. */
.nav-lien{display:inline-flex; align-items:center; min-width:40px; min-height:40px; text-decoration:none; white-space:nowrap}
@media (min-width:901px) and (max-width:1180px){
  .nav-lien{padding-inline:6px; font-size:14px}
}
@media (max-width:900px){
  header.avec-menu.menu-ouvert .bar .right{flex-direction:column; align-items:stretch; gap:6px}
}

/* --- « Mes billets » dans la barre, sous 900 px ---
   Posé par enTete() (data.js) à droite du logo, hors du menu replié : un
   acheteur doit trouver son billet d'un geste, à la porte. Au-dessus de
   900 px il est caché (celui de la colonne de droite suffit) ; en dessous,
   c'est celui de la colonne de droite qui l'est. Cible de 44 px. Sous
   520 px, le billet dessiné seul, le mot restant lu par les lecteurs
   d'écran, comme le bouton Menu. */
.billets-barre{display:none}
@media (max-width:900px){
  header.avec-menu .bar{grid-template-areas:"menu logo billets" "nav nav nav" "action action action"}
  header.avec-menu .bar > .billets-barre{
    grid-area:billets; justify-self:end; display:inline-flex; gap:8px;
    min-height:44px; min-width:44px; justify-content:center; padding-block:0;
    color:var(--ink);
  }
  header.avec-menu .bar .right > [data-page="billets"]{display:none}
}
@media (max-width:520px){
  header.avec-menu .bar > .billets-barre{width:44px; padding:0}
  .billets-barre__texte{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap}
}
@media (min-width:521px){
  .billets-barre__icone{display:none}
}

/* --- Un bouton ne déborde jamais sur petit écran ---
   .btn reste sur une ligne tant qu'il tient ; sous 640 px, un libellé
   trop long (« Voir une page d'organisateur » sur creer.html, 54 px de
   trop à 375 px) passe à la ligne au lieu de sortir de l'écran. */
@media (max-width:640px){
  .btn{white-space:normal; text-align:center; max-width:100%}
}

/* --- « Ce soir » sur l'accueil : le titre et « Voir tout le programme »
   sur la même ligne, le lien tout à droite, au-dessus des cartes. Un lien
   discret, pas un bouton : Martian Mono en capitales, 13 px, et une zone
   cliquable de 40 px de haut. S'il ne tient plus sur la ligne, il passe
   juste dessous, toujours à droite, jamais sous les cartes. --- */
.tete-rubrique{
  display:flex; align-items:baseline; justify-content:space-between; flex-wrap:wrap;
  gap:0 16px; margin-top:18px;
}
.tete-rubrique .tranche-titre{margin-bottom:0}
.tout-voir{
  margin-left:auto; display:inline-flex; align-items:center; gap:8px; min-height:40px;
  font-family:var(--info); font-size:13px; font-weight:700; text-transform:uppercase; letter-spacing:.12em;
  color:var(--ink); text-decoration:underline; text-decoration-thickness:2px; text-underline-offset:5px;
  text-decoration-color:transparent; transition:text-decoration-color .14s ease;
}
.tout-voir:hover{text-decoration-color:currentColor}
.ce-soir .grille, .ce-soir .vide{margin-top:12px}

/* ---------- Au programme, en bleu ----------
   Demande du client du 28 septembre 2026 : sur programme.html, tout ce
   qui était jaune passe en bleu encre. Le périmètre est body.page-bleue,
   posé sur cette seule page ; les autres gardent le jaune. Les tokens de
   page sont redéfinis ici plutôt que chaque règle réécrite.
   Contrastes mesurés : papier sur bleu 10,60 ; jaune sur bleu 7,08 ;
   bleu sur jaune 7,08 ; bleu sur papier 10,60 ; bleu doux sur papier
   10,29. Le rouge reste une ombre : 2,60 sur le bleu, il ne porte rien.
   La tête du logo est déjà la version pour fond sombre : rien à changer. */
body.page-bleue{
  --paper:var(--lb-bleu);
  --paper-2:var(--lb-papier);
  --ink:var(--lb-papier);
  --ink-soft:var(--lb-papier);
  --ink-mute:var(--lb-papier);
  --line:var(--lb-papier);
  --line-fort:var(--lb-papier);
  --accent:var(--lb-jaune);
}
/* Les surfaces papier reprennent l'encre bleue ; leur bord est jaune
   pour se détacher du fond (7,08). */
.page-bleue .recherche{
  --ink:var(--lb-bleu); --ink-soft:var(--lb-bleu-doux); --ink-mute:var(--lb-bleu-doux);
  --line:var(--lb-bleu); --line-fort:var(--lb-bleu);
  color:var(--lb-bleu); border-color:var(--lb-jaune);
}
.page-bleue .recherche:focus-within{outline:3px solid var(--lb-jaune); outline-offset:3px}
.page-bleue .programme-titre{color:var(--lb-jaune)}
/* La page courante ressort en jaune, texte bleu : 7,08. Le survol
   passe au papier, texte bleu : 10,60. */
.page-bleue .nav a:hover, .page-bleue .nav-lien:hover{background:var(--lb-papier); color:var(--lb-bleu)}
.page-bleue .nav a[aria-current="page"], .page-bleue .nav-lien[aria-current="page"]{background:var(--lb-jaune); color:var(--lb-bleu)}
/* Bouton de l'en-tête et bouton Menu : jaune, texte bleu. */
.page-bleue .btn--ghost{
  --bg:var(--lb-jaune); --fg:var(--lb-bleu); --sh:var(--lb-rouge);
  box-shadow:0 var(--press) 0 var(--sh);
}
.page-bleue .btn--ghost:active{box-shadow:0 0 0 var(--sh)}
/* Le pied de page est déjà bleu : un filet papier le sépare de la page. */
.page-bleue footer{border-top:3px solid var(--lb-papier)}

/* Une seule grille, sans tranches : les colonnes et la taille des cartes
   sont celles de .grille, les mêmes que « Ce soir » sur l'accueil ; la
   date se lit sur chaque carte. */
.grille--programme{margin-top:18px}

/* ---------- S'abonner à un organisateur ----------
   Le bouton de abonnement.js, dans l'encadré de l'organisateur
   (evenement.html) et en tête de sa page (organisateur.html), puis le
   panneau <dialog> qui demande le numéro. Pas abonné : bouton plein.
   Abonné : bouton à contour, plus discret, comme Shotgun ou Instagram.
   Le rouge ne porte aucun texte : il reste dans les ombres, la bordure
   du champ en erreur et rien d'autre. */
.orga-bloc--abo{flex-wrap:wrap; padding:0; gap:0}
.orga-bloc--abo:hover{border-color:var(--lb-bleu)}
.orga-lien{
  display:flex; align-items:center; gap:13px; flex:1 1 220px; min-width:0;
  padding:13px 15px; min-height:44px; color:inherit; text-decoration:none;
  border-radius:var(--lb-radius);
}
.orga-lien:hover b{text-decoration:underline; text-underline-offset:3px}
.orga-lien > span:last-child{min-width:0}
.abo{display:flex; align-items:center; gap:12px; flex-wrap:wrap}
.orga-bloc--abo .abo{padding:10px 15px 10px 0}
.abo-bouton{min-height:44px; min-width:44px}
/* La phrase de confirmation : vide, elle ne prend aucune place. */
.abo-statut{font-size:14px; color:var(--lb-bleu); font-weight:700; flex-basis:100%}
.abo-statut:empty{display:none}
.abo-statut-boite{flex-basis:100%}
.orga-bloc--abo .abo-statut{padding:0 15px 13px}
.abo--tete{margin-top:14px}
.abo-nombre{font-family:var(--lb-font-info); font-size:14px; color:var(--lb-bleu-doux)}

.abo-panneau{
  width:min(440px, calc(100% - 32px)); max-width:none; margin:auto; padding:0;
  background:var(--lb-papier); color:var(--lb-bleu);
  border:var(--lb-bordure); border-radius:var(--lb-radius);
  box-shadow:6px 6px 0 var(--lb-bleu);
}
.abo-panneau::backdrop{background:color-mix(in srgb, var(--lb-bleu) 55%, transparent)}
.abo-panneau form{padding:22px 20px 20px}
.abo-titre{font-size:clamp(20px,5vw,24px); line-height:1.05}
.abo-phrase{margin-top:10px; font-size:16.5px; color:var(--lb-bleu-doux)}
.abo-champ{margin:18px 0 0}
/* .champ est en grid : sans cette règle, [hidden] ne masquerait rien. */
.abo-champ[hidden]{display:none}
.abo-champ .erreur{margin-top:0}
.abo-actions{display:flex; flex-wrap:wrap; gap:12px; margin-top:20px}
.abo-actions .btn{flex:1 1 150px; min-height:48px}

/* Sous 520 px, le bouton passe sous le nom, sur toute la largeur de
   l'encadré : l'organisateur garde sa ligne, le pouce a sa cible. */
@media (max-width:520px){
  .orga-bloc--abo .abo{padding:0 15px 13px; flex-basis:100%}
  .orga-bloc--abo .abo-bouton{flex:1}
}

/* ---------- Le lieu d'un événement (evenement.html) ----------
   Carte Google Maps intégrée sans clé, et deux liens vers l'appli ou le
   site Google Maps. Seule exception du client à l'interdiction de toute
   dépendance hors Google Fonts (CLAUDE.md), et seulement pour Google Maps :
   à faire valider. */
.lieu-carte{margin-top:20px}
.lieu-carte iframe{
  display:block; width:100%; height:240px;
  border:3px solid var(--lb-bleu); border-radius:var(--lb-radius);
}
.lieu-liens{
  margin-top:16px; display:flex; flex-wrap:wrap; align-items:center; gap:16px 24px;
}
.lieu-nom{
  display:inline-flex; align-items:center; min-height:40px;
  font-weight:700; color:var(--lb-bleu); text-decoration-thickness:2px;
}
@media (min-width:640px){
  .lieu-carte iframe{height:300px}
}

/* --- creer.html : « Ce que ça coûte » mène à #cout, le titre « Quand
   vous êtes payé ». La marge le garde sous l'en-tête collant, et le
   focus posé par l'ancre ne dessine pas de cadre autour d'un titre. --- */
#cout{scroll-margin-top:120px}
#cout:focus{outline:none}

/* ---------- L'espace organisateur : connexion.html, inscription.html ----------
   Demande du client du 28 septembre 2026 : avant de créer un événement,
   l'organisateur se connecte, ou crée son compte à la première visite.
   Les deux pages sont en fond bleu (body.page-bleue) et reprennent les
   classes du formulaire de creer.html (.champ, .aide, .erreur, .duo) ;
   seules les couleurs changent, et seulement dans ce périmètre.
   Contrastes mesurés sur ce fond :
     - libellés, aides et texte courant : papier sur bleu, 10,60 ;
     - erreurs : jaune gras sur bleu, 7,08 (le rouge ne porte aucun texte) ;
     - champs : papier, texte bleu, 10,60 ; en erreur, bordure rouge,
       4,08 contre le papier du champ ;
     - focus : contour jaune de 3 px, décalé sur le bleu, 7,08 ;
     - bouton principal : jaune, texte bleu, 7,08 ; bouton à contour :
       papier sur bleu, 10,60.
   La confirmation de l'inscription est une carte papier, pour que la
   mascotte « ça chauffe », bordée de bleu, se pose sur du clair comme
   le veut BRAND.md. */
body.page-bleue .compte{max-width:520px; margin-inline:auto}
body.page-bleue .compte--large{max-width:720px}
body.page-bleue .compte-titre{font-size:clamp(30px,4.4vw,46px); color:var(--lb-papier)}
body.page-bleue .compte-intro{margin-top:14px; font-size:18px; color:var(--lb-papier); max-width:52ch}
body.page-bleue .compte-form{margin-top:30px}
/* Un titre qui reçoit le focus par le script (changement de vue) ne se
   cadre pas : ce n'est pas une commande. */
body.page-bleue .compte-titre[tabindex="-1"]:focus{outline:none}

/* Ces couleurs sont celles du cadre bleu : :not(.encart *) les retire des
   encarts papier (profil.html), qui gardent celles des surfaces plus bas
   (bord bleu 10,60, erreur bleue 10,60, focus bleu 10,60). Sans cela,
   papier sur papier : champs et boutons invisibles, erreur jaune à 1,50. */
body.page-bleue .compte .champ:not(.encart *) input,
body.page-bleue .compte .champ:not(.encart *) textarea{
  background:var(--lb-papier); color:var(--lb-bleu); border-color:var(--lb-papier);
}
body.page-bleue .compte .champ:not(.encart *) input:focus-visible,
body.page-bleue .compte .champ:not(.encart *) textarea:focus-visible{outline:3px solid var(--lb-jaune); outline-offset:3px}
body.page-bleue .compte .champ input[aria-invalid="true"],
body.page-bleue .compte .champ textarea[aria-invalid="true"]{border-color:var(--lb-rouge)}
body.page-bleue .compte .champ:not(.encart *) .erreur{color:var(--lb-jaune); font-size:14.5px}
body.page-bleue .compte .aide:not(.encart *) a{color:var(--lb-papier); font-weight:700; text-underline-offset:3px}

/* Un groupe par sujet : légende en titre, trait papier au-dessus. */
body.page-bleue .groupe{border:0; margin:0 0 30px; padding:24px 0 0; min-width:0; border-top:3px solid var(--lb-papier)}
body.page-bleue .groupe legend{
  float:left; width:100%; margin-bottom:18px; padding:0;
  font-family:var(--lb-font-titre); font-size:22px; text-transform:uppercase; color:var(--lb-jaune);
}
body.page-bleue .groupe legend + *{clear:both}
body.page-bleue .etiquette{font-family:var(--titre); font-size:15px; text-transform:uppercase; letter-spacing:.02em}
body.page-bleue .facultatif{font-family:var(--lb-font-texte); font-size:14px; text-transform:none; letter-spacing:0}

/* Mot de passe : le champ, puis Afficher à côté, jamais par-dessus. */
body.page-bleue .mdp-ligne{display:flex; gap:10px; align-items:stretch}
body.page-bleue .mdp-ligne input{flex:1; min-width:0}
body.page-bleue .mdp-voir{flex:none; min-width:104px; min-height:48px}
body.page-bleue .compte .btn--contour:not(.encart *){--fg:var(--lb-papier); box-shadow:0 var(--press) 0 var(--sh), inset 0 0 0 3px var(--lb-papier)}
body.page-bleue .compte .btn--contour:not(.encart *):active{box-shadow:0 0 0 var(--sh), inset 0 0 0 3px var(--lb-papier)}

/* Le bouton principal, sur le bleu : jaune, texte bleu. */
body.page-bleue .compte-envoi{margin-top:26px}
body.page-bleue .compte-envoi .btn{--bg:var(--lb-jaune); --fg:var(--lb-bleu); --sh:var(--lb-rouge)}

/* Mot de passe oublié : un bouton qui a l'air d'un lien, et sa phrase. */
body.page-bleue .oubli{margin-top:-4px}
body.page-bleue .lien-bouton{
  display:inline-flex; align-items:center; min-height:44px; padding:0 2px;
  background:none; border:0; cursor:pointer; color:var(--lb-papier);
  font-weight:700; font-size:15.5px; text-decoration:underline; text-underline-offset:4px;
}
body.page-bleue .oubli-texte{
  margin-top:6px; padding:4px 0 4px 14px; border-left:3px solid var(--lb-jaune);
  color:var(--lb-papier); font-size:15.5px; max-width:52ch;
}

body.page-bleue .compte-bas{
  margin-top:34px; padding-top:20px; border-top:3px solid var(--lb-papier);
  display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:4px 10px;
  color:var(--lb-papier); font-size:17px;
}
body.page-bleue .compte-lien{
  display:inline-flex; align-items:center; min-height:44px; padding:0 4px;
  color:var(--lb-jaune); font-weight:800; text-decoration:underline; text-underline-offset:4px;
}

/* Les neuf couleurs de PALETTE, avec un filet papier pour se détacher
   du bleu quelle que soit la teinte. */
body.page-bleue .pastilles{display:flex; flex-wrap:wrap; gap:10px; margin-top:2px}
body.page-bleue .pastille{
  width:44px; height:44px; border:3px solid var(--lb-papier); border-radius:var(--r-touche);
  cursor:pointer; font-size:19px; line-height:1; box-shadow:0 var(--press) 0 var(--lb-rouge);
}

/* La case des conditions : toute la ligne se touche. */
body.page-bleue .case-ligne{display:flex; align-items:center; gap:12px}
body.page-bleue .case-ligne input{flex:none; width:24px; height:24px; margin:0; accent-color:var(--lb-jaune); cursor:pointer}
body.page-bleue .case-ligne input:focus-visible{outline:3px solid var(--lb-jaune); outline-offset:3px}
body.page-bleue .compte .case-ligne label{
  display:flex; align-items:center; min-height:44px; cursor:pointer;
  font-family:var(--lb-font-texte); font-size:16.5px; font-weight:700; text-transform:none; letter-spacing:0;
}

/* La confirmation : carte papier, encre bleue. */
body.page-bleue .compte-merci{
  --ink:var(--lb-bleu); --ink-soft:var(--lb-bleu-doux); --accent:var(--lb-bleu);
  background:var(--lb-papier); color:var(--lb-bleu);
  border:3px solid var(--lb-jaune); border-radius:var(--lb-radius);
  text-align:center; padding:clamp(28px,5vw,48px) 20px;
}
body.page-bleue .compte-merci[hidden]{display:none}
body.page-bleue .compte-merci h2{font-size:clamp(24px,4vw,34px)}
/* Un seul cri : « Créer ma première fête » plein, « Aller à mon espace »
   à contour (la carte porte aussi .encart : boutons bleus, 10,60). */
body.page-bleue .merci-actions{margin-top:26px; display:flex; flex-wrap:wrap; justify-content:center; gap:12px}
body.page-bleue .case .aide a{display:inline-flex; align-items:center; min-height:44px}

/* ---------- Le panneau de réservation (evenement.html, reservation.js) ----------
   Demandé par le client le 28 septembre 2026 d'après la capture d'un autre
   site : nom, numéro WhatsApp, types de ticket, modes de paiement, puis le
   total et le bouton pour payer. Plein écran sous 640 px, feuille à droite
   au-delà. C'est un papier opaque qui redéfinit ses propres tokens de page :
   il se lit pareil sur le jaune et sur body.page-bleue.
   Contrastes : bleu sur papier 10,60 ; bleu doux sur papier 10,29 ; papier
   sur bleu (tuile choisie) 10,60. Le rouge ne porte aucun texte : ombres
   des boutons et bordure d'un champ en erreur seulement. */
.resa-panneau{
  --paper:var(--lb-papier); --paper-2:var(--lb-papier); --card:var(--lb-papier);
  --ink:var(--lb-bleu); --ink-soft:var(--lb-bleu-doux); --ink-mute:var(--lb-bleu-doux);
  --line:var(--lb-bleu); --line-fort:var(--lb-bleu); --accent:var(--lb-bleu);
  position:fixed; inset:0 0 0 auto; margin:0; padding:0;
  width:min(480px, 100%); height:100%; max-width:none; max-height:none;
  background:var(--lb-papier); color:var(--lb-bleu);
  border:0; border-left:var(--lb-bordure); overflow:hidden;
  font-family:var(--lb-font-texte);
}
.resa-panneau::backdrop{background:color-mix(in srgb, var(--lb-bleu) 55%, transparent)}
/* La page derrière ne défile pas pendant que le panneau est ouvert. */
html.resa-ouvert{overflow:hidden}
.resa-panneau form{display:flex; flex-direction:column; height:100%}

.resa-tete{display:flex; align-items:center; gap:14px; flex:none; padding:14px 20px; border-bottom:var(--lb-bordure)}
.resa-fermer{
  flex:none; display:grid; place-items:center; width:44px; height:44px; padding:0; cursor:pointer;
  background:var(--lb-papier); color:var(--lb-bleu);
  border:3px solid var(--lb-bleu); border-radius:var(--lb-radius);
  box-shadow:0 3px 0 var(--lb-rouge); transition:transform .07s ease, box-shadow .07s ease;
}
.resa-fermer:active{transform:translateY(3px); box-shadow:0 0 0 var(--lb-rouge)}
.resa-fermer .resa-ico{width:20px; height:20px; stroke-width:3}
.resa-titres{min-width:0}
.resa-titre{font-size:24px; line-height:1}
.resa-quoi{
  margin-top:5px; font-family:var(--lb-font-info); font-size:12px; letter-spacing:.08em;
  line-height:1.4; text-transform:uppercase; color:var(--lb-bleu-doux);
}

.resa-corps{flex:1; min-height:0; overflow-y:auto; overscroll-behavior:contain; padding:20px 20px 24px}
.resa-ico{width:22px; height:22px; flex:none}

/* Les champs : un libellé, puis une ligne soulignée de 3 px. */
.resa-champ{margin-bottom:22px}
.resa-champ > label, .resa-groupe legend{
  display:block; padding:0; margin-bottom:6px;
  font-family:var(--lb-font-titre); font-size:14px; text-transform:uppercase; letter-spacing:.02em;
}
.resa-ligne{display:flex; align-items:center; gap:10px; min-height:52px; border-bottom:3px solid var(--lb-bleu)}
.resa-ligne--erreur{border-bottom-color:var(--lb-rouge)}
.resa-ligne input{
  flex:1; min-width:0; padding:12px 2px; border:0; border-radius:3px; background:transparent;
  font:inherit; font-size:17px; font-weight:600; color:var(--lb-bleu);
}
.resa-ligne input::placeholder{color:var(--lb-bleu-doux); opacity:.75; font-weight:500}
.resa-ligne input:focus{outline:none}
/* Le focus épaissit le soulignement, de 3 à 6 px. */
.resa-ligne:focus-within{box-shadow:0 3px 0 var(--lb-bleu)}
.resa-aide{margin-top:7px; font-size:14px; color:var(--lb-bleu-doux)}
.resa-erreur{margin-top:6px; font-size:14px; font-weight:800; color:var(--lb-bleu)}

/* Le pays : drapeau et indicatif montrés, la liste native posée par
   dessus, transparente, pour garder le clavier et le lecteur d'écran. */
.resa-pays{
  position:relative; flex:none; display:flex; align-items:center; gap:6px;
  min-height:44px; padding:0 6px 0 8px;
  border:2px solid var(--lb-bleu); border-radius:var(--lb-radius);
}
.resa-pays:focus-within{outline:3px solid var(--lb-bleu); outline-offset:2px}
.resa-pays select{position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:pointer; font-size:16px}
.resa-pays-drapeau{display:flex}
.resa-drapeau{width:24px; height:16px}
.resa-pays-ind{font-family:var(--lb-font-info); font-size:13px; font-weight:700; letter-spacing:.04em}
.resa-pays .resa-ico{width:16px; height:16px; stroke-width:3}

/* Types de ticket : une carte papier par tarif. */
.resa-groupe{border:0; padding:0; margin:0 0 22px; min-width:0}
.resa-groupe legend{margin-bottom:10px}
.resa-tarif{
  display:grid; grid-template-columns:minmax(0,1fr) auto auto; align-items:center; gap:12px;
  padding:12px 12px 12px 14px; margin-bottom:10px;
  background:var(--lb-papier); border:var(--lb-bordure); border-radius:var(--lb-radius);
}
.resa-tarif-nom{min-width:0}
.resa-tarif-nom b{display:block; font-family:var(--lb-font-titre); font-weight:400; font-size:16px; text-transform:uppercase; line-height:1.1}
.resa-tarif-nom small{display:block; margin-top:3px; font-size:13px; line-height:1.3; color:var(--lb-bleu-doux)}
.resa-tarif-prix{font-family:var(--lb-font-info); font-weight:700; font-size:14px; letter-spacing:.06em; white-space:nowrap}
.resa-tarif .compteur{gap:6px}
.resa-tarif .compteur button{width:44px; height:44px; border-width:2px}
/* La case du nombre, encadrée de bleu, jamais de rouge. */
.resa-tarif .compteur output{
  display:grid; place-items:center; width:40px; height:40px;
  border:3px solid var(--lb-bleu); border-radius:var(--lb-radius); background:var(--lb-papier);
  font-family:var(--lb-font-info); letter-spacing:0;
}

/* Modes de paiement : trois tuiles. Choisie : fond bleu, texte papier. */
.resa-modes{display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:10px}
.resa-mode{position:relative; display:block}
.resa-mode input{position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:pointer}
.resa-mode span{
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:8px; height:100%;
  min-height:92px; padding:12px 6px; text-align:center;
  background:var(--lb-papier); color:var(--lb-bleu);
  border:var(--lb-bordure); border-radius:var(--lb-radius);
  transition:background .12s ease, color .12s ease;
}
.resa-mode .resa-ico{width:30px; height:30px}
.resa-mode b{font-size:14px; font-weight:800; line-height:1.15}
.resa-mode input:checked + span{background:var(--lb-bleu); color:var(--lb-papier)}
.resa-mode input:focus-visible + span{outline:3px solid var(--lb-bleu); outline-offset:3px}
.resa-note{font-size:14px; color:var(--lb-bleu-doux)}
/* Conditions de vente : bleu doux sur papier, lien bleu souligné ;
   le lien s'étire à 40 px de haut sans agrandir la ligne. */
.resa-cgv{font-size:14px; color:var(--lb-bleu-doux)}
.resa-cgv-lien{
  display:inline-flex; align-items:center; min-height:40px; margin-block:-12px;
  color:var(--lb-bleu); font-weight:700; text-decoration:underline; text-underline-offset:3px;
}
.resa-cgv-lien:focus-visible{outline:3px solid var(--lb-bleu); outline-offset:2px}

/* Le pied, collé en bas : le total, puis le bouton sur toute la largeur. */
.resa-pied{
  flex:none; display:grid; gap:12px;
  padding:14px 20px calc(18px + env(safe-area-inset-bottom));
  background:var(--lb-papier); border-top:var(--lb-bordure);
}
.resa-total{display:flex; align-items:baseline; justify-content:space-between; gap:12px; flex-wrap:wrap}
.resa-total-lib{font-size:14px; color:var(--lb-bleu-doux)}
.resa-total-som{font-family:var(--lb-font-info); font-weight:700; font-size:22px; letter-spacing:.04em}
.resa-payer{width:100%; min-height:56px; padding:14px 18px; font-size:17px; white-space:normal; text-align:center}
/* Sur le papier, le bouton à contour garde le fond du panneau. */
.resa-payer.btn--contour{--bg:var(--lb-papier)}

/* Sous 640 px : plein écran, sans bordure latérale. */
@media (max-width:640px){
  .resa-panneau{width:100%; border-left:0}
  .resa-tete{padding:10px 16px}
  .resa-corps{padding:18px 16px 22px}
  .resa-pied{padding:12px 16px calc(14px + env(safe-area-inset-bottom))}
  .resa-payer{font-size:16px}
}
/* Très étroit : le prix passe sous le nom, le compteur garde sa place. */
@media (max-width:400px){
  .resa-tarif{grid-template-columns:minmax(0,1fr) auto; grid-template-areas:"nom compteur" "prix compteur"; row-gap:4px}
  .resa-tarif-nom{grid-area:nom}
  .resa-tarif-prix{grid-area:prix}
  .resa-tarif .compteur{grid-area:compteur}
}
@media (prefers-reduced-motion:reduce){
  .resa-fermer:active{transform:none}
  .resa-mode span{transition:none}
}
/* Sur la page bleue, la feuille se détache du fond par un bord jaune
   (7,08), comme les cartes du programme. Le reste ne change pas. */
.page-bleue .resa-panneau{border-left-color:var(--lb-jaune)}

/* aide.html : « Comment ça marche », au pied de l'accueil, vise #organiser ;
   la marge garde le titre sous l'en-tête collant. */
#organiser,#mot-de-passe{scroll-margin-top:120px}

/* ============================================================
   TOUTES LES PAGES EN BLEU, SAUF L'ACCUEIL
   Demande du client du 28 septembre 2026 : « la page Au programme est
   bleue, j'aimerais que toutes les autres pages soient pareilles, à
   part la première page, Sortir ». body.page-bleue est donc posé sur
   programme.html, evenement.html, organisateur.html, creer.html et
   aide.html, et le sera sur connexion.html et inscription.html.
   index.html reste jaune.

   Le principe est déjà celui du programme : le cadre est bleu, texte
   papier (10,60) ; les surfaces qu'on lit ou qu'on remplit restent en
   papier, texte bleu (10,60), bord jaune pour se détacher du fond
   (jaune sur bleu : 7,08). Chaque surface remet les tokens de page à
   leur valeur claire : tout ce qui s'écrit avec --ink, --ink-soft,
   --line ou --accent se lit donc juste, dedans comme dehors.
   Le rouge ne porte toujours aucun texte (2,60 sur le bleu).
   ============================================================ */

/* --- Les surfaces papier --- */
.page-bleue :is(.encart, .passe, .orga-bloc,
  .barre-achat, .billet-final, .media-vide, .abo-panneau){
  --ink:var(--lb-bleu); --ink-soft:var(--lb-bleu-doux); --ink-mute:var(--lb-bleu-doux);
  --line:var(--lb-bleu); --line-fort:var(--lb-bleu); --accent:var(--lb-bleu);
  color:var(--lb-bleu); border-color:var(--lb-jaune);
}
.page-bleue .orga-bloc--abo:hover{border-color:var(--lb-jaune)}
/* Une surface dans une surface garde le bord bleu : le jaune sur le
   papier (1,50) ne se verrait pas. */
.page-bleue .passe .media-vide{border-color:var(--lb-bleu)}
.page-bleue .abo-panneau{border-color:var(--lb-jaune); box-shadow:6px 6px 0 var(--lb-jaune)}

/* --- Les boutons ---
   Sur le cadre bleu : plein jaune, texte bleu (7,08) ; à contour, bord
   et texte papier (10,60). Dans une surface papier : plein bleu, texte
   papier (10,60) ; à contour, bord et texte bleu (10,60). L'ombre reste
   rouge, elle ne porte rien. */
.page-bleue .btn{--bg:var(--lb-jaune); --fg:var(--lb-bleu); --sh:var(--lb-rouge)}
.page-bleue .btn--contour{
  --bg:transparent; --fg:var(--lb-papier);
  box-shadow:0 var(--press) 0 var(--sh), inset 0 0 0 3px var(--lb-papier);
}
.page-bleue .btn--contour:active{box-shadow:0 0 0 var(--sh), inset 0 0 0 3px var(--lb-papier)}
.page-bleue :is(.encart, .passe, .orga-bloc, .barre-achat, .billet-final,
  .abo-panneau, .resa-panneau, .carte) .btn{--bg:var(--lb-bleu); --fg:var(--lb-papier)}
.page-bleue :is(.encart, .passe, .orga-bloc, .barre-achat, .billet-final,
  .abo-panneau, .resa-panneau, .carte) .btn--contour{
  --bg:transparent; --fg:var(--lb-bleu);
  box-shadow:0 var(--press) 0 var(--sh), inset 0 0 0 3px var(--lb-bleu);
}
.page-bleue :is(.encart, .passe, .orga-bloc, .barre-achat, .billet-final,
  .abo-panneau, .resa-panneau, .carte) .btn--contour:active{box-shadow:0 0 0 var(--sh), inset 0 0 0 3px var(--lb-bleu)}
.page-bleue :is(.encart, .passe, .orga-bloc, .barre-achat, .billet-final,
  .abo-panneau, .resa-panneau, .carte) .btn--ghost{
  --bg:var(--lb-papier); --fg:var(--lb-bleu);
  box-shadow:0 var(--press) 0 var(--sh), inset 0 0 0 3px var(--lb-bleu);
}
.page-bleue :is(.encart, .passe, .orga-bloc, .barre-achat, .billet-final,
  .abo-panneau, .resa-panneau, .carte) .btn--ghost:active{box-shadow:0 0 0 var(--sh), inset 0 0 0 3px var(--lb-bleu)}

/* --- Ce qui était écrit en bleu en dur, et disparaissait sur le bleu --- */
.page-bleue .etape, .page-bleue .eyebrow{border-color:var(--lb-papier)}
.page-bleue .merci .ref{color:var(--lb-jaune)}
.page-bleue .verifie{background:var(--lb-papier); color:var(--lb-bleu)}
.page-bleue .abo-nombre{color:var(--ink-soft)}
.page-bleue .abo-statut{color:var(--ink)}
/* La pastille du quartier : papier, texte bleu (10,60). */
.page-bleue .puce-info--pale{background:var(--lb-papier); color:var(--lb-bleu)}
/* Un contenu déposé : bord jaune sur le cadre (7,08), bleu dans le
   bloc papier d'une soirée passée (10,60). */
.page-bleue .media{border-color:var(--accent)}
/* Dans l'encadré de l'organisateur, le cadre de focus déborderait sur
   le bleu de la page, où il ne se verrait plus : il rentre dans le
   papier. */
.page-bleue .orga-lien:focus-visible{outline-offset:-6px}

/* --- Le lieu : la carte et ses liens --- */
.page-bleue .lieu-carte iframe{border-color:var(--lb-jaune)}
.page-bleue .lieu-nom{color:var(--lb-papier)}
/* La carte prise au clavier : le focus est dans l'iframe, où
   :focus-visible ne se pose pas. Le cadre vient de :focus-within,
   jaune sur le bleu (7,08). */
.page-bleue .lieu-carte:focus-within iframe{outline:3px solid var(--lb-jaune); outline-offset:3px}

/* --- Les champs, fieldsets et légendes ---
   Un champ reste en papier, texte bleu (10,60). Sur le cadre bleu, son
   bord est jaune (7,08) ; dans une surface, bleu (10,60). Le focus est
   un cadre de 3 px à 3 px du champ : jaune sur le bleu, bleu sur le
   papier. En erreur, la bordure est rouge (4,08 contre le papier du
   champ) et le message est en gras : jaune sur le bleu (7,08), bleu
   dans une surface (10,60), jamais rouge. */
.page-bleue .champ input, .page-bleue .champ select, .page-bleue .champ textarea{
  background:var(--lb-papier); color:var(--lb-bleu); border-color:var(--lb-jaune);
}
.page-bleue :is(.encart, .abo-panneau, .barre-achat) .champ :is(input, select, textarea){border-color:var(--lb-bleu)}
/* :focus et non :focus-visible : dans un champ de date ou d'heure, le
   focus est sur l'une de ses cases et :focus-visible ne s'y pose pas. */
.page-bleue .champ :is(input, select, textarea):is(:focus, :focus-within){outline:3px solid var(--accent); outline-offset:3px}
/* Le texte d'exemple : bleu doux atténué, 4,72 sur le papier. */
.page-bleue .champ :is(input, textarea)::placeholder{color:var(--lb-bleu-doux); opacity:.72}
.page-bleue .champ .erreur{color:var(--accent); font-weight:700}
.page-bleue .champ :is(input, select, textarea)[aria-invalid="true"]{border-color:var(--lb-rouge)}
/* Spécificité nulle (:where) : un fieldset qui a son propre style (la
   barre d'achat, le panneau de réservation, les groupes de l'espace
   organisateur) le garde. Seul un fieldset nu prend ce cadre. */
:where(.page-bleue fieldset){border:3px solid var(--line); border-radius:var(--lb-radius)}
:where(.page-bleue legend){color:var(--ink); padding-inline:6px}
/* Cases et boutons radio : jaune sur le cadre, bleu sur le papier. */
:where(.page-bleue input[type="checkbox"], .page-bleue input[type="radio"]){accent-color:var(--accent)}

/* --- La mascotte sur le bleu ---
   La marque la pose sur le jaune ou le papier : son contour bleu se
   perd sur le bleu. Elle prend un liseré papier d'autocollant, comme
   les allumettes du bandeau « bizarrement simple » de l'accueil. La
   tête brûlée de .lb-panneau-sombre, faite pour le bleu, n'en a pas
   besoin. */
.page-bleue .lb-mascotte--hero, .page-bleue .lb-mascotte--merci{
  filter:drop-shadow(3px 0 0 var(--lb-papier)) drop-shadow(-3px 0 0 var(--lb-papier))
         drop-shadow(0 3px 0 var(--lb-papier)) drop-shadow(0 -3px 0 var(--lb-papier));
}

/* ============================================================
   LA COULEUR DE LA FÊTE (evenement.html)
   Demande du client du 28 septembre 2026, d'après DICE : le haut de la
   page d'un événement prend la couleur de la fête et descend en dégradé
   vers le bleu. ÉCART ASSUMÉ à la règle « aplats sans dégradé » de
   brand/BRAND.md, à la demande du client.

   La couleur de la fête est celle de son organisateur, une teinte de
   PALETTE : le script de la page la pose dans --teinte-fete et ajoute
   .page-fete au body. Un événement introuvable n'a ni l'une ni l'autre :
   bleu plein.

   Le haut du dégradé : la teinte à 80 % dans 20 % de bleu, le tout
   assombri de 45 % de noir, en OKLab. Mesuré sur les neuf teintes de
   PALETTE (papier / jaune dessus) :
     9B51E0 → 361C5B  12,88 / 8,60     6B4BFF → 241966  13,49 / 9,00
     C9341B → 481719  13,50 / 9,01     098660 → 01312C  12,89 / 8,61
     097CBC → 032C4D  12,90 / 8,61     D13C79 → 4B1835  12,86 / 8,58
     FFC93C → 594A2A   7,74 / 5,17     7DC242 → 274728   9,35 / 6,24
     A80CBC → 3C084D  14,23 / 9,50
   Le pire cas est la teinte la plus claire, FFC93C : 7,74 pour le
   papier et 5,17 pour le jaune. Avec 40 % de noir, le jaune y tombait
   à 4,39 : ne pas éclaircir. Le bas du dégradé est le bleu (10,60 et
   7,08) ; toute la bande entre les deux reste au-dessus du pire cas.
   Rien ne bouge : aucune animation.
   ============================================================ */
body.page-fete{
  --fete-haut:color-mix(in oklab, color-mix(in oklab, var(--teinte-fete) 80%, var(--lb-bleu)) 55%, #000);
  background-color:var(--lb-bleu);
  background-image:linear-gradient(to bottom, var(--fete-haut) 0, var(--lb-bleu) 100vh);
  background-repeat:no-repeat;
}
/* En haut de page, l'en-tête laisse passer la couleur. Dès qu'on
   descend (.stuck, posé par enTete()), il reprend son fond bleu pour
   que rien ne se lise à travers ; menu ouvert en haut de page, il prend
   la couleur du haut du dégradé, en aplat. */
body.page-fete header:not(.stuck){background:transparent}
body.page-fete header.menu-ouvert:not(.stuck){background:var(--fete-haut)}

/* ---------- creer.html : l'espace organisateur et le formulaire complet ----------
   Demande du client du 28 septembre 2026 : une fois connecté,
   l'organisateur remplit une fiche complète (date, début, fin, à
   propos…). Le formulaire s'allonge, par décision du client, contre le
   point 5 du virage de CLAUDE.md. Il est coupé en blocs (fieldset) pour
   se lire comme une suite de petites cartes. Les champs reprennent
   .champ, .duo, .encart ; ne s'ajoute ici que ce qui manquait. Tout
   passe par les tokens de page (--ink, --line, --card) pour suivre
   aussi bien le fond jaune que body.page-bleue. */
.espace-orga{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:10px 20px;
  padding:12px 16px; margin-bottom:28px;
}
.espace-orga__texte{display:flex; flex-direction:column; gap:3px; min-width:0}
.espace-orga__titre{font-family:var(--lb-font-titre); font-size:13px; text-transform:uppercase; letter-spacing:.04em}
.espace-orga__sortir{
  display:inline-flex; align-items:center; min-height:44px;
  font-weight:700; color:var(--ink); text-decoration-thickness:2px; text-underline-offset:3px;
}

.form-ev__note{margin-top:32px; color:var(--ink-soft); font-size:15px}
.form-ev fieldset{margin:18px 0 0; min-width:0}
/* La légende flotte pour se poser dans la carte, et non sur sa bordure. */
.form-ev legend{
  float:left; width:100%; padding:0; margin-bottom:18px;
  font-family:var(--titre); font-size:clamp(20px,2.6vw,24px); text-transform:uppercase; color:var(--ink);
}
.form-ev legend + *{clear:both}
.form-ev fieldset > :last-child{margin-bottom:0}
.form-ev .duo{align-items:start}
.form-ev__envoi{margin-top:28px}

/* « facultatif », dans le libellé : en texte courant, pas en capitales. */
.champ label .facultatif{
  font-family:var(--lb-font-texte); font-size:13.5px; font-weight:400;
  text-transform:none; letter-spacing:0; color:var(--ink-mute); margin-left:6px;
}

/* Heure de fin : la case « Se termine le lendemain ». */
.champ label.case{
  display:flex; align-items:center; gap:10px; min-height:44px; cursor:pointer;
  font-family:var(--lb-font-texte); font-size:15.5px; font-weight:600;
  text-transform:none; letter-spacing:0;
}
.champ label.case input{
  width:22px; height:22px; margin:0; padding:0; flex:none; border:0;
  accent-color:var(--accent); cursor:pointer;
}
.champ .aide:empty{display:none}

/* Fichier de l'affiche : le bouton natif prend l'allure des boutons. */
.champ input[type="file"]{padding:9px 12px; cursor:pointer}
.champ input[type="file"]::file-selector-button{
  font-family:var(--lb-font-titre); font-size:13px; text-transform:uppercase;
  background:var(--ink); color:var(--card); border:0; border-radius:var(--lb-radius);
  padding:9px 14px; margin-right:12px; cursor:pointer;
}
.affiche-apercu{display:flex; flex-wrap:wrap; align-items:flex-start; gap:14px 18px; margin:6px 0 0}
.affiche-apercu[hidden]{display:none}
.affiche-apercu img{
  width:120px; aspect-ratio:4/5; object-fit:cover;
  border:var(--lb-bordure); border-color:var(--line-fort); border-radius:var(--lb-radius);
}
.affiche-apercu figcaption{display:flex; flex-direction:column; align-items:flex-start; gap:12px; min-width:0; flex:1 1 180px}
.affiche-nom{font-size:14px; overflow-wrap:anywhere}

/* Le quartier : une liste courte en pastilles radio, un seul geste au
   pouce. Le bouton natif couvre sa pastille, invisible : clic, flèches
   et lecteurs d'écran restent ceux d'un vrai groupe radio. Coché, la
   pastille se remplit d'encre. */
.quartiers-choix{display:flex; flex-wrap:wrap; gap:8px}
/* .champ est en grille, ce qui l'emporte sur hidden : on le rétablit
   pour le champ « Autre », fermé tant qu'on ne l'a pas choisi. */
.form-ev .champ[hidden]{display:none}
.champ .choix-quartier{
  position:relative; display:block;
  font-family:var(--lb-font-texte); font-size:15px; text-transform:none; letter-spacing:0;
}
.champ .choix-quartier input{
  position:absolute; inset:0; width:100%; height:100%; margin:0; padding:0; opacity:0; cursor:pointer;
}
.choix-quartier span{
  display:flex; align-items:center; min-height:44px; padding:0 14px;
  border:2px solid var(--line-fort); border-radius:var(--lb-radius);
  background:var(--card); color:var(--ink); font-weight:600;
}
.choix-quartier input:checked + span{background:var(--ink); color:var(--card); border-color:var(--ink)}
.choix-quartier input:focus-visible + span{outline:3px solid var(--ink); outline-offset:2px}
.quartiers-choix[aria-invalid="true"] .choix-quartier span{border-color:var(--lb-rouge)}

/* Le lieu : la carte de vérification, sous le champ, dès qu'il est
   rempli. Hauteur modeste : elle confirme un repère, elle ne guide pas. */
.carte-apercu{margin-top:6px}
.carte-apercu[hidden]{display:none}
.carte-apercu iframe{
  display:block; width:100%; height:200px;
  border:var(--lb-bordure); border-color:var(--line-fort); border-radius:var(--lb-radius);
}
/* Le focus est dans l'iframe, où :focus-visible ne se pose pas. */
.carte-apercu:focus-within iframe{outline:3px solid var(--ink); outline-offset:3px}
.lien-carte{margin-top:6px}
.lien-carte a{
  display:inline-flex; align-items:center; min-height:44px;
  font-weight:700; color:var(--ink); text-decoration-thickness:2px; text-underline-offset:3px;
}

.nb-car{font-variant-numeric:tabular-nums}
.nb-car--ok{font-weight:700}

/* Les trois tarifs du site, calculés sur le prix de base. */
.tarifs-apercu{margin-top:4px}
.tarifs-apercu__titre{font-family:var(--titre); font-size:15px; text-transform:uppercase}
.tarifs-apercu .aide{font-size:13.5px; color:var(--ink-mute); margin-top:4px}
.tarifs-apercu ul{list-style:none; margin:10px 0 0; padding:0}
.tarifs-apercu li{
  display:grid; grid-template-columns:auto 1fr auto; align-items:baseline; gap:4px 14px;
  padding:10px 0; border-top:1px solid var(--line);
}
.tarif-nom{font-weight:700}
.tarif-det{font-size:14px; color:var(--ink-mute)}
.tarif-prix{font-weight:700; text-align:right}

/* Le récapitulatif avant publication. */
.recap h2{font-size:clamp(26px,3.6vw,38px)}
.recap h2:focus, .merci h2:focus{outline:none}
.recap-intro{color:var(--ink-soft); margin:12px 0 22px; max-width:52ch}
.recap-liste{display:grid; grid-template-columns:minmax(120px,170px) 1fr; gap:0; margin:0}
.recap-liste dt, .recap-liste dd{padding:11px 0; border-top:1px solid var(--line); margin:0}
.recap-liste dt:first-of-type, .recap-liste dt:first-of-type + dd{border-top:0; padding-top:0}
.recap-liste dt{font-family:var(--titre); font-size:13px; text-transform:uppercase; padding-right:14px}
.recap-liste dd{min-width:0; overflow-wrap:anywhere}
.recap-texte{white-space:pre-line}
.recap-affiche{
  width:96px; aspect-ratio:4/5; object-fit:cover;
  border:var(--lb-bordure); border-color:var(--line-fort); border-radius:var(--lb-radius);
}
.recap-actions{display:flex; flex-wrap:wrap; gap:14px 16px; margin-top:26px}
.merci-quand{font-weight:700; max-width:46ch; margin:0 auto 12px}

@media (max-width:520px){
  .recap-liste{grid-template-columns:1fr}
  .recap-liste dt{border-top:1px solid var(--line); padding-bottom:2px}
  .recap-liste dd{border-top:0; padding-top:0}
  .recap-actions .btn{flex:1 1 100%}
  .tarifs-apercu li{grid-template-columns:1fr auto}
  .tarif-det{grid-column:1 / -1; grid-row:2}
}

/* Sur fond bleu (body.page-bleue, décision du client du 28 septembre
   2026) : aucune règle en plus. Le bandeau, les blocs du formulaire et
   le récapitulatif sont des .encart, que le thème bleu passe en papier
   à bord jaune ; tout le reste s'écrit avec --ink, --ink-soft, --line,
   --accent et --card, qui suivent le fond où ils sont posés. */

/* ==== Curseur « tête de l'allumette » (demande du client, 29 septembre 2026) ====
   La souris prend la forme de la tête du logo, sur tout le site.
   - 32 x 32 px maximum (au-delà, certains navigateurs ignorent le curseur) ;
     liseré papier + trait bleu encre : lisible sur le jaune comme sur le bleu.
   - Point chaud au bout de la flamme : (16, 2) au repos, (16, 3) sur un
     élément cliquable. Le clic tombe là où la flamme pointe.
   - Repli : SVG, puis PNG, puis le curseur du navigateur (auto, pointer, text).
   - Rien sur les appareils sans souris (tactile) ni sans survol.
   - Les champs de saisie gardent le curseur texte (I) : sinon on ne voit plus
     où l'on tape. Les éléments désactivés gardent leur « interdit » propre.
   Fichiers : assets/curseur/allumette(.svg|.png), allumette-clic(.svg|.png). */
@media (hover: hover) and (pointer: fine) {
  html, body {
    cursor: url("assets/curseur/allumette.svg") 16 2, url("assets/curseur/allumette.png") 16 2, auto;
  }
  /* « html body » relève la spécificité : plusieurs composants posent déjà
     cursor:pointer sur leurs classes, on veut la même tête partout. */
  html body :is(a[href], button, [role="button"], label[for], select, summary,
      input[type="checkbox"], input[type="radio"], input[type="submit"],
      input[type="button"], input[type="file"]):not(:disabled):not([aria-disabled="true"]) {
    cursor: url("assets/curseur/allumette-clic.svg") 16 3, url("assets/curseur/allumette-clic.png") 16 3, pointer;
  }
  html body :is(input:not([type]), input[type="text"], input[type="email"],
      input[type="tel"], input[type="password"], input[type="number"],
      input[type="search"], input[type="url"], textarea,
      [contenteditable]:not([contenteditable="false"])) {
    cursor: text;
  }
  /* Éléments désactivés : la tête au repos (le « interdit » des classes
     .btn[disabled] etc. reste prioritaire grâce à :where). */
  html body :where(button, select, input, textarea):disabled { cursor: url("assets/curseur/allumette.svg") 16 2, url("assets/curseur/allumette.png") 16 2, auto; }
}
