/* =========================================================
   Chợ Vỉa Hè — Home V2 « carnet kraft »
   Refonte 07.2026 (retours cliente) : fond kraft de la carte imprimée,
   marqueurs littéraux retirés (pg. 0X, traits crayon, annotation),
   histoire fusionnée, composition à rail unique + diptyques alternés,
   pied de page jaune.
   État de repos SANS JS = tout visible (progressive enhancement).
   ========================================================= */

/* ---------- TOKENS (source unique — voir DESIGN.md) ---------- */
:root {
  /* Papier & encre (70%) — kraft échantillonné sur la carte imprimée de
     la cliente. Contrastes mesurés sur --papier :
     encre 12.6:1 · encre-doux 7.3:1 · framboise 4.3:1 (GROS TEXTE UNIQUEMENT)
     · framboise-fonce 5.3:1 · bleu 4.25:1 (gros texte / filets) · bleu-fonce 6.0:1 */
  /* Échantillonné dans le PDF de la carte rentrée 26 (page intérieure) :
     #F1E3C9 est la couleur de fond dominante du carnet imprimé.
     Extraction de la matière : node tools/texture-carnet.mjs */
  --papier: #F1E3C9;
  --papier-ombre: #E6D4B2;
  --encre: #1E1A17;
  --encre-doux: #4a423a;

  /* Encres illustration (25%) */
  --framboise: #C0264B;        /* titres, gros texte ≥24px (ou ≥18.7px gras) */
  --framboise-fonce: #A81F3F;  /* corps de texte, liens, petits labels */
  --orange: #E9531F;
  --bleu: #1E6E8C;             /* filets, focus, gros texte */
  --bleu-fonce: #17566E;       /* labels, légendes, petits textes */
  --vert: #2E7D32;

  /* Éclats du lieu (5%) */
  --jaune: #F2B300;            /* encre sur jaune = 9.0:1 — JAMAIS de blanc */
  --rouge-neon: #E4002B;

  /* --ligne-carnet supprimé : le carnet de référence n'a pas de réglure. */

  /* Type */
  --f-titre: 'Lora', Georgia, serif;
  --f-corps: 'Be Vietnam Pro', system-ui, sans-serif;
  --f-hand: 'Dancing Script', 'Segoe Script', cursive;

  /* Espacements fluides — rapport 5:1 section/paragraphe (80px / 16px) */
  --pad-x: clamp(1.15rem, 5vw, 4rem);
  --sec-y: clamp(3rem, 6vw, 5rem);   /* 48px mobile → 80px desktop */
  --measure: 66ch;                    /* plafond de lisibilité FR (62-68 car.) */

  /* Conteneurs */
  --wrap-max: 1080px;    /* colonne courante */
  --wrap-prose: 940px;   /* texte long : 78% de son contenu ≈ 66ch */
  --wrap-wide: 1240px;   /* diptyques : images plus grandes */

  /* Ease + durées motion (tweakables) */
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --rev-dur: 0.7s;

  /* Échelles nommées (une valeur par rôle, pas d'ad-hoc) */
  --r-card: 14px;
  --r-photo: 14px;
  --r-ui: 10px;
  --sh-card: 0 8px 20px rgba(30,26,23,0.10);
  --sh-photo: 0 12px 28px rgba(30,26,23,0.22);

  --header-h: 3.6rem;
}

/* ---------- RESET ---------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  /* PAS de scroll-behavior: smooth. Lenis l'interdit : il repositionne le scroll
     image par image, et le navigateur ré-animait CHAQUE repositionnement —
     deux lissages empilés, ~2 s de retard à la molette sous Chrome (Firefox
     beaucoup moins). Les ancres restent douces : c'est home.js qui les anime. */
  scroll-padding-top: calc(var(--header-h) + 0.5rem);
}
body {
  margin: 0;
  font-family: var(--f-corps);
  font-weight: 400;
  color: var(--encre);
  background: var(--papier);
  line-height: 1.65;
  font-size: clamp(1rem, 0.95rem + 0.35vw, 1.12rem);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}
img, picture, svg { display: block; max-width: 100%; }
img { height: auto; }
h1, h2, h3 { line-height: 1.08; margin: 0 0 0.5em; text-wrap: balance; }
p { margin: 0 0 1rem; }              /* 16px — base du rapport 5:1 */
a { color: var(--framboise-fonce); } /* 5.3:1 sur kraft */
ul, ol { margin: 0; }

/* ---------- MATIÈRE DU PAPIER — deux couches ----------
   Le papier ancien se lit à deux échelles. La première version n'en avait
   qu'une, la plus fine, et le fond ressortait comme un aplat beige.

   body::before — L'ÉCHELLE DE LA PAGE. Les taches, l'usure, les variations
     larges du carnet de la cliente. Une seule image, jamais répétée, en
     `cover` : c'est ce qui fait « vieux papier » plutôt que « fond beige ».
     Une tuile ne peut pas porter ça — des taches qui se répètent tous les
     700px se voient immédiatement.
   body::after — L'ÉCHELLE DE LA FIBRE. Le grain, vu de près. Là une tuile
     convient : le grain n'a pas d'accident unique à trahir.

   Les deux images sont grises et centrées sur 128 ; en `overlay`, un pixel à
   128 ne change rien, au-dessus éclaircit, en dessous assombrit. Jamais
   `multiply`, qui assombrirait toute la page.
   Les deux couches sont fixées et en z-index 0 : elles n'atteignent que le
   papier, pas les photos ni le pied de page jaune, opaques et au-dessus.
   Régénération : node tools/texture-carnet.mjs */
body::before,
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
/* La page, EN COULEUR et sans mode de fusion. Voir le commentaire ci-dessus :
   `overlay` divisait la modulation par dix sur un fond clair. --papier reste
   la couleur de repli tant que l'image n'est pas chargée. */
body::before {
  background-image: url('./assets/papier-fond.webp');
  background-size: cover;
  background-position: center top;
  background-repeat: no-repeat;
}
/* Le grain, en `multiply` : sur un fond clair il conserve son amplitude,
   contrairement à `overlay`. Discret, c'est la couche du dessous qui porte
   le caractère. */
body::after {
  opacity: 1;
  background-image: url('./assets/papier-tile.webp');
  background-repeat: repeat;
  background-size: 620px auto;
  mix-blend-mode: multiply;
}

/* PLUS DE LIGNES RÉGLÉES.
   Le carnet de référence de la cliente (Fond Carte CHO.png) est du papier
   vieilli SANS aucune réglure : c'est la trame de lignes qui donnait au site
   un air de cahier d'écolier au lieu d'un carnet de voyage. La matière vient
   désormais uniquement du grain de papier (body::after), extrait de ce même
   carnet par tools/texture-carnet.mjs. */
.section, .couverture {
  position: relative;
  z-index: 1;
}

