/* jamin.brussels — app mobile (généré par web/app_build.py, ne pas éditer) */
:root{
  --noir:#0D0D0D; --jaune:#FFF100; --blanc:#FFFFFF; --creme:#F4F1E8;
  --l1:rgba(255,255,255,.16); --l2:rgba(255,255,255,.35); --l3:rgba(255,255,255,.25);
  --t2:rgba(255,255,255,.72); --t3:rgba(255,255,255,.45);
  --slab:'Alfa Slab One',Georgia,serif;
  --sans:Inter,system-ui,-apple-system,sans-serif;
  --mono:'JetBrains Mono',ui-monospace,monospace;
  --hachure:repeating-linear-gradient(45deg,var(--jaune) 0 6px,var(--noir) 6px 12px);
  --safe-b:env(safe-area-inset-bottom,0px);
  --tabh:calc(65px + var(--safe-b));
}
*{box-sizing:border-box}
html,body{margin:0;padding:0;background:var(--noir);color:var(--blanc);
  font-family:var(--sans);-webkit-font-smoothing:antialiased;overscroll-behavior-y:none}

/* Chaque écran occupe au moins la hauteur visible : sans ça, un jour à deux
   dates laisse le bouton d'action flotter au milieu de l'écran. */
.screen{display:flex;flex-direction:column}
.screen.tabbed{min-height:100vh;min-height:100dvh;padding-bottom:var(--tabh)}
.screen.detail{min-height:100vh;min-height:100dvh}
.screen.carte{height:100vh;height:100dvh;padding-bottom:var(--tabh);overflow:hidden}
.filler{flex:1}
a{color:inherit;text-decoration:none}
img{display:block}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}
.hachure{height:6px;background:var(--hachure);flex:none}

/* — barre haute — */
/* Le logo grandit, la barre non : les 8 px pris par l'image sont rendus par le
   rembourrage vertical, qui passe de 10 à 6. La barre garde ses 46 px, donc le
   rail reste calé dessous et le contenu ne se décale pas.
   Les marges latérales passent de 16 à 10 pour la même raison : à 34 px de
   haut le logo mesure 192 px de large et venait toucher « MES DATES » dès que
   le compteur de favoris atteignait deux chiffres. */
/* Une gouttière de 10 px entre les colonnes : le logo agrandi venait sinon
   toucher « MES DATES » dès que le compteur de favoris passait à deux
   chiffres — 80 px au lieu de 63, ce qui suffit à combler l'espace. */
.top{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;
  gap:0 10px;
  padding:6px 10px;background:var(--blanc)}
/* `min-width:0` autorise la colonne du logo à se resserrer : sans lui, une
   image ne descend jamais sous sa largeur intrinsèque et déborderait plutôt
   que de céder. */
.top>a:not(.mine){min-width:0;display:flex;justify-content:center}
/* Hauteur définie plutôt que `height:auto` avec un plafond : tant que l'image
   n'est pas chargée, une hauteur automatique vaut zéro, et `majHauteurBarre`
   mesurait alors une barre de 25 px au lieu de 46 — le rail se figeait 21 px
   trop haut et laissait passer une bande de contenu dessous. Les 34 px sont
   donc posés d'emblée ; `max-width` empêche le débordement quand la colonne
   se resserre, et `object-fit` garde les proportions du logo dans la boîte
   au lieu de l'étirer. */
.top img{height:34px;width:auto;max-width:100%;object-fit:contain}
/* `nowrap` : avec un compteur de favoris à deux chiffres, la colonne se
   resserrait assez pour casser « MES DATES » en deux lignes. Le libellé tient
   désormais sa ligne et c'est le logo, lui seul autorisé à se resserrer, qui
   cède les quelques pixels. */
.top .mine{justify-self:end;font:600 10px/1 var(--mono);letter-spacing:.1em;
  color:rgba(13,13,13,.55);display:flex;align-items:center;gap:5px;white-space:nowrap}
.top .mine b{background:var(--noir);color:var(--jaune);padding:2px 4px;font:700 9px/1 var(--mono)}
/* La colonne de droite porte deux choses depuis le 2026-08-25 : les langues et
   « MES DATES ». Elles s'empilent — côte à côte, elles laissaient au logo une
   colonne de 90 px où il se réduisait à un timbre. */
.top .droite{justify-self:end;display:flex;flex-direction:column;align-items:flex-end;gap:4px}
/* Les trois langues, toutes visibles : un menu déroulant aurait caché
   l'existence même des versions anglaise et néerlandaise, et personne ne
   cherche une langue qu'il ne sait pas là. Celle en cours est la seule en
   noir plein — le reste se lit comme des boutons éteints. */
.top .langues{display:flex;gap:2px}
.top .langues button{font:700 9px/1 var(--mono);letter-spacing:.06em;padding:3px 4px;
  border:1px solid rgba(13,13,13,.18);background:transparent;color:rgba(13,13,13,.45);
  cursor:pointer;border-radius:2px}
.top .langues button[aria-pressed=true]{background:var(--noir);color:var(--jaune);
  border-color:var(--noir)}
/* RETOUR et ACCUEIL partagent la colonne de gauche. `min-width:0` la laisse
   céder devant le logo si le compteur de favoris grossit, comme le fait déjà
   la colonne centrale. */
.top .nav{justify-self:start;display:flex;align-items:center;gap:9px;min-width:0}
.top .back{font:600 10px/1 var(--mono);letter-spacing:.1em;
  color:rgba(13,13,13,.55);white-space:nowrap}
/* Cible tactile de 30 px pour une icône de 17 : le pouce ne vise pas le trait. */
.top .home{display:flex;align-items:center;justify-content:center;
  width:30px;height:30px;margin:-6px 0;color:rgba(13,13,13,.55)}