/* ---------- CONTENEURS ---------- */
.wrap {
  width: 100%;
  max-width: var(--wrap-max);
  margin-inline: auto;
  padding-inline: var(--pad-x);
  position: relative;
  z-index: 2;
}
.wrap--prose { max-width: var(--wrap-prose); }
.wrap--wide  { max-width: var(--wrap-wide); }
.section { padding-block: var(--sec-y); position: relative; overflow: hidden; }

/* RAIL UNIQUE : titres, textes et boutons démarrent tous au même x.
   Colonne de texte à 78% du conteneur, plafonnée à 66 caractères →
   la gouttière droite (~22%) accueille les illustrations d'Oriane. */
.rail { width: min(78%, var(--measure)); max-width: 100%; }

/* alias d'ancre : docs/carte/ pointe encore vers ../#genese */
.anchor-alias { display: block; height: 0; }

/* ---------- ACCÈS ---------- */
.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--encre);
  color: var(--papier);
  padding: 0.6rem 1rem;
  z-index: 2000;
  border-radius: 0 0 8px 0;
}
.skip-link:focus { left: 0; }
:focus-visible {
  outline: 3px solid var(--bleu);
  outline-offset: 3px;
  border-radius: 3px;
}
/* sur fond jaune (CTA, pied de page), le bleu tombe à ~3:1 → encre */
/* le temps que le module de réservation se charge (voir home.js) */
.btn-cta.is-loading { opacity: 0.72; cursor: progress; }
.btn-cta:focus-visible,
.sticky-btn--book:focus-visible,
.footer :focus-visible { outline-color: var(--encre); }
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}

/* ---------- HELPERS TYPO ---------- */
.handwritten { font-family: var(--f-hand); font-weight: 600; }
.viet { font-family: var(--f-titre); }

h2 {
  font-family: var(--f-titre);
  font-weight: 600;
  color: var(--framboise);
  /* plafond 2,5rem : mesuré, h2 (48px) et titre du lieu (54px) lisaient au
     rang du H1 (56px). Le H1 garde 3,5rem — au-delà, « vietnamienne » ne
     tient plus dans sa colonne. */
  font-size: clamp(1.8rem, 1.2rem + 2.6vw, 2.5rem);
  letter-spacing: -0.01em;
}
h3 {
  font-family: var(--f-titre);
  font-weight: 600;
  color: var(--encre);
  font-size: clamp(1.15rem, 1rem + 0.9vw, 1.5rem);
}
.section-intro { color: var(--encre-doux); }

/* =========================================================
   PARAGRAPHES JUSTIFIÉS (demande cliente)
   La justification sans césure creuse des « rivières » de blanc dès que
   la colonne est étroite : `hyphens: auto` (le <html lang="fr"> fournit
   le dictionnaire de coupure) et une limite de crénage évitent ça.
   On ne justifie QUE le texte courant — jamais les légendes, les prix,
   les titres ou les lignes manuscrites, qui restent alignés à gauche.
   ========================================================= */
.prose p,
.section-intro,
.lede,
.lieu-intro,
.reserver-lead,
.lexique p,
.info-block p,
.ml-page p {
  text-align: justify;
  text-align-last: left;   /* la dernière ligne ne s'étire pas */
  hyphens: auto;
  -webkit-hyphens: auto;
  hyphenate-limit-chars: 6 3 3;
}

/* Sous ~380px la colonne est trop étroite pour que la justification
   tienne : on revient au fer à gauche plutôt que d'afficher des trous. */
@media (max-width: 339px) {
  .prose p, .section-intro, .lede, .lieu-intro, .reserver-lead,
  .lexique p, .info-block p, .ml-page p { text-align: left; }
}

/* Ouverture manuscrite des longs blocs : 2-3 lignes courtes, une par
   paragraphe — texture dans le texte sans changer la mise en page. */
.lede {
  margin: 0 0 1.6rem;
  font-family: var(--f-hand);
  font-weight: 600;
  color: var(--bleu-fonce);
  font-size: clamp(1.5rem, 1.05rem + 2vw, 2.35rem);
  line-height: 1.18;
}
.lede p { margin: 0; }
.lede p + p { margin-top: 0.1em; }

/* =========================================================
   BOUTONS / LIENS
   ========================================================= */
.btn-cta {
  display: inline-block;
  background: var(--jaune);
  color: var(--encre);          /* encre sur jaune (9.0:1), jamais blanc */
  text-decoration: none;
  font-family: var(--f-corps);
  font-weight: 600;
  padding: 0.85rem 1.6rem;
  border-radius: 999px;
  position: relative;
  box-shadow: 0 6px 0 color-mix(in srgb, var(--jaune) 60%, #000 15%);
  transition: transform 0.25s var(--ease-out), box-shadow 0.25s var(--ease-out), filter 0.25s var(--ease-out);
}
.btn-cta::before {
  content: "";
  position: absolute;
  inset: -18px;
  z-index: -1;
  border-radius: inherit;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--jaune) 70%, transparent), transparent 75%);
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 0.4s var(--ease-out), transform 0.4s var(--ease-out);
}
.btn-cta:hover, .btn-cta:focus-visible {
  transform: translateY(-3px);
  box-shadow: 0 9px 0 color-mix(in srgb, var(--jaune) 60%, #000 18%);
  filter: saturate(1.1);
}
.btn-cta:hover::before, .btn-cta:focus-visible::before { opacity: 1; transform: scale(1); }
.btn-cta:active { transform: translateY(0); box-shadow: 0 3px 0 color-mix(in srgb, var(--jaune) 60%, #000 18%); }
.btn-cta--sm {
  padding: 0.5rem 1rem;
  font-size: 0.9rem;
  box-shadow: 0 4px 0 color-mix(in srgb, var(--jaune) 60%, #000 15%);
  min-height: 44px;             /* cible tactile partout */
  display: inline-flex;
  align-items: center;
}
/* PIÈGE FOND JAUNE : le CTA jaune disparaît sur le pied de page jaune.
   Variante encre (papier sur encre = 12.6:1). */
.btn-cta--ink {
  background: var(--encre);
  color: var(--papier);
  box-shadow: 0 6px 0 rgba(30,26,23,0.35);
}
.btn-cta--ink::before { background: radial-gradient(closest-side, rgba(30,26,23,0.30), transparent 75%); }
.btn-cta--ink:hover, .btn-cta--ink:focus-visible { box-shadow: 0 9px 0 rgba(30,26,23,0.4); filter: none; }
.btn-cta--ink:active { box-shadow: 0 3px 0 rgba(30,26,23,0.4); }

/* Lien secondaire "encre" — souligné qui se dessine + tache aquarelle.
   [data-ink] reçoit exactement le même traitement : la navigation, les liens
   du pied de page et « Télécharger la carte illustrée » partagent donc la
   même animation de barre. */
.ink-link,
[data-ink] {
  position: relative;
  color: var(--encre);
  text-decoration: none;
  font-weight: 500;
  padding: 0.05rem 0.15rem;
}
.ink-link::after,
[data-ink]:not(.btn-cta)::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -2px;
  height: 2px;
  background: var(--framboise);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.4s var(--ease-out);
}
.ink-link::before,
[data-ink]:not(.btn-cta)::before {
  content: "";
  position: absolute;
  inset: -6px -8px;
  z-index: -1;
  border-radius: 12px;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--framboise) 22%, transparent), transparent 78%);
  opacity: 0;
  transform: scale(0.5);
  transition: opacity 0.4s var(--ease-out), transform 0.4s var(--ease-out);
}
.ink-link:hover::after, .ink-link:focus-visible::after,
[data-ink]:not(.btn-cta):hover::after,
[data-ink]:not(.btn-cta):focus-visible::after { transform: scaleX(1); }
.ink-link:hover::before, .ink-link:focus-visible::before,
[data-ink]:not(.btn-cta):hover::before,
[data-ink]:not(.btn-cta):focus-visible::before { opacity: 1; transform: scale(1); }