.top .home svg{width:17px;height:17px;fill:none;stroke:currentColor;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.top .home:active{color:var(--noir)}

/* — rail temporel — */
.rail{display:flex;overflow-x:auto;scrollbar-width:none;
  border-top:2px solid var(--blanc);border-bottom:2px solid var(--blanc)}
.rail::-webkit-scrollbar{display:none}
.rail button{flex:none;padding:11px 13px;text-align:left;
  border-right:1px solid var(--l3);background:var(--noir)}
.rail button:last-child{border-right:0}
.rail .s{font:700 8.5px/1 var(--mono);letter-spacing:.1em;color:var(--t3)}
.rail .b{margin-top:6px;font:400 14px/1 var(--slab);color:var(--blanc);white-space:nowrap}
.rail button[aria-selected=true]{background:var(--jaune)}
.rail button[aria-selected=true] .s{color:rgba(13,13,13,.6)}
.rail button[aria-selected=true] .b{color:var(--noir)}
/* Bascule jour/semaine : posée dans le rail mais collée à son bord gauche,
   elle reste sous le pouce quand les onglets défilent. Fond opaque —
   les onglets passent dessous — et bordure jaune pour dire qu'elle commande
   le rail au lieu d'en faire partie. */
.rail .railvue{position:sticky;left:0;z-index:1;background:var(--noir);
  border-right:2px solid var(--jaune)}
.rail .railvue .s{color:var(--jaune)}
.rail .railvue .b{color:var(--jaune)}

/* — hero — */
.hero{position:relative;height:148px;overflow:hidden;flex:none}
.hero .bg{position:absolute;inset:0;background-size:cover;background-position:center;
  filter:grayscale(1) contrast(1.35) brightness(.6)}
.hero .fade{position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(13,13,13,.4) 0%,rgba(13,13,13,.1) 35%,rgba(13,13,13,.98) 100%)}
.hero .lab{position:absolute;left:16px;bottom:16px;display:flex;align-items:flex-end;gap:12px}
.badge{background:var(--jaune);color:var(--noir);font:400 26px/.9 var(--slab);
  padding:5px 9px 8px;transform:rotate(-1.2deg);display:inline-block}
.hero .head{font:400 13px/1.25 var(--slab);max-width:160px;padding-bottom:2px}
.hero .hachure{position:absolute;left:0;right:0;bottom:0}

/* — filtres — */
.filters{display:flex;align-items:center;gap:7px;padding:14px 16px 12px;
  border-bottom:2px solid var(--blanc);
  /* Un pixel de recouvrement : la hauteur du rail tombe sur une demie
     (54,5 px), et la valeur arrondie laissait passer une lame de contenu
     entre les deux barres. Mieux vaut mordre sur son filet blanc. */
  position:sticky;top:calc(var(--h-rail,51px) - 1px);z-index:38;
  background:var(--noir)}
.chip{padding:9px 13px;border:1px solid var(--l2);font:400 14px/1 var(--slab);color:var(--blanc)}
.chip[aria-pressed=true]{background:var(--jaune);border-color:var(--jaune);color:var(--noir)}
.count{margin-left:auto;font:400 10px/1 var(--mono);color:var(--t3)}

/* — listes — */
.wrap{padding:0 16px}
.grouphead{padding:18px 0 6px;display:flex;align-items:baseline;justify-content:space-between;
  border-bottom:1px solid var(--l2)}
.grouphead .t{font:400 16px/1 var(--slab)}
.grouphead .n{font:400 10px/1 var(--mono);color:var(--t3)}
.row{display:flex;gap:12px;padding:15px 0;border-bottom:1px solid var(--l1);
  width:100%;text-align:left;align-items:flex-start}
.row .h{width:66px;flex:none;font:400 18px/1 var(--slab);color:var(--jaune)}
.row .mid{flex:1;min-width:0}
/* Titre en tête, dans la graisse d'affiche et un cran au-dessus de ce que
   portait le nom du lieu (17 px) : c'est lui qu'on cherche en parcourant la
   liste. Casse d'origine et non capitales — un titre est une phrase, parfois
   longue, et les capitales la rendraient illisible sur trois lignes. */
.row .titre{font:400 18.5px/1.15 var(--slab);color:var(--blanc)}
/* Capitales quand la tête de ligne est un nom de lieu — c'est sa forme
   partout ailleurs dans l'app. Un titre ou un nom d'artiste garde sa casse :
   ce sont des phrases et des noms propres, que les capitales abîment. */
.row .titre.caps{text-transform:uppercase}
/* Le « @ » d'une jam articule deux noms sans leur disputer la vedette. */
.row .titre .chez{color:rgba(255,255,255,.45);font-weight:400}
/* La ligne du lieu, sous celle de l'organisateur : même famille, un cran en
   dessous, pour qu'on lise « qui » avant « où ». */
.row .titre.chezlieu{margin-top:2px;font-size:.88em;color:rgba(255,255,255,.82)}
/* Lieu ou festival, dessous : la ligne de contexte. Plus petite, en capitales
   espacées — ce sont des noms propres courts, et cette forme les distingue du
   titre sans lui disputer l'attention. */
.row .souslig{margin-top:5px;font:700 12.5px/1.35 var(--sans);
  letter-spacing:.05em;text-transform:uppercase;color:var(--t2)}
/* Troisième ligne, réservée aux jams : qui reçoit. Casse d'origine — c'est un
   nom de personne ou de groupe — et ton plus discret que les deux lignes
   au-dessus, qu'elle complète sans leur disputer le regard. */
.row .artiste{margin-top:3px;font:400 13.5px/1.35 var(--sans);color:var(--t3)}
.row .artiste + .artiste{margin-top:5px}
.row .adr{margin-top:6px;font:400 10.5px/1.3 var(--mono);color:var(--t3)}
.tag{align-self:flex-start;background:var(--jaune);color:var(--noir);
  font:800 9px/1 var(--sans);letter-spacing:.08em;padding:4px 5px;flex:none}
.tag.pwyw{background:var(--blanc)}
.star{align-self:flex-start;color:var(--jaune);font:400 13px/1 var(--sans)}
.empty{padding:34px 16px;font:400 13px/1.6 var(--sans);color:var(--t3)}
.note{padding:26px 16px 30px;margin:0;font:400 11.5px/1.6 var(--sans);color:var(--t3)}

/* — barre basse — */
.tabs{position:fixed;left:0;right:0;bottom:0;z-index:50;display:flex;gap:8px;
  padding:11px 14px calc(11px + var(--safe-b));background:var(--noir);
  border-top:2px solid var(--blanc)}
.tabs button{flex:1;text-align:center;padding:12px 0;border:1px solid var(--l2);
  font:800 10px/1 var(--mono);letter-spacing:.1em;color:rgba(255,255,255,.75)}
.tabs button[aria-selected=true]{background:var(--blanc);color:var(--noir);border-color:var(--blanc)}
.tabs button.jam{border-color:var(--jaune);color:var(--jaune)}
.tabs button.jam[aria-selected=true]{background:var(--jaune);color:var(--noir)}

/* — carte — */
#map{position:absolute;inset:0;background:var(--noir)}
.mapwrap{position:relative;flex:1;min-height:0}
.search{position:absolute;top:14px;left:16px;right:16px;z-index:500;background:var(--noir);
  border:2px solid var(--blanc);padding:10px 12px;font:600 11px/1.2 var(--sans);
  color:var(--blanc);width:auto}
.search::placeholder{color:var(--t3)}
.leaflet-container{background:var(--noir)}
.leaflet-tile-pane{filter:grayscale(1) contrast(1.15) brightness(.72)}
.leaflet-control-attribution{background:rgba(13,13,13,.75)!important;color:var(--t3)!important;
  font:400 8px/1.4 var(--mono)!important;padding:2px 5px!important}
.leaflet-control-attribution a{color:rgba(255,255,255,.6)!important}
.leaflet-attribution-flag{display:none!important}
.pin .p1{background:var(--blanc);color:var(--noir);padding:5px 7px;
  font:400 13px/1 var(--slab);white-space:nowrap;display:inline-block}
.pin.on .p1{background:var(--jaune)}
.pin .p2{margin-top:4px;font:700 9px/1 var(--mono);color:rgba(255,255,255,.7)}
.pin.on .p2{color:var(--jaune)}
.sheet{border-top:2px solid var(--blanc);background:var(--noir);flex:none;
  max-height:44%;overflow:auto;-webkit-overflow-scrolling:touch}
.sheet .grip{width:34px;height:3px;background:var(--l2);margin:9px auto 6px}
.sheet .sh{padding:4px 16px 10px;display:flex;align-items:baseline;justify-content:space-between}
.sheet .sh .t{font:400 16px/1 var(--slab)}
.sheet .sh .k{font:400 9.5px/1 var(--mono);color:var(--t3)}
.srow{display:flex;gap:12px;padding:13px 16px;border-top:1px solid var(--l1);
  align-items:center;width:100%;text-align:left}
.srow .th{width:52px;height:52px;flex:none;background-size:cover;background-position:center;
  filter:grayscale(1) contrast(1.35) brightness(.85)}