/* =========================================================
   HEADER FIXE
   ========================================================= */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 1000;
  min-height: var(--header-h);
  display: flex;
  align-items: center;
  background: color-mix(in srgb, var(--papier) 82%, transparent);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid rgba(30,26,23,0.10);
  /* le bandeau doit être peint tout de suite, pas après le reste */
  will-change: transform;
  transform: translateZ(0);
}
.site-header .wrap {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding-block: 0.5rem;
  max-width: var(--wrap-wide);
}
.wordmark {
  font-family: var(--f-titre);
  font-weight: 600;
  color: var(--framboise);
  font-size: clamp(1.15rem, 1rem + 1vw, 1.5rem);
  text-decoration: none;
  line-height: 1;
  white-space: nowrap;
  display: inline-flex; align-items: center; min-height: 44px;   /* cible tactile */
}
/* Logo officiel (tools/logo-svg.py, depuis le .ai de la cliente) */
.wordmark img { display: block; height: clamp(22px, 18px + 1vw, 30px); width: auto; }
.footer-wordmark img { display: block; height: clamp(56px, 44px + 3vw, 84px); width: auto; }
.main-nav { margin-left: auto; }
.main-nav ul {
  list-style: none;
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 2vw, 1.6rem);
  padding: 0;
}
.main-nav a {
  color: var(--encre);
  text-decoration: none;
  font-weight: 500;
  font-size: 0.98rem;
}
/* Un seul « Réserver » jaune à la fois : celui de l'en-tête disparaît tant
   que celui du héros est visible (règle DESIGN.md, tous écrans). */
.hero-cta-visible .header-cta { opacity: 0; pointer-events: none; transition: opacity 0.25s var(--ease-out); }
.header-cta {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-block: 0.55rem;
}

/* burger — masqué desktop */
.burger {
  margin-left: 0;
  display: none;
  width: 2.75rem; height: 2.75rem;
  padding: 0;
  border: 1px solid rgba(30,26,23,0.18);
  border-radius: 10px;
  background: rgba(255,255,255,0.32);
  color: var(--encre);
  cursor: pointer;
}
.burger span, .burger span::before, .burger span::after {
  content: "";
  display: block;
  width: 20px; height: 2px;
  background: var(--encre);
  margin: 0 auto;
  position: relative;
  transition: transform 0.25s var(--ease-out), opacity 0.2s;
}
.burger span::before { position: absolute; top: -6px; left: 0; }
.burger span::after  { position: absolute; top: 6px;  left: 0; }

/* overlay menu plein écran */
.nav-overlay {
  position: fixed;
  inset: 0;
  z-index: 1500;
  background: var(--papier);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: var(--pad-x);
  transform: translateY(-100%);
  transition: transform 0.4s var(--ease-out);
  overflow-y: auto;                 /* en paysage mobile (360px de haut) le
  -webkit-overflow-scrolling: touch;   bouton Réserver passait sous le bord */
}
@media (max-height: 460px) { .nav-overlay { justify-content: flex-start; } }
.nav-overlay[hidden] { display: none; }
.nav-overlay.is-open { transform: translateY(0); }
.nav-overlay ul { list-style: none; padding: 0; }
.nav-overlay li { margin: 0.35rem 0; }
.nav-overlay a {
  font-family: var(--f-titre);
  font-weight: 600;
  color: var(--encre);
  text-decoration: none;
  font-size: clamp(1.9rem, 8vw, 2.8rem);
}
.nav-overlay .btn-cta { margin-top: 1rem; font-size: 1.2rem; }
.overlay-close {
  position: absolute;
  top: 1rem; right: 1rem;
  width: 3rem; height: 3rem;
  border: 1px solid rgba(30,26,23,0.2);
  border-radius: 12px;
  background: rgba(255,255,255,0.4);
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
  color: var(--encre);
}

/* =========================================================
   COUVERTURE (hero) — l'illustration du stand EST l'image du site
   ========================================================= */
.couverture {
  position: relative;
  z-index: 1;
  padding: calc(var(--header-h) * 2 + 0.75rem + clamp(2rem, 6vw, 4rem)) 0 var(--sec-y);
  overflow: hidden;
  border-bottom: 1px dashed rgba(30,26,23,0.18);
}
.lanternes-pendantes {
  position: absolute;
  top: calc(var(--header-h) - 2px);
  right: max(0.5rem, calc(50% - 880px));
  width: clamp(88px, 22vw, 176px);
  z-index: 3;
  transform-origin: top center;
  animation:
    lantern-entrance 2.8s cubic-bezier(0.34, 0.06, 0.36, 0.96) both,
    sway 6s var(--ease-out) 2.8s infinite alternate;
  filter: drop-shadow(0 8px 18px rgba(192,38,75,0.18));
  pointer-events: none;
}
.lanternes-pendantes img { width: 100%; }
@keyframes sway { from { transform: rotate(-2.5deg); } to { transform: rotate(2.5deg); } }
@keyframes lantern-entrance {
  0%   { transform: rotate(0deg); }
  22%  { transform: rotate(7deg); }
  48%  { transform: rotate(-5.5deg); }
  72%  { transform: rotate(4deg); }
  100% { transform: rotate(-2.5deg); }
}

.guirlande-top {
  position: absolute;
  top: calc(var(--header-h) - 2px);
  left: max(0px, calc(50% - 880px));
  width: min(46vw, 380px);
  opacity: 0.9;
  z-index: 1;
  pointer-events: none;
}

.couverture .wrap { position: relative; z-index: 2; }
.cover-title {
  font-family: var(--f-titre);
  font-weight: 600;
  color: var(--framboise);
  font-size: clamp(2.1rem, 1.1rem + 4.6vw, 3.5rem);
  line-height: 1.06;
  margin: 0 0 1.4rem;
  max-width: 15ch;
}
/* « vietnamienne » est plus long que la colonne sur les tout petits écrans :
   on n'autorise la coupure en plein mot QUE là, sinon le titre se casse en
   « vietnami- / enne » dès qu'une fenêtre de bureau est réduite. */