.srow .th.nophoto{background:repeating-linear-gradient(45deg,#2a2a2a 0 5px,#161616 5px 10px)}
.srow .mid{flex:1;min-width:0}
.srow .lieu{font:400 16px/1.05 var(--slab);text-transform:uppercase}
.srow .d{font:400 11.5px/1.3 var(--sans);color:rgba(255,255,255,.65);margin-top:4px}
.srow .h{font:400 17px/1 var(--slab);color:var(--jaune);flex:none}

/* — écrans de détail — */
.dhero{position:relative;flex:none}
.dhero.ev{height:300px}
.dhero.lieu{height:232px}
.dhero .bg{position:absolute;inset:0;background-size:cover;background-position:center;
  background-color:#1a1a1a;filter:grayscale(1) contrast(1.35) brightness(.6)}
.dhero .fade{position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(13,13,13,.55) 0%,rgba(13,13,13,.1) 35%,rgba(13,13,13,.98) 100%)}
.iconbtn{position:absolute;top:14px;left:16px;width:32px;height:32px;border:2px solid var(--blanc);
  font:400 16px/28px var(--sans);text-align:center;z-index:2;background:rgba(13,13,13,.5)}
/* ACCUEIL se range contre RETOUR : 16 de marge + 32 de bouton + 8 d'écart. */
.iconbtn.home{left:56px;display:flex;align-items:center;justify-content:center}
.iconbtn.home svg{width:16px;height:16px;fill:none;stroke:currentColor;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.iconbtn:active{background:var(--jaune);color:var(--noir);border-color:var(--jaune)}
/* Le sélecteur de langue d'une fiche : en face de RETOUR, sur le bandeau
   sombre, donc en blanc sur voile noir plutôt qu'en noir sur blanc. */
.dhero .langues{position:absolute;top:14px;right:16px;z-index:2;display:flex;gap:2px}
.dhero .langues button{font:700 9px/1 var(--mono);letter-spacing:.06em;padding:5px 5px;
  border:1px solid rgba(255,255,255,.35);background:rgba(13,13,13,.5);
  color:rgba(255,255,255,.7);border-radius:2px}
.dhero .langues button[aria-pressed=true]{background:var(--jaune);color:var(--noir);
  border-color:var(--jaune)}
.dhero .cap{position:absolute;left:16px;right:16px;bottom:16px}
.dhero h2{margin:12px 0 0;font:400 27px/1 var(--slab);text-transform:uppercase}
.dhero.lieu h2{font-size:32px;line-height:.95}
.dhero p{margin:8px 0 0;font:400 14px/1.35 var(--sans);color:rgba(255,255,255,.85)}
.dhero .adr{font:400 10.5px/1.3 var(--mono);color:rgba(255,255,255,.6);letter-spacing:.06em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Bandeau d'événement : quatre lignes qui descendent en taille — qui joue, où,
   à quelle adresse, et quand. Le nom du lieu tient le milieu, entre le nom de
   l'artiste et l'adresse (Chaker, 2026-08-15). */
.dhero.ev .cap .ou{margin:7px 0 0;font:400 17px/1.15 var(--slab);
  text-transform:uppercase;color:rgba(255,255,255,.92)}
.dhero.ev .cap .adr{margin-top:4px}
/* « with Untel » : la troisième ligne d'un bandeau de jam. Plus petite que le
   nom du lieu, plus grande que l'adresse — c'est une information, pas un
   titre. Les connecteurs « @ » et « with » se lisent en gris : ils articulent
   la phrase sans peser autant que les noms. */
.dhero.ev .cap .avec{margin:5px 0 0;font:400 14px/1.25 var(--sans);
  color:rgba(255,255,255,.86)}
.dhero.ev .cap .lien{color:rgba(255,255,255,.5)}
.dhero.ev .cap .quand{margin-top:9px;display:inline-block;background:var(--jaune);
  color:var(--noir);font:400 15px/1 var(--slab);text-transform:uppercase;
  padding:5px 8px}
/* Les réseaux de la tête d'affiche, contre son nom. Sur une photo, ils
   réclament leur propre fond : les pastilles sombres de la liste s'y perdent. */
.dhero.ev .cap h2 .mini .m{background:rgba(0,0,0,.55);border-color:rgba(255,255,255,.25)}
/* L'entrée et le type, sur une seule ligne. La bande de trois colonnes faisait
   130 px de haut pour trois mots ; celle-ci en fait moins de quarante. */
/* Trois colonnes plutôt qu'une rangée : les deux extrêmes prennent la même
   largeur, ce qui place la date au MILIEU de la bande et non au milieu de ce
   qui reste. Avec `space-between`, elle glissait vers la gauche dès que
   « ENTRÉE À PRIX LIBRE » s'allongeait (Chaker, 2026-08-16). */
/* Trois colonnes tant que ça tient, deux lignes sinon. Avec le mois et
   l'heure de fin, « MER 26 AOÛT · 20H30 → 23H30 » ne laissait plus la place
   à « ENTRÉE GRATUITE » sur un écran de 390 px : la pastille sortait de
   l'écran, et toute la page se mettait à défiler horizontalement. La date
   garde sa ligne, le type et l'entrée se rangent dessous. */
.cartouche{display:flex;flex-wrap:wrap;justify-content:center;
  gap:7px 9px;align-items:center;padding:10px 14px;
  border-bottom:2px solid var(--blanc)}
/* Pas de réordonnancement : l'ordre reste TYPE · DATE · ENTRÉE, celui qu'ont
   les deux tiers des fiches qui tiennent sur une ligne. Quand ça déborde,
   c'est « ENTRÉE GRATUITE » qui descend — l'information la moins urgente des
   trois, puisque tout l'agenda est gratuit. */
/* La date porte le jaune — c'est elle qu'on cherche en premier ; le type et
   l'entrée se lisent de part et d'autre sans lui disputer l'œil. */
/* `0 1 auto` : la date reste sur la ligne quand tout tient — c'est le cas des
   deux tiers des dates, qui n'ont pas d'heure de fin — et prend la ligne pour
   elle seule quand elle s'allonge. */
.cartouche .qd{flex:0 1 auto;text-align:center;background:var(--jaune);
  color:var(--noir);font:400 15px/1 var(--slab);text-transform:uppercase;
  padding:5px 8px;white-space:nowrap}
.cartouche .ty{font:700 10px/1.25 var(--mono);
  letter-spacing:.12em;color:var(--t3)}
.cartouche .px{white-space:nowrap;
  border:1px solid rgba(255,255,255,.35);font:800 9px/1 var(--sans);
  letter-spacing:.05em;padding:6px 7px;color:rgba(255,255,255,.9)}
/* Le carrousel de la tête d'affiche vit entre le cartouche et la description,
   sans section autour de lui : il reprend donc les marges à son compte, sans
   quoi il touchait le bord de l'écran quand tout le reste est en retrait. */
.screen.detail > .carrwrap{padding:14px 16px 0}
.pill{background:var(--jaune);color:var(--noir);font:800 9px/1 var(--sans);
  letter-spacing:.09em;padding:5px 7px;display:inline-block}
.stats{display:flex;border-bottom:2px solid var(--blanc)}
.stats div{flex:1;padding:13px 11px;border-right:1px solid var(--l3);min-width:0}
.stats div:last-child{border-right:0}
.stats .k{font:700 8.5px/1.3 var(--mono);color:var(--t3);letter-spacing:.1em}
/* Le mot rétrécit, il ne se casse pas. `overflow-wrap:anywhere` coupait
   « CONCERT » en « CONCE / RT » au milieu de la bande, sur tout écran de moins
   de 420 px — c'est-à-dire sur presque tous les téléphones. Une taille fluide
   le fait tenir ; la coupure ne reste que pour les valeurs qui, elles,
   n'auraient vraiment aucune chance. */
.stats .v{margin-top:7px;font:400 clamp(11.5px,3.1vw,16px)/1.15 var(--slab);
  overflow-wrap:break-word;hyphens:none}
.stats .v.j{color:var(--jaune);font-size:clamp(14px,3.9vw,18px)}
.para{padding:16px 16px 0;margin:0}
/* `margin:0` valait quand la description tenait dans un seul paragraphe. Elle
   en compte plusieurs depuis qu'on respecte la mise en page de l'annonce : il
   leur faut de l'air, sinon les lignes se touchent et le pavé revient. */
.para p{margin:0 0 9px;font:400 13.5px/1.65 var(--sans);color:rgba(255,255,255,.8)}
.para p:last-child{margin-bottom:0}
.sec{padding:22px 16px 0}
.sech{border-bottom:2px solid var(--blanc);padding-bottom:6px;
  font:700 10px/1 var(--mono);letter-spacing:.16em}
.kv{display:flex;gap:12px;padding:14px 0;border-bottom:1px solid var(--l1);
  width:100%;text-align:left;align-items:center}
.kv .d{width:66px;flex:none;font:400 18px/1 var(--slab);color:var(--jaune)}
.kv .t{font:400 15px/1.1 var(--slab);text-transform:uppercase}
.kv .s{margin-top:5px;font:400 12.5px/1.35 var(--sans);color:rgba(255,255,255,.7)}
.cta{position:sticky;bottom:0;margin-top:auto;display:flex;gap:8px;
  padding:11px 14px calc(12px + var(--safe-b));
  background:var(--noir);border-top:2px solid var(--blanc)}
.cta button,.cta a{flex:1;text-align:center;padding:14px 0;border:2px solid var(--blanc);
  font:800 10.5px/1 var(--sans);letter-spacing:.08em}
.cta .on{background:var(--blanc);color:var(--noir)}
.cta .prim{background:var(--jaune);border-color:var(--jaune);color:var(--noir)}

/* — jammer — */
.jam h2{margin:0;font:400 26px/1 var(--slab)}
.jam .lede{margin:10px 0 0;font:400 12.5px/1.5 var(--sans);color:rgba(255,255,255,.7)}
.jam .head{padding:16px 16px 14px;border-bottom:2px solid var(--blanc)}
.tagrow{display:flex;flex-wrap:wrap;gap:6px;margin-top:14px}
.tagrow span{padding:10px 12px;border:1px solid var(--l2);font:400 14px/1 var(--slab)}
.box{margin:22px 16px 0;padding:14px;border:2px solid var(--blanc);display:flex;gap:13px;align-items:center}
.box .sq{width:46px;height:46px;flex:none;
  background:repeating-linear-gradient(45deg,var(--jaune) 0 5px,var(--noir) 5px 10px)}
.box .t{font:400 15px/1.15 var(--slab);text-transform:uppercase}
.box .s{font:400 11.5px/1.45 var(--sans);color:rgba(255,255,255,.65);margin-top:5px}
.rules{margin-top:14px;display:flex;flex-direction:column;gap:12px}
.rules div{display:flex;gap:11px}
.rules .n{font:400 15px/1.2 var(--slab);color:var(--jaune);flex:none}
.rules .x{font:400 12.5px/1.45 var(--sans);color:rgba(255,255,255,.8)}
.btnline{display:inline-block;border:2px solid var(--blanc);padding:11px 14px;
  font:800 10.5px/1 var(--sans);letter-spacing:.08em;margin-top:4px}

/* ─────────────────────────────────────────────────────────────────────
   Ajouts postérieurs à la maquette. Ils vivent en FIN de feuille et non
   en tête : à égalité de spécificité, c'est la dernière règle qui gagne,
   et les règles d'origine les écrasaient — `button{background:none}`
   effaçait le fond des vignettes vidéo, `.row .titre` annulait la taille
   du titre.
   ───────────────────────────────────────────────────────────────────── */
/* — navigation dans la galerie —
   Zones de 44 px collees aux bords : au pouce, on vise le bord de l'ecran plus
   surement que le centre d'un petit bouton. */
.zoomwrap .znav{position:absolute;top:50%;transform:translateY(-50%);
  width:46px;height:76px;border:0;border-radius:8px;background:rgba(255,255,255,.10);
  color:#fff;font:300 30px/1 system-ui;cursor:pointer;z-index:2}
.zoomwrap .znav.prev{left:8px}
.zoomwrap .znav.next{right:8px}
.zoomwrap .zcount{position:absolute;bottom:calc(env(safe-area-inset-bottom,0px) + 12px);
  left:50%;transform:translateX(-50%);font:600 12px/1 var(--mono,monospace);
  color:#F2F2F2;background:rgba(0,0,0,.55);padding:6px 11px;border-radius:99px}
.zoomwrap .zbody{display:flex;align-items:center;justify-content:center;
  width:100%;height:100%}
/* — bande de medias sous une ligne de liste —
   Defilement horizontal plutot qu'un retour a la ligne : la ligne garde sa
   hauteur quel que soit le nombre d'images, et l'agenda reste parcourable. */
.bande{display:flex;gap:7px;margin-top:9px;overflow-x:auto;padding-bottom:2px;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.bande::-webkit-scrollbar{display:none}
.bande .mv{width:76px;height:56px;flex:0 0 auto;border-radius:7px;
  object-fit:cover;background:#1A1A1A center/cover no-repeat;
  border:1px solid #2E2E2E;cursor:pointer;padding:0;position:relative}
.bande .mv .play{position:absolute;inset:0;display:flex;align-items:center;
  justify-content:center;font-size:17px;color:#fff;text-shadow:0 2px 6px #000}
.bande .mv:focus-visible{outline:2px solid #FFF100;outline-offset:2px}
/* — vidéos du lieu — */
.vids{display:flex;gap:10px;flex-wrap:wrap;padding:2px 0}
.vids .vid{width:104px;height:104px;border-radius:9px;border:1px solid #2E2E2E;
  background:#1A1A1A center/cover no-repeat;position:relative;cursor:pointer;padding:0}
.vids .vid .play{position:absolute;inset:0;display:flex;align-items:center;
  justify-content:center;font-size:24px;color:#fff;text-shadow:0 2px 8px #000}
.zoomwrap.lecteur .zbody iframe{width:min(100%,760px);height:min(84dvh,860px);
  border:0;border-radius:8px;background:#000}
/* — visionneuse d'affiche —
   L'image tient dans l'ecran (contain) : une affiche est faite pour etre lue
   d'un coup, pas parcourue. `dvh` plutot que `vh` pour ne pas passer sous la
   barre d'adresse mobile. */
.zoomwrap{position:fixed;inset:0;z-index:10000;background:rgba(0,0,0,.94);
  display:flex;align-items:center;justify-content:center;padding:16px;
  animation:zfade .14s ease-out}
@keyframes zfade{from{opacity:0}to{opacity:1}}
.zoomwrap .zbody img{max-width:100%;max-height:88dvh;object-fit:contain;border-radius:6px}
.zoomwrap .zclose{position:absolute;top:calc(env(safe-area-inset-top,0px) + 10px);
  right:12px;width:44px;height:44px;border:0;border-radius:50%;
  background:rgba(255,255,255,.12);color:#fff;font:300 26px/1 system-ui;
  cursor:pointer;z-index:2}
/* Le nom de qui l'on regarde. Il s'arrête avant le bouton de fermeture, et se
   coupe proprement plutôt que de passer à la ligne sur un écran étroit. */
.zoomwrap .ztitre{position:absolute;top:calc(env(safe-area-inset-top,0px) + 10px);
  left:14px;right:66px;z-index:1;color:#fff;
  font:700 13px/1.35 var(--mono);letter-spacing:.08em;text-transform:uppercase;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  text-shadow:0 1px 6px rgba(0,0,0,.9)}
/* — zoom desactive —
   La meta viewport suffit sur Android. Safari iOS l'ignore depuis iOS 10 : le
   double-tap est coupe ici, et le pincement par le gestionnaire gesturestart. */
html{touch-action:manipulation;-webkit-text-size-adjust:100%}
/* — mini-icones dans la liste — */
.mini{display:inline-flex;gap:5px;margin-left:7px;vertical-align:middle}
.mini .m{display:inline-flex;align-items:center;justify-content:center;
  width:22px;height:22px;border-radius:50%;background:#1A1A1A;
  border:1px solid #333;color:#C6C6C6}
.mini .m svg{width:13px;height:13px;fill:currentColor}
/* Plus grandes sur une fiche (22 → 26 px) : on y vient pour suivre l'artiste,
   et à bout de doigt une pastille de 22 px se rate une fois sur trois. La
   liste, elle, garde sa densité — les agrandir y renvoyait les logos à la
   ligne sous chaque nom. */
.screen.detail .mini{gap:7px;margin-left:9px}
.screen.detail .mini .m{width:26px;height:26px}
.screen.detail .mini .m svg{width:15px;height:15px}
/* Le globe et l'appareil photo sont dessinés au trait : leurs silhouettes
   pleines s'empâtaient en une tache à cette taille. */
.mini .m.trait svg{fill:none;stroke:currentColor;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}
.mini .m.web{color:#FFF100}
.mini .m.fb{color:#7EA6FF}
.mini .m.ig{color:#FF8FBF}
/* Mêmes tons désaturés que les trois autres : sur fond noir, les couleurs de
   marque pleines crieraient plus fort que les noms qu'elles accompagnent. */
.mini .m.yt{color:#FF8A8A}
.mini .m.bc{color:#7FD4E8}
/* Repère posé DEVANT un nom : goutte de carte pour un lieu, micro pour qui
   joue. Plus petit et plus sobre que les rangées de réseaux qui suivent le
   nom — il annonce la nature de la ligne, il ne mène pas quelque part (sauf
   la goutte, qui ouvre la carte). */
.pre{display:inline-flex;align-items:center;justify-content:center;
  width:17px;height:17px;margin-right:4px;vertical-align:-3px;color:#7A7A7A}
.pre svg{width:13px;height:13px;fill:currentColor}
a.pre{color:#7FD4E8}
a.pre:hover{color:#B4E9F6}
.pre.mic{color:#C3A6E6}
/* Deux rangées voisines — celle de l'événement puis celle de l'artiste, sur
   une ligne de concert où le titre est le nom de l'artiste. Sans ce trait
   elles se lisent comme une seule, et rien ne dit que les premières mènent à
   la soirée et les suivantes à la personne. */
.mini + .mini{margin-left:9px;padding-left:9px;
  border-left:1px solid rgba(255,255,255,.20)}
/* La mention de prix vit sous l'heure. Elle ne parait que hors gratuit, donc
   toujours pour dire « prix libre » — d'ou une seule couleur. */
.h .px{font:700 8.5px/1.1 var(--mono,monospace);letter-spacing:.04em;
  color:#FF8FBF;margin-top:4px;white-space:nowrap}
/* « SUR INSCRIPTION » ferme la colonne de gauche. En vert plutot qu'en rose :
   ce n'est pas une reserve sur le prix — tout reste gratuit — mais une
   demarche a faire avant de venir.
   Sans empattement et sans coupure : en mono a 8,5 px, « SUR INSCRIPTION » ne
   tenait pas dans les 66 px de la colonne et se brisait en deux, ce qui
   donnait TROIS lignes sur une jam la ou l'on en veut deux. La graisse et la
   couleur suffisent a la faire voir, la taille n'a pas a s'en meler. */
.h .insc{font:700 7.5px/1.35 var(--sans);letter-spacing:0;
  color:#7FD6A5;margin-top:4px;white-space:nowrap}
/* Ce sont les noms qui sont cliquables, plus la ligne entiere : ils portent
   donc l'affordance et le focus visible. */
.row{cursor:pointer}
.row .lk{cursor:pointer;display:inline}
.row .lk:focus-visible{outline:2px solid #FFF100;outline-offset:2px;border-radius:3px}
.row .lk:active{opacity:.65}
/* Souligne discretement ce qui ouvre la fiche de l'evenement, ou que cela
   tombe : premiere ligne pour un concert ou un festival, deuxieme pour une
   jam, dont la tete de ligne est le lieu. Le selecteur vise donc le lien
   lui-meme et non la ligne qui le porte. Taille et graisse restent posees par
   les regles d'origine, plus haut. */
.row .lk[data-ev]{text-decoration:underline;text-decoration-color:#FFF10066;
  text-underline-offset:3px}
/* Un nom de festival n'ouvre rien : il ne prend donc ni soulignement ni
   curseur, pour ne pas promettre un écran qui n'existe pas. */
.row .souslig.fest{color:var(--jaune)}
/* — liens externes (site / Facebook / Instagram) —
   Pastilles de 44 px de haut : c'est le minimum tapable au pouce sans viser. */
.liens{display:flex;gap:12px;flex-wrap:wrap;padding:4px 0 2px}
.liens .lien{display:inline-flex;align-items:center;justify-content:center;
  width:44px;height:44px;border-radius:50%;background:#1A1A1A;
  border:1px solid #2E2E2E;color:#F2F2F2;text-decoration:none}
.liens .lien svg{width:20px;height:20px;fill:currentColor;flex:0 0 auto}
.liens .lien:active{transform:scale(.97)}
.liens .lien.web{color:#FFF100}
.liens .lien.fb{color:#7EA6FF}
.liens .lien.ig{color:#FF8FBF}

/* ══ FICHE LIEU : bandeau, carrousel, réseaux ══════════════════════════════
   Ces règles ferment la feuille : posées plus haut, celles qui suivaient les
   annulaient en silence (à spécificité égale, la dernière gagne). */

/* Bandeau du lieu raccourci : 232 px prenaient le quart d'un écran de
   téléphone avant tout contenu. À 196 px l'image reste ample et le carrousel
   entre dans le premier regard. */
.dhero.lieu{height:196px}

/* Logos superposés au bandeau, en bas à droite — le nom du lieu occupe la
   gauche. Fond sombre translucide : les logos fournis sont blancs sur noir et
   disparaîtraient sur une photo claire. Remontés avec le bandeau. */
.dhero .dlogos{position:absolute;right:12px;bottom:46px;z-index:3;
  display:flex;gap:8px;align-items:flex-end;pointer-events:none}
.dhero .dlogos img{height:52px;width:auto;max-width:84px;object-fit:contain;
  border-radius:8px;background:rgba(0,0,0,.55);padding:5px;
  box-shadow:0 2px 10px rgba(0,0,0,.45)}

/* Carrousel : bande horizontale sous le bandeau, à la place des compteurs.
   Défilement au doigt avec accroche, pas de flèches — sur téléphone le geste
   est plus naturel que deux cibles de 44 px. */
.carrwrap{position:relative}
.carr{display:flex;gap:8px;overflow-x:auto;padding:12px 14px 14px;
  scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
  scrollbar-width:none;
  /* Le doigt garde la main : `pan-x` autorise le glissement horizontal et
     laisse le défilement vertical de la page au navigateur. Sans cette
     déclaration, un glissement en biais pouvait être happé par la page. */
  touch-action:pan-x pan-y}
.carr::-webkit-scrollbar{display:none}

/* Flèches : posées SUR la bande, discrètes, elles signalent surtout qu'il y a
   une suite. Elles s'effacent à l'extrémité atteinte, et disparaissent quand
   il n'y a qu'un seul média. */
.carrnav{position:absolute;top:50%;transform:translateY(-50%);z-index:2;
  width:34px;height:34px;border-radius:50%;border:1px solid #333;
  background:rgba(15,15,15,.82);color:#F2F2F2;font:400 20px/1 system-ui,sans-serif;
  display:flex;align-items:center;justify-content:center;cursor:pointer;
  padding:0;transition:opacity .18s ease}
.carrnav.prev{left:6px}
.carrnav.next{right:6px}
.carrnav[data-bout]{opacity:.22;pointer-events:none}
.carrwrap.seul .carrnav{display:none}
/* Miniatures agrandies : à 148 px on devinait la scène sans la voir. À 208 px
   (format 16/9, comme les vignettes YouTube) deux tiennent encore à l'écran,
   ce qui laisse comprendre qu'on peut faire défiler. */
.carr .cslide{flex:0 0 auto;width:208px;height:117px;border-radius:10px;
  object-fit:cover;background:#141414 center/cover no-repeat;
  border:1px solid #2A2A2A;scroll-snap-align:start;padding:0;cursor:pointer}
.carr .cslide.vid .play{font-size:30px}
.carr .cslide.vid{position:relative;display:flex;align-items:center;
  justify-content:center;color:#fff}
.carr .cslide.vid .play{font-size:22px;line-height:1;
  text-shadow:0 2px 8px rgba(0,0,0,.8);pointer-events:none}
/* Vignette sans image : un dégradé et le nom du réseau, plutôt qu'un carré
   noir qu'on prendrait pour une image qui n'a pas chargé. */
.carr .cslide.vid.nothumb{flex-direction:column;gap:6px;
  background:linear-gradient(145deg,#242424,#141414)}
.carr .cslide.vid .srcl{font:700 10px/1 system-ui,sans-serif;
  letter-spacing:.09em;text-transform:uppercase;color:#BDBDBD;
  pointer-events:none}

/* Réseaux : icône + nombre d'abonnés collé, sous le carrousel.
   Centrés et agrandis — alignés à gauche et en petit, ils passaient pour une
   note de bas de page alors que ce sont les liens qu'on vient chercher. */
.reseaux{display:flex;gap:12px;flex-wrap:wrap;justify-content:center;
  padding:2px 14px 18px}
.reseaux .rs{display:inline-flex;align-items:center;gap:9px;height:48px;
  padding:0 17px;border-radius:24px;background:#1A1A1A;border:1px solid #2E2E2E;
  color:#F2F2F2;text-decoration:none;font:600 14px/1 system-ui,sans-serif}
.reseaux .rs svg{width:24px;height:24px;fill:currentColor;flex:0 0 auto}
.reseaux .rs .ab{color:#CFCFCF;letter-spacing:.02em}
.reseaux .rs:active{transform:scale(.97)}
.reseaux .rs.web{color:#FFF100}
.reseaux .rs.fb{color:#7EA6FF}
.reseaux .rs.ig{color:#FF8FBF}
.reseaux .rs.yt{color:#FF6B6B}

/* Présentation du lieu. Repliée par défaut quand elle dépasse deux
   paragraphes : le dégradé du bas montre qu'il reste à lire, sans couper un
   mot net. */
/* Sans titre au-dessus, les 22 px de `.sec` laissaient un trou : le texte
   remonte juste sous les pastilles de réseaux. */
.secdesc{padding-top:2px}
.lieudesc p{margin:0 0 10px;font:400 13.5px/1.65 system-ui,sans-serif;
  color:#D8D8D8}
.lieudesc p:last-child{margin-bottom:0}
.lieudesc.repliable{position:relative;max-height:132px;overflow:hidden}
.lieudesc.repliable::after{content:'';position:absolute;left:0;right:0;bottom:0;
  height:56px;background:linear-gradient(180deg,rgba(17,17,17,0),#111)}
.lieudesc.repliable.ouvert{max-height:none;overflow:visible}
.lieudesc.repliable.ouvert::after{display:none}
.pluslong{margin-top:10px;padding:9px 15px;border-radius:17px;
  background:transparent;border:1px solid #3A3A3A;color:#FFF100;
  font:700 10.5px/1 system-ui,sans-serif;letter-spacing:.09em;cursor:pointer}
.pluslong:active{transform:scale(.97)}

/* ══ LISTE DU JOUR : bande de médias et code postal ════════════════════════ */

/* La bande sous le titre devient un carrousel. Elle garde la taille de ses
   vignettes — c'est une ligne de liste, pas une fiche — mais défile au doigt
   et porte les mêmes flèches que le carrousel du lieu. */
.bandewrap{position:relative;margin-top:8px}
.bande.carr{display:flex;gap:6px;overflow-x:auto;padding:0;
  scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
  scrollbar-width:none;touch-action:pan-x pan-y}
.bande.carr::-webkit-scrollbar{display:none}
.bande.carr .mv{flex:0 0 auto;scroll-snap-align:start}
/* Flèches réduites : la bande est deux fois moins haute que le carrousel de
   la fiche lieu, des ronds de 34 px la masqueraient. */
.bandewrap .carrnav{width:26px;height:26px;font-size:16px}
.bandewrap .carrnav.prev{left:2px}
.bandewrap .carrnav.next{right:2px}

/* Code postal sous l'heure, dans la même colonne étroite. */
.row .h .cp{margin-top:3px;font:600 10.5px/1 var(--mono);
  color:rgba(255,255,255,.55);letter-spacing:.06em}

/* ══ FICHE LIEU · PROCHAINES DATES ═════════════════════════════════════════
   Trois colonnes : date à gauche, ce qui se joue au milieu, affiche à droite.
   La ligne s'aligne en haut — avec trois lignes de part et d'autre, un
   centrage ferait flotter la date au milieu d'un titre sur deux lignes. */
.kv{align-items:flex-start}
.kv .d{width:58px;display:flex;flex-direction:column;line-height:1.15}
.kv .d b{font:400 15px/1.1 var(--slab);font-weight:400}
.kv .d i{font-style:normal;font:600 10px/1.3 var(--mono);letter-spacing:.04em;
  color:rgba(255,241,0,.62);font-variant-numeric:tabular-nums}
/* Artiste prévu : deuxième voix de la ligne, sous le titre. */
.kv .a{margin-top:3px;font:400 13px/1.2 var(--slab);color:rgba(255,255,255,.92)}
.kv .s{margin-top:4px;text-transform:uppercase;letter-spacing:.1em;
  font:600 10px/1.3 var(--mono);color:rgba(255,255,255,.55)}
/* Affiche de l'événement, à l'extrême droite. */
.kv .kvthumb{flex:none;width:62px;height:62px;object-fit:cover;border-radius:2px;
  border:1px solid rgba(255,255,255,.22);background:var(--l1)}

/* ══ HORAIRES D'OUVERTURE ══════════════════════════════════════════════════
   Juste sous la description. Pas de titre : deux colonnes alignées se lisent
   d'elles-mêmes, et un intitulé de plus alourdirait une fiche déjà dense. */
.sechor{padding-top:14px}
.hor{display:flex;flex-direction:column;gap:5px;
  border-left:2px solid rgba(255,241,0,.5);padding-left:11px}
.horl{display:flex;gap:10px;align-items:baseline}
.horl .j{flex:0 0 92px;font:600 10.5px/1.35 var(--mono);letter-spacing:.07em;
  text-transform:uppercase;color:rgba(255,255,255,.62)}
.horl .v{font:400 13px/1.35 var(--sans);color:var(--blanc);
  font-variant-numeric:tabular-nums}
.horl.off .v{color:rgba(255,255,255,.42);font-style:italic}

/* Vidéo qui s'ouvre hors de l'app (plateforme refusant l'intégration). */
.mv.vid .ext{position:absolute;right:4px;bottom:4px;font:600 11px/1 var(--mono);
  color:rgba(255,255,255,.85);text-shadow:0 1px 3px rgba(0,0,0,.8)}
/* Vidéo sans aperçu : hachures et nom de la plateforme, plutôt qu'un carré
   noir qu'on prend pour une image qui n'a pas fini de charger. Facebook ne
   publie plus l'image de partage de ses vidéos, et ses anciennes adresses
   signées ont expiré — la tuile dit ce qu'elle est, et le lecteur s'ouvre
   quand même. */
.mv.vid.nothumb{background-image:repeating-linear-gradient(135deg,
  #171717 0 8px,#1F1F1F 8px 16px)}
.mv.vid.nothumb .plat{position:absolute;left:0;right:0;bottom:6px;text-align:center;
  font:700 8px/1.2 var(--mono);letter-spacing:.1em;color:#7E7E7E}

/* ══ CE QUI RESTE VISIBLE AU DÉFILEMENT ════════════════════════════════════
   Le rail des dates et les filtres, dans cet ordre, collés en haut (Chaker,
   2026-08-26). C'était auparavant le logo et le rail : le logo ne sert à rien
   pendant qu'on parcourt une liste — on sait sur quel site on est —, alors
   que le filtre JAM/CONCERT/FESTIVAL, lui, se décidait en haut de page et
   obligeait à tout remonter pour changer d'avis.

   Les filtres se collent SOUS le rail : `--h-rail` est mesurée au rendu (voir
   `majHauteurBarre`), le rail changeant de hauteur avec la langue et les
   réglages du téléphone. La valeur de repli couvre le cas où le script n'a
   pas encore tourné.

   Le fond opaque est indispensable des deux côtés : sans lui, les lignes qui
   défilent se liraient au travers. */
.rail{position:sticky;top:0;z-index:39;background:var(--noir)}

/* Jam ou concert, sous l'heure et le code postal. Une pastille plutôt qu'un
   mot nu : la colonne mêle déjà trois informations de nature différente, un
   cadre léger évite qu'elles se lisent comme une seule ligne. */
.row .h .ty{margin-top:5px;display:inline-block;padding:2px 5px;border-radius:2px;
  font:700 9px/1.25 var(--mono);letter-spacing:.1em;
  border:1px solid rgba(255,241,0,.45);color:rgba(255,241,0,.85)}
.row .h .ty.concert{border-color:rgba(255,255,255,.32);
  color:rgba(255,255,255,.72)}