@media (max-width: 400px) {
  .cover-title { overflow-wrap: break-word; }
}
.cover-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.4rem;
  margin: 0;
}
.cover-scroll {
  font-family: var(--f-hand);
  color: var(--encre-doux);
  font-size: 1.3rem;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

/* le stand : plein cadre confortable sur mobile (déborde jusqu'aux bords) */
.cover-stand {
  margin: clamp(1.5rem, 5vw, 2.5rem) calc(var(--pad-x) * -1) 0;
}
.cover-stand img {
  width: 100%;
  height: auto;
  filter: drop-shadow(0 14px 22px rgba(30,26,23,0.14));
}
.cover-stand figcaption {
  margin-top: 0.6rem;
  padding-inline: var(--pad-x);
  font-family: var(--f-hand);
  font-size: clamp(1.15rem, 3vw, 1.5rem);
  color: var(--bleu-fonce);
}

/* Desktop : texte au rail gauche, stand géant qui file vers le bord droit.
   Le seuil est 781px — le MÊME que celui du menu (burger en dessous).
   Avant, le héros basculait à 1000px et la barre de navigation à 780px :
   entre les deux on obtenait un menu de bureau posé sur un héros mobile,
   les lanternes retombaient sur le bouton « Réserver » et la couverture
   dépassait la hauteur de l'écran. C'est le bug des fenêtres non
   maximisées (typiquement un Mac à ~900px de large). */
@media (min-width: 781px) {
  .couverture .wrap {
    display: grid;
    grid-template-columns: minmax(290px, 27vw) minmax(0, 1fr);
    column-gap: clamp(1rem, 2vw, 2rem);
    align-items: center;
    max-width: 1760px;
    padding-right: 0;              /* le stand file jusqu'au bord */
  }
  .cover-col { grid-column: 1; grid-row: 1 / span 2; align-self: center; }
  .cover-actions { flex-direction: column; align-items: flex-start; }
  .cover-stand {
    grid-column: 2;
    grid-row: 1 / span 2;
    margin: 0;
    max-width: 1200px;
  }
  .cover-stand img { transform: rotate(1deg); }
  .cover-stand figcaption { padding-inline: 0; }
}

/* ---------- Les autres adresses de la famille (fin de l'histoire) ---------- */
.autres-kicker {
  color: var(--bleu-fonce);
  font-size: clamp(1.15rem, 4vw, 1.5rem);
  margin: clamp(1.5rem, 4vw, 2.5rem) 0 0.4rem;
  display: inline-block;
  transform: rotate(-2deg);
}
.autres-adresses { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.35rem; }
/* nom au-dessus, description dessous : sinon un nom tient sur la ligne et
   l'autre passe à la ligne selon la largeur, et les deux ne se ressemblent plus */
.autres-adresses li { display: grid; gap: 0; }
.info-block--autres p { text-align: left; }   /* colonne étroite : pas de justification */
.info-block--autres strong { font-weight: 600; color: var(--encre); }
.autres-nom { font-family: var(--f-titre); font-weight: 600; font-size: 1.1em; }
/* liens vers les deux autres adresses : filet permanent (pas de survol au tactile),
   cible tactile 44px */
.autres-nom a, .info-block--autres strong a {
  color: var(--framboise-fonce);
  /* soulignement sur le texte, pas border-bottom : la bordure se posait au bas
     de la zone tactile de 44px et barrait la ligne suivante */
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, currentColor 35%, transparent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
  display: inline-flex; align-items: center; min-height: 44px;
}
.info-block--autres p { hyphens: manual; -webkit-hyphens: manual; }
.autres-nom a:hover, .autres-nom a:focus-visible,
.info-block--autres strong a:hover, .info-block--autres strong a:focus-visible { color: var(--framboise); }
.autres-desc { color: var(--encre-doux); }

/* =========================================================
   MARGINALIA (illustrations d'Oriane dans la gouttière)
   ========================================================= */
.marginalia {
  position: absolute;
  z-index: 1;
  pointer-events: none;
  opacity: 0.92;
  filter: drop-shadow(0 8px 14px rgba(30,26,23,0.10));
}
.marginalia img { width: 100%; }

/* =========================================================
   BANDEAU PHOTO PLEIN-BLEED (séparateur de sections)
   Remplace les traits crayon supprimés. Format très panoramique,
   opposé franc au format « contenu » 3:2 des diptyques.
   ========================================================= */
.bandeau {
  position: relative;
  z-index: 1;
  width: 100%;
  margin: 0;
  overflow: hidden;
  background: var(--papier-ombre);
}
.bandeau img {
  width: 100%;
  aspect-ratio: 2.8 / 1;
  min-height: 190px;
  object-fit: cover;
}
.bandeau--lanternes img { object-position: center 62%; }

/* =========================================================
   DIPTYQUES ALTERNÉS (texte à côté de l'image)
   Toutes les images contenues ont RIGOUREUSEMENT la même taille
   (même colonne 1fr, même ratio 3:2) — seul le côté change.
   ========================================================= */
.dip {
  display: grid;
  gap: clamp(1.25rem, 3vw, 2.75rem);
  align-items: center;
  margin-block: clamp(2rem, 5vw, 3.5rem);
}
.dip-text > *:last-child { margin-bottom: 0; }
.dip-media { margin: 0; }
.dip-media img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--r-photo);
  box-shadow: var(--sh-photo);
}
.dip-media figcaption {
  margin-top: 0.55rem;
  font-family: var(--f-hand);
  font-size: clamp(1.1rem, 2.6vw, 1.4rem);
  color: var(--bleu-fonce);
}
@media (min-width: 900px) {
  .dip { grid-template-columns: 1fr 1fr; }
  .dip--media-right .dip-text  { grid-column: 1; grid-row: 1; }
  .dip--media-right .dip-media { grid-column: 2; grid-row: 1; }
  .dip--media-left  .dip-text  { grid-column: 2; grid-row: 1; }
  .dip--media-left  .dip-media { grid-column: 1; grid-row: 1; }
  .dip--media-right .dip-media img { transform: rotate(1deg); }
  .dip--media-left  .dip-media img { transform: rotate(-1deg); }
}

/* DUO signature : le dessin ↔ la vraie photo, taille identique */
.duo {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(1.4rem, 4vw, 3rem);
  margin-block: clamp(2rem, 5vw, 3.5rem);
  align-items: start;
}
@media (min-width: 700px) { .duo { grid-template-columns: 1fr 1fr; } }
.duo-item { margin: 0; }
.duo-item img {
  width: 100%;
  aspect-ratio: 3 / 2;
}
.duo-item--carnet img {
  object-fit: contain;
  filter: drop-shadow(0 12px 20px rgba(30,26,23,0.14));
  transform: rotate(-1deg);
}
.duo-item--reel img {
  object-fit: cover;
  border-radius: var(--r-photo);
  box-shadow: var(--sh-photo);
  transform: rotate(1deg);
}
.duo-item figcaption {
  font-family: var(--f-hand);
  font-size: clamp(1.2rem, 3.5vw, 1.6rem);
  margin-top: 0.6rem;
}
/* La légende de droite est alignée à droite : elle suit la POSITION dans la
   grille, pas la nature de l'image (l'ordre photo/dessin peut être inversé). */
.duo-item--carnet figcaption { color: var(--framboise-fonce); }
.duo-item--reel figcaption { color: var(--bleu-fonce); }
@media (min-width: 700px) {
  .duo-item:last-child figcaption { text-align: right; }
}

/* =========================================================
   HISTOIRE (genèse + voyages fusionnées)
   ========================================================= */
.histoire .wrap { position: relative; }
.prose { font-size: clamp(1.05rem, 1rem + 0.4vw, 1.18rem); }
.prose p:last-child { margin-bottom: 0; }
.histoire-punch {
  font-family: var(--f-titre);
  /* en droit : l'italique Lora 400 coûtait 49 Ko (latin + vietnamien) pour
     cette seule ligne. Le titre du lieu garde son italique, validé cliente. */
  font-size: clamp(1.25rem, 1rem + 1.3vw, 1.65rem);
  color: var(--encre);
  margin-block: clamp(1.5rem, 4vw, 2.5rem) 0;
}
.histoire-punch strong { color: var(--framboise-fonce); font-style: normal; font-weight: 600; }

/* encarts définition CHỢ / VỈA HÈ — texte officiel de la carte */
.lexique {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(1.1rem, 3vw, 2rem);
  margin-block: clamp(2rem, 5vw, 3.5rem) 0;
}
@media (min-width: 780px) { .lexique { grid-template-columns: 1fr 1fr; } }
.lexique-item {
  position: relative;
  background: var(--papier-ombre);
  border-radius: var(--r-card);
  box-shadow: var(--sh-card);
  padding: clamp(1.2rem, 3vw, 1.8rem);
  padding-right: clamp(1.2rem, 3vw, 4.5rem);
  margin: 0;
}
.lexique-mot {
  display: block;
  font-family: var(--f-titre);
  font-weight: 600;
  font-size: clamp(1.5rem, 1.1rem + 1.8vw, 2.1rem);
  color: var(--framboise);
  line-height: 1.1;
  margin-bottom: 0.15rem;
}
.lexique-trad {
  display: block;
  font-family: var(--f-hand);
  font-weight: 600;
  font-size: 1.25rem;
  color: var(--bleu-fonce);
  margin-bottom: 0.7rem;
}
.lexique-item p { margin: 0; color: var(--encre-doux); }
.lexique-illus {
  position: absolute;
  right: -0.4rem;
  bottom: -0.6rem;
  width: clamp(64px, 9vw, 104px);
  opacity: 0.85;
  pointer-events: none;
  filter: drop-shadow(0 6px 10px rgba(30,26,23,0.12));
}

/* marginalia de l'histoire — dans la gouttière droite du rail */
.marg-cafe { width: clamp(90px, 13vw, 150px); top: 5%; right: 1%; }
.marg-baguette { width: clamp(70px, 10vw, 118px); bottom: 6%; left: 0.5%; }
.marg-panier { width: clamp(80px, 11vw, 132px); top: 46%; right: 2%; opacity: 0.72; }

/* =========================================================
   CARTE (teaser)
   ========================================================= */
.carte .wrap { position: relative; }
.plat-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.2rem;
  margin: 2rem 0;
}
.plat-card {
  margin: 0;
  background: rgba(255,255,255,0.34);
  border: 1px solid rgba(30,26,23,0.12);
  border-radius: var(--r-card);
  padding: clamp(1rem, 3.5vw, 1.5rem);
  display: grid;
  grid-template-columns: minmax(84px, 30%) 1fr;
  gap: 1rem;
  align-items: center;
}
.plat-card img {
  width: 100%;
  max-height: 130px;
  object-fit: contain;
  filter: drop-shadow(0 8px 14px rgba(30,26,23,0.12));
}
.plat-nom {
  font-family: var(--f-titre);
  font-weight: 600;
  color: var(--framboise);
  font-size: clamp(1.5rem, 1.2rem + 2vw, 2.1rem);
  margin: 0 0 0.2rem;
  line-height: 1.1;
}
.plat-desc { margin: 0; color: var(--encre-doux); font-size: 1rem; }
.carte-cta { margin-top: 1.5rem; }
.marg-citrons { width: clamp(72px, 11vw, 128px); top: 8%; right: 1.5%; opacity: 0.9; }
.marg-coriandre { width: clamp(60px, 9vw, 104px); bottom: 6%; right: 1%; opacity: 0.9; }
.marg-sriracha { width: clamp(60px, 8vw, 100px); top: 44%; right: 1.5%; opacity: 0.7; }

/* =========================================================
   LE LIEU — même papier que le reste (le jaune est parti) ;
   l'énergie vient désormais des photos, plus grandes.
   ========================================================= */
.lieu { position: relative; z-index: 1; }
.lieu-title {
  color: var(--framboise);
  font-family: var(--f-titre);
  font-weight: 600;
  font-style: italic;
  font-size: clamp(1.9rem, 1.2rem + 2.6vw, 2.5rem);
}
.lieu-intro { font-size: clamp(1.1rem, 1rem + 0.6vw, 1.35rem); color: var(--encre); }
.lieu-bandeau { margin-block: clamp(1.75rem, 4vw, 2.75rem); }
.lieu-bandeau img { object-position: center 58%; }
.lieu-photos {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(1.1rem, 3vw, 2rem);
}
.lieu-photo { margin: 0; }
.lieu-photo img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--r-photo);
  box-shadow: var(--sh-photo);
}
.lieu-photo--neon img { object-position: center 22%; }
.lieu-photo figcaption {
  font-family: var(--f-hand);
  font-size: clamp(1.1rem, 2.6vw, 1.4rem);
  margin-top: 0.5rem;
  color: var(--bleu-fonce);
}
.lieu-photo:nth-child(odd) img { transform: rotate(-0.8deg); }
.lieu-photo:nth-child(even) img { transform: rotate(0.8deg); }
@media (min-width: 780px) { .lieu-photos { grid-template-columns: 1fr 1fr; } }
.marg-guirlande-lieu {
  width: min(56vw, 420px);
  top: clamp(0.4rem, 1.5vw, 1rem);
  right: 3%;
  opacity: 0.85;
  filter: drop-shadow(0 6px 12px rgba(30,26,23,0.14));
  z-index: 3;
}

/* =========================================================
   ON EN PARLE — presse + avis Google
   Deux registres différents : la presse est une liste sobre (c'est le nom
   du média qui porte la crédibilité), les avis sont des citations sur
   fond kraft, en écriture de carnet.
   ========================================================= */
/* PAS de fond plein : une bande --papier-ombre sur toute la largeur formait
   un grand rectangle qui coupait la page et se lisait comme un cadre posé
   par-dessus le reste. La section vit sur le même papier que le reste, avec
   les mêmes filets pointillés que la couverture et l'en-tête de la carte.
   Classe .on-en-parle et NON .presse : ce nom était déjà pris par l'ancien
   bloc de la section contact, mes styles débordaient donc sur lui. */
.on-en-parle {
  border-top: 1px dashed rgba(30,26,23,0.18);
  border-bottom: 1px dashed rgba(30,26,23,0.18);
}
.presse-kicker {
  color: var(--bleu-fonce);
  font-size: clamp(1.15rem, 4vw, 1.5rem);
  margin: 0 0 0.15rem;
  display: inline-block;
  transform: rotate(-2deg);
}
.presse-liste {
  list-style: none;
  margin: clamp(1.4rem, 4vw, 2.2rem) 0 0;
  padding: 0;
  display: grid;
  gap: clamp(0.9rem, 3vw, 1.4rem);
}
.presse-item {
  border-left: 3px solid var(--framboise);
  padding-left: clamp(0.8rem, 2.5vw, 1.1rem);
}
.presse-media {
  margin: 0;
  font-family: var(--f-corps);
  font-weight: 600;
  font-size: 0.86rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--framboise-fonce);
}
.presse-titre { margin: 0.25rem 0 0; font-size: clamp(1rem, 0.95rem + 0.4vw, 1.14rem); }
/* filet permanent discret : au tactile il n'y a pas de survol, sans lui les
   trois articles se lisaient comme du texte mort */
.presse-titre a { color: var(--encre); text-decoration: none; border-bottom: 1px solid color-mix(in srgb, currentColor 35%, transparent); }
.presse-titre a:hover,
.presse-titre a:focus-visible { color: var(--framboise); }

.avis-grille {
  display: grid;
  gap: clamp(1rem, 3vw, 1.6rem);
  margin-top: clamp(1.8rem, 5vw, 2.8rem);
}
.avis {
  margin: 0;
  display: flex; flex-direction: column;   /* signature calée en bas, quelle que soit la longueur */
  background: color-mix(in srgb, var(--papier) 88%, #fff);
  border: 1px solid rgba(30,26,23,0.12);
  border-radius: var(--r-card);
  box-shadow: var(--sh-card);
  padding: clamp(1.1rem, 3.5vw, 1.6rem);
}
.avis blockquote { margin: 0; }
.avis blockquote p {
  margin: 0;
  color: var(--encre);
  font-size: clamp(0.98rem, 0.94rem + 0.3vw, 1.06rem);
  text-align: justify;
  text-align-last: left;
  hyphens: auto;
  -webkit-hyphens: auto;
}
.avis blockquote p::before { content: '« '; }
.avis blockquote p::after { content: ' »'; }
.avis figcaption {
  margin-top: auto; padding-top: 0.9rem;
  font-family: var(--f-hand);
  font-size: 1.2rem;
  color: var(--bleu-fonce);
}
.avis-source {
  font-family: var(--f-corps);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--encre-doux);
  margin-left: 0.5rem;
}
.avis-lien {
  margin: clamp(1rem, 3vw, 1.4rem) 0 0;
  font-family: var(--f-hand);
  font-size: 1.25rem;
}
.avis-lien a { color: var(--bleu-fonce); text-decoration: none; display: inline-flex; align-items: center; min-height: 44px; border-bottom: 1px solid color-mix(in srgb, currentColor 35%, transparent); }
.avis-lien a:hover,
.avis-lien a:focus-visible { color: var(--framboise); }
@media (min-width: 780px) {
  /* auto-fit : 3 articles tiennent sur une ligne en grand écran, passent à 2
     puis 1 en dessous, sans laisser d'item orphelin sur une ligne à lui. */
  .presse-liste { grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr)); }
  .avis-grille { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 339px) {
  .avis blockquote p { text-align: left; }
}

/* =========================================================
   RÉSERVER / CONTACT (sobre)
   ========================================================= */
.reserver { background-image: none; }
.reserver .wrap { position: relative; z-index: 2; }
.reserver-title { color: var(--framboise); }
.reserver-lead { font-size: clamp(1.1rem, 1rem + 0.6vw, 1.35rem); }
.reserver-cta { margin: 1.5rem 0 2.5rem; }
.reserver-cta .btn-cta { font-size: 1.15rem; padding: 1rem 2rem; }

.infos-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.5rem 2rem;
}
.info-block h3 {
  font-family: var(--f-corps);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.78rem;
  color: var(--bleu-fonce);   /* 6.0:1 — petit texte, le bleu clair ne passait pas */
  margin-bottom: 0.5rem;
}
.info-block p, .info-block address { margin: 0 0 0.3rem; font-style: normal; }
/* Liens du bloc contact : même barre qui se dessine que partout ailleurs.
   Le trait fin permanent reste (le lien doit se voir sans survol) ; c'est la
   barre épaisse framboise qui se déploie au survol. */
.info-block a {
  position: relative;
  color: var(--encre);
  text-decoration: none;
  display: inline-block;
  padding-block: 0.55rem;
  margin-block: -0.55rem;
}
/* barre au survol uniquement, calée sous le texte (et non sous la zone de tap) */
.info-block a:not(.btn-cta)::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  bottom: calc(0.55rem - 3px);
  height: 2px;
  background: var(--framboise);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.4s var(--ease-out);
}
.info-block a:not(.btn-cta):hover::after,
.info-block a:not(.btn-cta):focus-visible::after { transform: scaleX(1); }
.info-block a:hover, .info-block a:focus-visible { color: var(--framboise-fonce); }
.horaires-list { list-style: none; padding: 0; }
.horaires-list li { display: flex; justify-content: space-between; gap: 1rem; max-width: 22rem; padding: 0.15rem 0; }
.horaires-list .jour { color: var(--encre-doux); }
.marg-poulets { width: clamp(76px, 11vw, 132px); top: 7%; right: 1%; opacity: 0.7; }

/* Questions du comptoir */
.comptoir { margin-top: clamp(2.5rem, 6vw, 4rem); }
.comptoir-title {
  font-size: clamp(1.5rem, 4vw, 2rem);
  color: var(--bleu-fonce);
  display: inline-block;
  margin: 0 0 1.2rem;
}
.comptoir-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
  gap: 1.2rem;
  margin: 0;
}
.comptoir-item {
  background: var(--papier-ombre);
  border-radius: var(--r-card);
  padding: 1.1rem 1.2rem;
  box-shadow: var(--sh-card);
}
.comptoir-item dt {
  font-family: var(--f-hand);
  font-weight: 600;
  font-size: 1.3rem;
  color: var(--framboise-fonce);
  margin-bottom: 0.4rem;
}
.comptoir-item dd { margin: 0; color: var(--encre-doux); font-size: 1rem; }
.comptoir-item dd a { color: var(--encre); border-bottom: 1px solid var(--framboise); text-decoration: none; }

/* =========================================================
   PISTE SCOOTER — pleine largeur, juste au-dessus du pied de page.
   Le scooter la traverse au scroll (gauche→droite, sens du dessin).
   Pas de pin, pas de scroll-trap.
   ========================================================= */
.scooter-track {
  position: relative;
  z-index: 1;
  width: 100%;
  /* la piste ne sert qu'à faire rouler le scooter : juste sa hauteur + la
     bande basse des légendes, sinon la fin de page paraît vide */
  min-height: clamp(150px, 17vw, 210px);
  border-top: 2px dashed rgba(30,110,140,0.32);
  border-bottom: 2px dashed rgba(30,110,140,0.32);
  padding: 1.2rem 0 3.6rem;
  margin-top: clamp(1rem, 3vw, 2rem);
  overflow: hidden;
}
.scooter {
  position: relative;
  width: clamp(130px, 20vw, 300px);
  margin-left: 3%;
  z-index: 2;
}
.scooter img {
  width: 100%;
  /* dessin v3 : regarde à DROITE → aucun flip, roule gauche→droite */
  filter: drop-shadow(0 10px 16px rgba(30,26,23,0.15));
}
.track-legend {
  position: absolute;
  font-family: var(--f-hand);
  font-weight: 600;
  color: var(--framboise-fonce);
  font-size: clamp(1.4rem, 4vw, 2.2rem);
  transform: rotate(-4deg);
  z-index: 1;
  text-shadow: 0 1px 0 var(--papier), 0 0 10px var(--papier), 0 0 4px var(--papier);
}
.track-legend--hanoi { top: 8%; left: var(--pad-x); }
.track-legend--saigon { bottom: 0.8rem; right: var(--pad-x); color: var(--bleu-fonce); transform: rotate(3deg); }

/* =========================================================
   FOOTER JAUNE (toutes les pages)
   Encre sur jaune = 9.0:1. JAMAIS de blanc sur jaune.
   ========================================================= */
.footer {
  position: relative;
  z-index: 1;
  background: var(--jaune);
  background-image: none;
  color: var(--encre);
  padding-block: clamp(2.25rem, 5vw, 3.5rem);
  overflow: hidden;
}
.footer .wrap { max-width: var(--wrap-max); }
.footer-grid {
  display: grid;
  /* mobile : infos sur toute la largeur, puis navigation et vélo côte à
     côte — empilé, le vélo laissait 164px de jaune vide entre le bouton
     et la liste. */
  grid-template-columns: 1fr auto;
  grid-template-areas: "infos infos" "nav velo";
  gap: 1.75rem 1.5rem;
  align-items: start;
}
.footer-infos { grid-area: infos; }
.footer-nav   { grid-area: nav; }
.footer-illus { grid-area: velo; align-self: end; }
@media (min-width: 700px) {
  /* infos | vélo | navigation */
  .footer-grid { grid-template-columns: minmax(0, 1.1fr) auto minmax(0, 0.7fr); grid-template-areas: "infos velo nav"; }
}
.footer-wordmark {
  display: inline-block;
  font-family: var(--f-titre);
  font-weight: 600;
  color: var(--encre);          /* framboise sur jaune = 3.1:1 → encre */
  font-size: clamp(1.6rem, 1.2rem + 2vw, 2.4rem);
  text-decoration: none;
  line-height: 1.1;
  margin-bottom: 0.6rem;
}
.footer-infos p, .footer-infos address {
  margin: 0 0 0.3rem;            /* assez d'air pour que la barre de survol
                                    d'une ligne ne touche pas la suivante */
  font-style: normal;
  color: var(--encre);
  line-height: 1.5;
}
/* Les lignes cliquables (téléphone, Instagram) gardent une zone de tap de
   44px, mais celle-ci est absorbée par des marges négatives : elle n'ajoute
   plus d'écart visible entre les lignes. */
.footer-infos a {
  position: relative;
  color: var(--encre);
  text-decoration: none;
  display: inline-block;
  padding-block: 0.62rem;
  margin-block: -0.55rem;
}
/* Barre qui se déploie AU SURVOL uniquement (aucun trait au repos) — en
   encre, le framboise ne tient pas le contraste sur le jaune.
   `bottom` compense le padding de la zone de tap : sans ça la barre se pose
   ~10 px plus bas et vient barrer la ligne de texte suivante. */
.footer-infos a:not(.btn-cta)::after,
.footer-nav a:not(.btn-cta)::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  bottom: calc(0.62rem - 3px);
  height: 2px;
  background: var(--encre);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.4s var(--ease-out);
}
.footer-infos a:not(.btn-cta):hover::after, .footer-infos a:not(.btn-cta):focus-visible::after,
.footer-nav a:not(.btn-cta):hover::after, .footer-nav a:not(.btn-cta):focus-visible::after { transform: scaleX(1); }
.footer-cta { margin-top: 1.2rem !important; }
/* le CTA du pied de page est un bouton, pas un lien de liste : il ne doit
   hériter ni de la couleur encre ni du soulignement de .footer-infos a
   (sinon texte encre sur pastille encre = illisible). */
.footer-infos .btn-cta--ink {
  color: var(--papier);
  border-bottom: 0;
  padding-block: 0.85rem;
  margin-block: 0;
}
.footer-nav-title {
  font-family: var(--f-corps);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--encre);
  margin: 0 0 0.6rem;
}
.footer-nav ul { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 0; }
.footer-nav a {
  position: relative;
  color: var(--encre);
  text-decoration: none;
  display: inline-block;
  padding-block: 0.62rem;
  margin-block: -0.3rem;         /* zone de tap conservée, écart visuel réduit */
}
/* l'illustration d'Oriane habite le coin bas-droit du pied de page */
/* Le vélo vit DANS la grille, juste à gauche du bloc « Le carnet ».
   (Avant : posé en absolu en bas à droite — c'est-à-dire pile là où les
   widgets tiers déposent leur bouton flottant, qui passait par-dessus.) */
.footer-illus {
  width: clamp(110px, 20vw, 200px);
  justify-self: center;
  align-self: end;
  pointer-events: none;
  filter: drop-shadow(0 8px 14px rgba(30,26,23,0.14));
}
.footer-illus img { width: 100%; }

/* =========================================================
   STICKY BAR MOBILE (≤780px)
   ========================================================= */
.sticky-actions {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 1400;
  display: none;
  gap: 0;
  padding-bottom: env(safe-area-inset-bottom, 0);
  background: color-mix(in srgb, var(--papier) 94%, transparent);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  border-top: 1px solid rgba(30,26,23,0.14);
  box-shadow: 0 -6px 18px rgba(30,26,23,0.12);
  /* --vv-bas : hauteur de la barre d'outils du navigateur qui recouvre le bas
     de la fenêtre (Firefox Android la place EN BAS, par-dessus les éléments
     fixés). Calculée en JS via l'API visualViewport ; 0 par défaut. */
  transform: translateY(calc(110% - var(--vv-bas, 0px)));
  transition: transform 0.35s var(--ease-out);
}
.sticky-actions[hidden] { display: none; }
.sticky-actions.is-visible { transform: translateY(calc(-1 * var(--vv-bas, 0px))); }
.sticky-btn {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 3.4rem;
  font-family: var(--f-corps);
  font-weight: 600;
  font-size: 0.98rem;
  text-decoration: none;
  border: none;
  white-space: nowrap;
}
.sticky-btn--book { flex-grow: 1.3; background: var(--jaune); color: var(--encre); }
.sticky-btn--call,
.sticky-btn--route {
  background: var(--papier);
  color: var(--encre);
  border-left: 1px solid rgba(30,26,23,0.14);
}
.sticky-btn:active { filter: brightness(0.95); }

/* =========================================================
   REVEAL (hooks motion — sans JS reste visible via .no-js)
   ========================================================= */
[data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--rev-dur) var(--ease-out), transform var(--rev-dur) var(--ease-out);
}
[data-reveal].is-in { opacity: 1; transform: none; }
.no-js [data-reveal] { opacity: 1; transform: none; }
.gsap-ready [data-reveal] { opacity: 1; transform: none; transition: none; }
.motion-armed [data-reveal] { opacity: 1; transform: none; transition: none; }
/* L'ÉTAT CACHÉ EST PORTÉ PAR LE CSS et armé AVANT LE PREMIER RENDU par le
   script inline du <head> (.motion-armed) : GSAP ne fait qu'animer VERS
   l'état visible. Si l'état de départ était posé par GSAP (ou par une classe
   ajoutée après chargement), la page s'afficherait visible puis les blocs
   sauteraient à 0 → clignotement. */
/* `:not(.marginalia)` — les illustrations de gouttière (verre de cà phê,
   citrons, panier…) sont décoratives, en position absolue et aria-hidden.
   Les faire apparaître avec le texte les faisait glisser de 24px à contre-
   temps du stagger, juste à côté du titre : ça se lit comme un défaut
   d'affichage, pas comme une apparition. Elles sont là dès le départ. */
.motion-armed [data-reveal] > .wrap > *:not(.marginalia),
.motion-armed [data-reveal] > .lieu-inner > *:not(.marginalia) {
  opacity: 0;
  transform: translateY(24px);
}
.motion-armed .voyages-diptyque .diptyque-item { opacity: 0; transform: translateY(26px); }
.scooter.is-riding { will-change: transform; }

/* =========================================================
   RESPONSIVE
   ========================================================= */
@media (min-width: 640px) {
  .plat-grid { grid-template-columns: 1fr 1fr; }
  .infos-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 900px) {
  .infos-grid { grid-template-columns: repeat(3, 1fr); }
}

/* Header responsive : burger sous 780px, CTA Réserver conservé */
@media (max-width: 780px) {
  .main-nav { display: none; }
  .header-cta { margin-left: auto; }
  .burger { display: block; margin-left: 0.5rem; }

  .sticky-active .header-cta {
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s var(--ease-out);
  }
  .sticky-actions { display: flex; }
  body { padding-bottom: calc(3.4rem + env(safe-area-inset-bottom, 0)); }
}
@media (min-width: 781px) {
  .nav-overlay { display: none !important; }
}

/* Hero densifié sous 781px (même seuil que le burger) : le haut du stand
   doit être visible dès le premier écran. */
@media (max-width: 780px) {
  .couverture {
    padding-top: calc(var(--header-h) + clamp(1.5rem, 5vw, 3rem));
    padding-bottom: clamp(2.5rem, 7vw, 4rem);
  }
  .guirlande-top { display: none; }
  .lanternes-pendantes { top: var(--header-h); width: clamp(72px, 20vw, 130px); }
  .cover-stand figcaption { display: none; }
}

/* Fenêtre étroite mais en mode bureau (781-1100px) : la guirlande de gauche
   et les lanternes de droite se rapprochent du logo et du bouton Réserver.
   On les rétrécit et on les descend sous la barre pour qu'elles ne se
   superposent jamais aux éléments cliquables. */
@media (min-width: 781px) and (max-width: 1100px) {
  .lanternes-pendantes {
    top: calc(var(--header-h) + 0.5rem);
    width: clamp(76px, 13vw, 130px);
    right: 0.75rem;
  }
  .guirlande-top {
    top: calc(var(--header-h) + 0.5rem);
    width: min(30vw, 250px);
  }
}

/* RÈGLE BINAIRE ≤780px : toute marginalia calée en % de bord est masquée
   (elle tomberait sur le texte quand les colonnes se replient).
   Whitelist testée à 375px : .footer-illus (le pied de page lui réserve
   sa place par un padding-bottom dédié). */
@media (max-width: 780px) {
  /* Bandeau : fond OPAQUE et sans flou sur mobile. Le backdrop-filter oblige
     le navigateur à recomposer le fond à chaque frame ; pendant que la barre
     d'URL de Safari/Firefox se rétracte, le bandeau se repeint en retard et
     semble « entrer » dans la barre du navigateur (signalé par la cliente). */
  .site-header {
    background: var(--papier);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .rail { width: 100%; }
  .marginalia { display: none; }
  .track-legend--hanoi { top: 5%; }
  .scooter { width: clamp(120px, 30vw, 170px); margin-left: 5%; }
  .scooter-track { min-height: clamp(150px, 34vw, 200px); padding-bottom: 4rem; }
  /* le vélo étant maintenant dans le flux, plus besoin de lui réserver
     une bande vide en bas du pied de page */
  .footer-illus { width: clamp(96px, 26vw, 140px); justify-self: end; }
  .lexique-illus { width: clamp(56px, 14vw, 84px); }
}
@media (max-width: 420px) {
  :root { --header-h: 3.9rem; }
  .site-header .wrap { gap: 0.5rem; padding-inline: 0.9rem; }
  .header-cta { padding: 0.45rem 0.85rem; min-height: 44px; font-size: 0.85rem; box-shadow: 0 3px 0 color-mix(in srgb, var(--jaune) 60%, #000 15%); }
  .burger { width: 2.75rem; height: 2.75rem; margin-left: 0.4rem; }
}

/* =========================================================
   REDUCED MOTION — tout statique
   ========================================================= */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
  .lanternes-pendantes { animation: none !important; }
}
