/* Crema, café et cantine de quartier. Croix-Rousse, Lyon 4e.
   Aperçu de prospection Caelestis. Palette pipetée sur leurs propres photos :
   le crème de la devanture, le brun du velours de l'étage, l'inox des plateaux,
   et le violet de leur signature sur les réseaux. */

@import url('polices.css?v=9bfa8b8e');

/* Le navigateur mène la transition d'une page à l'autre ; le logo et la barre
   restent en place pendant que le reste se renouvelle. */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation-duration: .28s; }
::view-transition-new(root) { animation-duration: .4s; }

:root {
  /* Primitives, relevées à la pipette sur les photos du lieu */
  --papier:        #F2EBE3;  /* oklch(0.943 0.013 71.3) devanture couleur crème */
  --sable:         #E7DCD0;  /* oklch(0.900 0.020 70.0) fond alterné */
  --espresso:      #231A13;  /* oklch(0.226 0.019 59.5) intérieur vu par la vitre */
  --velours:       #4F392B;  /* oklch(0.365 0.039 53.6) banquette de l'étage */
  --encre-doux:    #5E4F44;  /* oklch(0.439 0.027 58.2) texte secondaire */
  --violet:        #5A3FB8;  /* oklch(0.469 0.181 287.5) leur accent sur les réseaux */
  --violet-clair:  #BCA6F7;  /* oklch(0.774 0.116 296.1) le même, sur fond sombre */
  --inox:          #9B9A96;  /* oklch(0.686 0.006 95.1) plateaux et comptoir */
  --inox-clair:    #D7D4CE;  /* oklch(0.871 0.009 84.6) filets */
  --crema:         #9A5A30;  /* oklch(0.532 0.101 52.1) la mousse de l'espresso */
  --crema-clair:   #C98A54;  /* oklch(0.685 0.104 60.3) le disque sur fond sombre */

  /* Rôles */
  --fond: var(--papier);
  --fond-2: var(--sable);
  --fond-plein: var(--espresso);
  --texte: var(--espresso);
  --texte-2: var(--encre-doux);
  --texte-sur-plein: #EDE4DA;
  --texte-sur-plein-2: #B5A79A;
  --accent: var(--violet);
  --accent-sur-plein: var(--violet-clair);
  --filet: color-mix(in oklab, var(--espresso) 16%, transparent);
  --filet-sur-plein: color-mix(in oklab, #EDE4DA 20%, transparent);

  /* Rythme */
  --marge: clamp(20px, 5vw, 72px);
  --large: 1340px;
  --texte-large: 68ch;
  --s-1: clamp(10px, 1.2vw, 16px);
  --s-2: clamp(18px, 2.2vw, 32px);
  --s-3: clamp(32px, 4vw, 56px);
  --s-4: clamp(56px, 7vw, 96px);
  --s-5: clamp(88px, 6vw + 40px, 160px);
  --s-6: clamp(120px, 14vw, 220px);

  --rayon: 3px;
  --rayon-2: 5px;
  --sortie: cubic-bezier(.16, 1, .3, 1);
}

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

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

body {
  margin: 0;
  background: var(--fond);
  color: var(--texte);
  font-family: 'Satoshi', system-ui, sans-serif;
  font-size: 17px;
  line-height: 1.62;
  font-weight: 400;
  overflow-x: hidden;
  touch-action: pan-y pinch-zoom;
}

h1, h2, h3, .display {
  font-family: 'Clash Display', 'Satoshi', system-ui, sans-serif;
  font-weight: 600;
  letter-spacing: -0.03em;
  line-height: 0.95;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0 0 1em; max-width: var(--texte-large); }
p:last-child { margin-bottom: 0; }

a { color: inherit; }

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

/* Le <picture> sort de la mise en page : sans cela, posé dans une grille, il
   prend sa largeur intrinsèque et l'image tombe à 82 px de large. */
picture { display: contents; }

:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }

/* ---------- Dispositif signature : le disque de crema ----------
   La mousse ambrée qui couronne un espresso, et qui donne son nom à la maison.
   Elle revient en puce, en repère d'heure, en filigrane et en favicon. */

.disque {
  display: inline-block;
  width: 0.56em;
  height: 0.56em;
  border-radius: 50%;
  background: var(--crema);
  flex: none;
}
.sur-plein .disque, .plein .disque { background: var(--crema-clair); }

.surtitre {
  display: flex;
  align-items: center;
  gap: 0.7em;
  font-family: 'Satoshi', sans-serif;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--texte-2);
  margin: 0 0 var(--s-2);
}
.plein .surtitre { color: var(--texte-sur-plein-2); }

/* ---------- Trame ---------- */

.enveloppe { width: min(100% - var(--marge) * 2, var(--large)); margin-inline: auto; }
.etroit { width: min(100% - var(--marge) * 2, 860px); margin-inline: auto; }

section { padding-block: var(--s-5); }
section.serre { padding-block: var(--s-4); }
section.plein {
  background: var(--fond-plein);
  color: var(--texte-sur-plein);
  position: relative;
  isolation: isolate;
}
/* Matière plutôt que dégradé : un grain discret sur les fonds sombres. */
section.plein::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}
section.sable { background: var(--fond-2); }

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

.entete {
  view-transition-name: entete;
  position: fixed;
  inset: 0 0 auto;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
  padding: 14px var(--marge);
  color: var(--texte-sur-plein);
  transition: background .5s var(--sortie), color .5s var(--sortie), box-shadow .5s var(--sortie);
}
.entete.pose {
  background: var(--papier);
  color: var(--espresso);
  box-shadow: 0 1px 0 var(--filet);
}
.entete__nom {
  view-transition-name: logo;
  font-family: 'Clash Display', sans-serif;
  font-weight: 500;
  font-size: 26px;
  letter-spacing: 0.1em;
  text-decoration: none;
  text-transform: lowercase;
}
.nav { display: flex; align-items: center; gap: clamp(14px, 2vw, 32px); }
.nav a {
  font-size: 14.5px;
  font-weight: 500;
  text-decoration: none;
  padding: 6px 0;
  position: relative;
}
/* Zone de clic portée à 44 px sans changer la hauteur de la barre. */
.nav a::before, .nav__menu::before {
  content: '';
  position: absolute;
  inset: -6px -8px;
  min-height: 44px;
  top: 50%;
  translate: 0 -50%;
}
.nav a::after {
  content: '';
  position: absolute;
  left: 0; right: 100%; bottom: 0;
  height: 1.5px;
  background: currentColor;
  transition: right .5s var(--sortie);
}
.nav a:hover::after, .nav a[aria-current='page']::after { right: 0; }
.nav a[aria-current='page'] { font-weight: 700; }
.nav a.bouton { padding: 12px 24px; }
.nav a.bouton::after { content: none; }

.bouton {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  padding: 13px 26px;
  border: 1.5px solid currentColor;
  border-radius: 999px;
  font-size: 14.5px;
  font-weight: 700;
  text-decoration: none;
  transition: background .3s var(--sortie), color .3s var(--sortie);
}
.bouton:hover { background: var(--espresso); color: var(--papier); border-color: var(--espresso); }
.entete.pose .bouton:hover, .plein .bouton:hover { background: var(--papier); color: var(--espresso); border-color: var(--papier); }
.bouton--plein {
  background: var(--espresso);
  color: var(--papier);
  border-color: var(--espresso);
}
.bouton--plein:hover { background: var(--violet); border-color: var(--violet); color: #fff; }
.nav__menu { display: none; position: relative; }

/* ---------- Héros ---------- */

.heros {
  position: relative;
  /* le contenu suit la marge de l'enveloppe */
  min-height: 100svh;
  display: flex;
  align-items: flex-end;
  color: var(--texte-sur-plein);
  isolation: isolate;
  overflow: hidden;
}
.heros__media { position: absolute; inset: 0; z-index: -2; }
.heros__media img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 58%; }
/* Voile de lisibilité, posé sur le média : outil de contraste, pas décoration. */
.heros::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(to top, rgba(18, 12, 8, .9) 0%, rgba(18, 12, 8, .66) 38%, rgba(18, 12, 8, .3) 68%, rgba(18, 12, 8, .52) 100%),
    rgba(18, 12, 8, .14);
}
.heros__contenu { padding-block: clamp(40px, 9vh, 110px) clamp(34px, 7vh, 72px); }
/* Le texte du héros se pose sur une photo claire par endroits : il garde sa propre ombre. */
.heros .surtitre { color: #EFE6DC; text-shadow: 0 1px 16px rgba(18, 12, 8, .85); }
.heros h1 { text-shadow: 0 2px 30px rgba(18, 12, 8, .55); }
.heros__appel, .heros__etat { text-shadow: 0 1px 14px rgba(18, 12, 8, .8); }
.heros h1 {
  font-size: clamp(3.1rem, 8.4vw, 6.6rem);
  line-height: 0.92;
  max-width: 15ch;
  margin-bottom: var(--s-2);
}
.heros__appel {
  font-size: clamp(17px, 1.4vw, 20px);
  color: #EBE1D6;
  max-width: 46ch;
  margin-bottom: var(--s-3);
}
.heros__pied {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  padding-top: var(--s-2);
  border-top: 1px solid var(--filet-sur-plein);
}
.heros__pied p { margin: 0; }
.heros__etat { display: flex; align-items: center; gap: 0.6em; font-size: 15px; font-weight: 500; line-height: 1.2; }
.heros__fil {
  position: absolute;
  left: 50%;
  bottom: 0;
  width: 1px;
  height: clamp(34px, 6vh, 58px);
  overflow: hidden;
  background: color-mix(in oklab, #EDE4DA 22%, transparent);
}
.heros__fil::after {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 42%;
  background: var(--crema-clair);
}
.js .heros__fil::after { animation: descend 2.6s var(--sortie) infinite; }
.heros__fil { transition: opacity .6s var(--sortie); z-index: 1; }
body.defile .heros__fil { opacity: 0; }
@keyframes descend {
  0% { transform: translateY(-110%); }
  55%, 100% { transform: translateY(260%); }
}
.heros__etat .disque { background: var(--crema-clair); }

/* ---------- Ruban des heures (module sur mesure) ---------- */

.ruban { position: relative; }
.ruban__grille { display: grid; gap: var(--s-3); grid-template-columns: 1fr; }
@media (min-width: 900px) {
  .ruban__grille { grid-template-columns: minmax(0, 6fr) minmax(0, 6fr); gap: var(--s-4); align-items: stretch; }
}

.services { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; }
.service {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: var(--s-2);
  row-gap: 7px;
  padding: 18px 0;
  border-bottom: 1px solid var(--filet-sur-plein);
}
.service:first-child { border-top: 1px solid var(--filet-sur-plein); }
.service__nom { font-family: 'Clash Display', sans-serif; font-weight: 500; font-size: clamp(20px, 2.1vw, 27px); letter-spacing: -0.02em; line-height: 1.12; }
.service__quand { font-size: 14px; font-weight: 700; letter-spacing: 0.08em; color: var(--crema-clair); white-space: nowrap; }
.service__quoi { color: var(--texte-sur-plein-2); font-size: 15.5px; grid-column: 2 / -1; }
@media (max-width: 640px) {
  .service { grid-template-columns: auto minmax(0, 1fr); row-gap: 6px; }
  .service__quand { grid-column: 2; }
}

/* ---------- Titres de section ---------- */

.titre-section {
  font-size: clamp(2.1rem, 4.4vw, 3.5rem);
  max-width: 18ch;
  margin-bottom: var(--s-2);
}
.chapeau { font-size: clamp(17px, 1.3vw, 19.5px); color: var(--texte-2); max-width: 54ch; }
.plein .chapeau { color: var(--texte-sur-plein-2); }

.entete-section {
  display: grid;
  gap: var(--s-2);
  margin-bottom: var(--s-3);
}
@media (min-width: 900px) {
  .entete-section {
    grid-template-columns: minmax(0, 6fr) minmax(0, 5fr);
    gap: var(--s-4);
    align-items: end;
  }
  .entete-section .titre-section { margin-bottom: 0; }
}

/* ---------- Deux colonnes asymétriques ---------- */

.duo { display: grid; gap: var(--s-3); align-items: center; }
@media (min-width: 820px) {
  .duo { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--s-4); }
  .duo:has(.pile) { align-items: start; }
  .duo--inverse { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
  .duo--inverse .duo__texte { order: 2; }
  .entete-section { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); gap: var(--s-3); align-items: end; }
  .entete-section .titre-section { margin-bottom: 0; }
}
.duo__texte h2 { margin-bottom: var(--s-2); }
.duo > figure { transition: transform .5s var(--sortie), box-shadow .5s var(--sortie); }
.duo > figure:hover { transform: translateY(-4px); box-shadow: 0 18px 44px -24px rgba(24, 16, 10, .55); }

/* Rupture de conteneur : l'image déborde vers le bord de l'écran. */
.deborde-droite { margin-right: calc(var(--marge) * -1); }
.deborde-gauche { margin-left: calc(var(--marge) * -1); }
@media (min-width: 1460px) {
  .deborde-droite { margin-right: calc((100vw - var(--large)) / -2); }
  .deborde-gauche { margin-left: calc((100vw - var(--large)) / -2); }
}

/* ---------- Bandes de média pleine largeur ---------- */

.bande { position: relative; width: min(100%, 1800px); margin-inline: auto; }
.bande img { width: 100%; height: clamp(320px, 62vh, 680px); object-fit: cover; }
.bande--haute img { height: clamp(420px, 86vh, 900px); }
.bande__legende {
  position: absolute;
  left: var(--marge);
  bottom: clamp(18px, 3vw, 34px);
  color: #F2EBE3;
  font-size: 14px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-shadow: 0 1px 14px rgba(20, 14, 10, .7);
  display: flex;
  align-items: center;
  gap: 0.7em;
  max-width: 40ch;
}
.bande__legende .disque { background: var(--crema-clair); }

/* ---------- Figures ---------- */

figure { margin: 0; }
figure img { border-radius: var(--rayon); }
figcaption {
  margin-top: 12px;
  font-size: 13.5px;
  color: var(--texte-2);
  display: flex;
  align-items: center;
  gap: 0.6em;
}
.plein figcaption { color: var(--texte-sur-plein-2); }

/* ---------- Mosaïque de photos ---------- */

.mosaique { display: grid; gap: var(--s-2); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 900px) { .mosaique { grid-template-columns: repeat(12, minmax(0, 1fr)); } }
.mosaique img { width: 100%; height: 100%; object-fit: cover; border-radius: var(--rayon); }
.m-haute { grid-column: span 2; aspect-ratio: 3 / 4; }
.m-large { grid-column: span 2; aspect-ratio: 4 / 3; }
@media (min-width: 900px) {
  .m-haute { grid-column: span 4; aspect-ratio: 3 / 4; }
  .m-large { grid-column: span 8; aspect-ratio: 16 / 10; }
  .m-tiers { grid-column: span 4; aspect-ratio: 1 / 1; }
  .m-moitie { grid-column: span 6; aspect-ratio: 4 / 3; }
}
.m-tiers, .m-moitie { grid-column: span 1; aspect-ratio: 1 / 1; }


/* ---------- Galerie : une mosaïque dense, tailles variées ---------- */

.galerie {
  display: grid;
  gap: var(--s-1);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: minmax(190px, auto);
}
/* Sur un téléphone, dix photos empilées ajoutent quatre écrans de défilement :
   la galerie devient un rail que l'on fait glisser au doigt. */
@media (max-width: 759px) {
  .galerie {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-left: var(--marge);
    gap: 10px;
    margin-inline: calc(var(--marge) * -1);
    padding-inline: var(--marge);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .galerie::-webkit-scrollbar { display: none; }
  .galerie figure { flex: 0 0 66vw; height: 78vw; scroll-snap-align: start; }
  .galerie figure.g-double { flex-basis: 80vw; }
  .galerie figure.g-triple { flex-basis: 86vw; }
}
@media (min-width: 760px) {
  .galerie { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-2); grid-auto-rows: minmax(330px, auto); }
  .galerie .g-double { grid-column: span 2; }
  /* Une photo en bandeau ferme une rangée que trois cellules ne rempliraient
     pas : quatre photos se posent alors en un paysage au-dessus et trois
     dessous, au lieu de laisser un vide au coin. */
  .galerie .g-triple { grid-column: 1 / -1; }
  .galerie .g-triple img { height: clamp(300px, 34vw, 520px); }
}
@media (min-width: 1180px) { .galerie { grid-auto-rows: minmax(400px, auto); } }
/* ⚠️ `height: 100%` ne vaut que pour la grille. Posée ici sans condition, elle
   passait après la rupture du rail, à spécificité égale, et écrasait son
   `height: 78vw` : en flex, chaque photo reprenait alors la hauteur de son
   fichier, et le rail alignait dix figures de 324 à 634 px. La galerie prenait
   la plus haute, d'où 213 px de vide sous les photos sur un téléphone. */
.galerie figure { margin: 0; }
@media (min-width: 760px) { .galerie figure { height: 100%; } }
.galerie img { width: 100%; height: 100%; object-fit: cover; border-radius: var(--rayon); display: block; }

/* Pile : deux ou trois photos empilées dans une colonne, la seconde décalée.
   Préférée à une grille de deux dans un duo, où chaque photo tomberait sous
   320 px de large sur un écran de 1440. */
.pile { display: grid; gap: var(--s-2); }
.pile figure { margin: 0; }
.pile img { width: 100%; height: auto; border-radius: var(--rayon); display: block; }
.pile .decalee { width: 74%; margin-left: auto; }
.pile .decalee-gauche { width: 74%; margin-right: auto; }

/* ---------- Carte, volets ---------- */

.volets { display: grid; gap: var(--s-3); }
@media (min-width: 820px) { .volets { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s-2); } }
.volet { display: flex; flex-direction: column; gap: var(--s-2); transition: transform .35s var(--sortie); }
.volet:hover { transform: translateY(-5px); }
.volet picture { display: contents; }
.volet > picture > img, .volet img { overflow: hidden; }
.volet img { aspect-ratio: 4 / 5; object-fit: cover; width: 100%; border-radius: var(--rayon); }
.volet h3 { font-size: clamp(25px, 2.4vw, 33px); }
.volet ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; }
.volet li { display: flex; gap: 0.75em; align-items: baseline; font-size: 16px; color: var(--texte-2); }
.plein .volet li { color: var(--texte-sur-plein-2); }
.volet li .disque { transform: translateY(-0.12em); }

/* ---------- Liste de carte (page La carte) ---------- */

.plats { display: grid; gap: 0; }
.plat {
  display: grid;
  gap: 4px var(--s-2);
  padding: 22px 0;
  border-bottom: 1px solid var(--filet);
  align-items: baseline;
}
.plein .plat { border-color: var(--filet-sur-plein); }
.plats .plat:first-child { border-top: 1px solid var(--filet); }
.plein .plats .plat:first-child { border-top-color: var(--filet-sur-plein); }
@media (min-width: 760px) { .plat { grid-template-columns: minmax(0, 9fr) minmax(0, 11fr); } }
.plat__nom { font-family: 'Clash Display', sans-serif; font-weight: 500; font-size: clamp(21px, 2vw, 26px); letter-spacing: -0.02em; line-height: 1.12; }
.plat__detail { color: var(--texte-2); font-size: 16px; }
.plein .plat__detail { color: var(--texte-sur-plein-2); }

/* ---------- Fiche technique ---------- */

.fiche { margin: 0; display: grid; gap: 0; }
.fiche > div {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--s-2);
  align-items: baseline;
  padding: 15px 0;
  border-bottom: 1px solid var(--filet);
}
.plein .fiche > div { border-color: var(--filet-sur-plein); }
.fiche dt { font-size: 12.5px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--texte-2); }
.plein .fiche dt { color: var(--texte-sur-plein-2); }
.fiche dd { margin: 0; font-size: 16.5px; font-weight: 500; text-align: right; }

/* ---------- Torréfacteurs ---------- */

.grains { display: grid; gap: 1px; }
.grain {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: 22px 0;
  border-bottom: 1px solid var(--filet-sur-plein);
}
.grain:first-child { border-top: 1px solid var(--filet-sur-plein); }
.grain__nom { font-family: 'Clash Display', sans-serif; font-weight: 500; font-size: clamp(26px, 3.4vw, 46px); letter-spacing: -0.03em; line-height: 1.08; transition: color .5s var(--sortie); }
.grain:hover .grain__nom { color: var(--crema-clair); }

/* ---------- Avis ---------- */

.note { display: flex; align-items: baseline; gap: 0.5em; }
.note__chiffre { font-family: 'Clash Display', sans-serif; font-weight: 600; font-size: clamp(3.4rem, 7vw, 6rem); line-height: 0.85; letter-spacing: -0.04em; }
.note__sur { font-size: 16px; color: var(--texte-2); }
.plein .note__sur { color: var(--texte-sur-plein-2); }
.verbatims { list-style: none; margin: var(--s-3) 0 0; padding: 0; display: grid; gap: var(--s-2); }
.verbatim { padding-left: var(--s-2); border-left: 2px solid var(--crema); font-size: 17px; }
.plein .verbatim { border-color: var(--crema-clair); }
.verbatim span { display: block; margin-top: 7px; font-size: 13px; color: var(--texte-2); }
.plein .verbatim span { color: var(--texte-sur-plein-2); }

/* ---------- Scène immersive : un texte posé sur une photo plein cadre ----------
   Sert aux moments signature, pour qu'aucune section ne reste sans image. */

.scene {
  position: relative;
  width: min(100%, 1800px);
  margin-inline: auto;
  min-height: clamp(520px, 86vh, 860px);
  display: flex;
  align-items: flex-end;
  color: var(--texte-sur-plein);
  isolation: isolate;
  overflow: hidden;
}
.scene__media { position: absolute; inset: 0; z-index: -2; }
.scene__media img { width: 100%; height: 100%; object-fit: cover; }
.scene::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(to top, rgba(18, 12, 8, .92) 0%, rgba(18, 12, 8, .7) 42%, rgba(18, 12, 8, .34) 74%, rgba(18, 12, 8, .22) 100%),
    rgba(18, 12, 8, .18);
}
.scene__contenu { padding-block: clamp(40px, 8vh, 96px); }
.scene .regle__mot { font-size: clamp(3.4rem, 11vw, 9rem); }
.scene .regle__texte { color: #EDE4DA; text-shadow: 0 1px 14px rgba(18, 12, 8, .7); }
.scene .surtitre { color: #EFE6DC; text-shadow: 0 1px 16px rgba(18, 12, 8, .85); }
.scene .regle__mot { text-shadow: 0 2px 30px rgba(18, 12, 8, .5); }

/* ---------- Moment signature : la règle des trente minutes ---------- */

.regle { position: relative; overflow: hidden; }
.regle__disque {
  position: absolute;
  right: -14vw;
  top: 50%;
  translate: 0 -50%;
  width: min(74vw, 760px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: color-mix(in oklab, var(--crema-clair) 13%, transparent);
  z-index: 0;
  pointer-events: none;
}
.regle .enveloppe { position: relative; z-index: 1; }
.regle__mot {
  font-family: 'Clash Display', sans-serif;
  font-weight: 600;
  font-size: clamp(4rem, 14vw, 11rem);
  line-height: 0.82;
  letter-spacing: -0.045em;
  margin: 0 0 var(--s-2);
}
.regle__texte { font-size: clamp(17px, 1.5vw, 21px); max-width: 48ch; }

/* ---------- Formulaire ---------- */

.formulaire { display: grid; gap: var(--s-2); }
.champ { display: grid; gap: 7px; }
.champ label { font-size: 13.5px; font-weight: 700; color: var(--texte-2); }
.plein .champ label { color: var(--texte-sur-plein-2); }
.champ input, .champ textarea {
  font-family: inherit;
  font-size: 16.5px;
  color: inherit;
  background: transparent;
  border: 0;
  border-bottom: 1.5px solid var(--filet);
  padding: 11px 0;
  border-radius: 0;
}
.plein .champ input, .plein .champ textarea { border-color: var(--filet-sur-plein); }
.champ input::placeholder, .champ textarea::placeholder { color: var(--texte-2); opacity: 1; }
.plein .champ input::placeholder, .plein .champ textarea::placeholder { color: var(--texte-sur-plein-2); }
.champ input:focus, .champ textarea:focus { outline: 0; border-color: var(--accent); }
.plein .champ input:focus, .plein .champ textarea:focus { border-color: var(--accent-sur-plein); }
@media (min-width: 760px) { .formulaire__paire { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-2); } }

/* ---------- Pied ---------- */

.pied { background: var(--espresso); color: var(--texte-sur-plein); padding-block: var(--s-4) var(--s-2); }
.pied__haut { display: grid; gap: var(--s-3); }
@media (min-width: 880px) { .pied__haut { grid-template-columns: minmax(0, 6fr) minmax(0, 3fr) minmax(0, 3fr); gap: var(--s-3); } }
.pied__nom {
  font-family: 'Clash Display', sans-serif;
  font-weight: 500;
  font-size: clamp(3.4rem, 11vw, 8.4rem);
  line-height: 0.82;
  letter-spacing: 0.02em;
  text-transform: lowercase;
  margin: var(--s-4) 0 var(--s-2);
  color: color-mix(in oklab, var(--texte-sur-plein) 22%, transparent);
}
.pied a { color: var(--texte-sur-plein); text-decoration: none; }
.pied a:hover { color: var(--crema-clair); }
.pied ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; font-size: 15.5px; }
.pied h2 { font-size: 14px; font-family: 'Satoshi', sans-serif; font-weight: 700; color: var(--texte-sur-plein-2); margin-bottom: var(--s-2); }
.pied__bas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-1) var(--s-2);
  justify-content: space-between;
  padding-top: var(--s-2);
  border-top: 1px solid var(--filet-sur-plein);
  font-size: 13px;
  color: var(--texte-sur-plein-2);
}


/* ---------- Moment épinglé : la galerie glisse pendant que la page tient ----------
   Le script pose la classe, et sans lui la galerie reste la grille ordinaire. */

.js .galerie--rail { display: flex; gap: var(--s-2); width: max-content; padding-right: var(--marge); }
.js .galerie--rail figure { flex: 0 0 clamp(300px, 34vw, 480px); height: clamp(380px, 54vh, 620px); }
.js .galerie--rail figure.g-double { flex-basis: clamp(420px, 48vw, 680px); }
.js .galerie--rail figure.g-triple { flex-basis: clamp(480px, 56vw, 800px); }
.epingle { position: relative; overflow: hidden; }
.epingle__piste { will-change: transform; }
.epingle__barre {
  position: absolute;
  left: var(--marge);
  right: var(--marge);
  bottom: clamp(18px, 3vh, 34px);
  height: 2px;
  background: color-mix(in oklab, var(--espresso) 14%, transparent);
}
.epingle__barre span { display: block; height: 100%; width: 0; background: var(--crema); transform-origin: left; }

/* ---------- Texte-masque : la photo se lit à travers les lettres ---------- */

.mot-masque {
  background-image: var(--photo);
  background-size: 128% auto;
  background-position: 50% 46%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}
@supports not ((background-clip: text) or (-webkit-background-clip: text)) {
  .mot-masque { color: var(--texte-sur-plein); -webkit-text-fill-color: currentColor; }
}

/* ---------- Profondeur : des blocs qui chevauchent le média ---------- */

.chevauche { position: relative; z-index: 2; }
@media (min-width: 900px) {
  .chevauche { margin-top: clamp(-180px, -12vw, -80px); }
  .chevauche__carte {
    background: var(--papier);
    padding: clamp(24px, 3vw, 44px);
    border-radius: var(--rayon-2);
    box-shadow: 0 30px 70px -40px rgba(24, 16, 10, .55);
    width: min(100%, 600px);
  }
  .plein .chevauche__carte { background: var(--espresso); box-shadow: 0 30px 70px -40px rgba(0, 0, 0, .8); }
}
.chevauche__carte dt { color: var(--texte-2); }

/* ---------- Grille cassée : deux colonnes décalées ---------- */

@media (min-width: 1000px) {
  .duo--decale > :last-child { transform: translateY(clamp(40px, 6vw, 96px)); }
  .pleine-largeur { width: calc(100% + var(--marge) * 2); margin-inline: calc(var(--marge) * -1); }
}

/* ---------- Mouvement ----------
   Trois gestes, choisis pour un café : le voile qui se lève sur une photo,
   le disque de crema qui se remplit comme une extraction, et les lignes de
   titre qui montent. Tout le contenu reste visible sans JavaScript : la
   classe .js, posée par le script, est la seule à masquer quoi que ce soit. */

[data-leve] { transition: opacity 1s var(--sortie), transform 1.1s var(--sortie); }
.js [data-leve] { opacity: 0; transform: translateY(26px); }
.js [data-leve].vu { opacity: 1; transform: none; }
.js [data-leve='2'] { transition-delay: .09s; }
.js [data-leve='3'] { transition-delay: .18s; }
.js [data-leve='4'] { transition-delay: .27s; }

/* 1. Le voile qui se lève : une photo se découvre du bas vers le haut, et
   avance de deux pour cent pendant qu'elle se découvre. */
.js figure[data-leve] img,
.js .galerie[data-leve] img,
.js .pile[data-leve] img,
.js .mosaique[data-leve] img,
.js .bande[data-leve] img {
  clip-path: inset(0 0 100% 0);
  transform: scale(1.04);
  transition: clip-path 1.2s var(--sortie), transform 1.5s var(--sortie);
}
.js figure[data-leve].vu img,
.js .galerie[data-leve].vu img,
.js .pile[data-leve].vu img,
.js .mosaique[data-leve].vu img,
.js .bande[data-leve].vu img { clip-path: inset(0 0 0 0); transform: none; }
/* Dans une galerie, les photos se découvrent l'une après l'autre. */
.js .galerie[data-leve] figure:nth-child(3n+2) img { clip-path: inset(0 100% 0 0); }
.js .galerie[data-leve].vu figure:nth-child(3n+2) img { clip-path: inset(0 0 0 0); }
.js .galerie[data-leve] img { transition-delay: 0s; }
.js .galerie[data-leve] figure:nth-child(2) img { transition-delay: .08s; }
.js .galerie[data-leve] figure:nth-child(3) img { transition-delay: .16s; }
.js .galerie[data-leve] figure:nth-child(4) img { transition-delay: .24s; }
.js .galerie[data-leve] figure:nth-child(5) img { transition-delay: .32s; }
.js .galerie[data-leve] figure:nth-child(6) img { transition-delay: .40s; }
.js .galerie[data-leve] figure:nth-child(n+7) img { transition-delay: .48s; }
/* La figure qui se dévoile ne doit pas emporter son image en translation. */
.js figure[data-leve], .js .galerie[data-leve], .js .pile[data-leve], .js .mosaique[data-leve], .js .bande[data-leve] { opacity: 1; transform: none; }

/* 2. Le disque de crema se remplit, comme une extraction qui monte. */
.disque {
  background: transparent;
  box-shadow: inset 0 0 0 1.5px var(--crema);
  transition: box-shadow .9s var(--sortie);
}
.sur-plein .disque, .plein .disque, .heros .disque, .bande__legende .disque, .film__legende .disque {
  box-shadow: inset 0 0 0 1.5px var(--crema-clair);
}
.js .disque { box-shadow: inset 0 0 0 1.5px var(--crema); }
.vu .disque, .vu.disque, .heros .disque { box-shadow: inset 0 0 0 .3em var(--crema); }
.plein .vu .disque, .plein .vu.disque, .heros .disque, .bande__legende .disque, .film__legende .disque { box-shadow: inset 0 0 0 .3em var(--crema-clair); }
html:not(.js) .disque { box-shadow: inset 0 0 0 .3em var(--crema); }
html:not(.js) .plein .disque, html:not(.js) .heros .disque { box-shadow: inset 0 0 0 .3em var(--crema-clair); }

/* 3. Les lignes d'un titre montent l'une après l'autre. Le script découpe,
   et sans lui le titre reste un titre ordinaire. */
.ligne { display: block; overflow: hidden; }
.ligne > span { display: block; transform: translateY(104%); transition: transform 1s var(--sortie); }
.ligne.vu > span, .vu .ligne > span { transform: none; }
.ligne:nth-child(2) > span { transition-delay: .07s; }
.ligne:nth-child(3) > span { transition-delay: .14s; }
.ligne:nth-child(4) > span { transition-delay: .21s; }

/* Parallaxe : le média dérive, le texte reste. */
.js [data-parallaxe] { will-change: transform; }

/* Survols : la photo respire dans son cadre, la ligne de carte avance. */
.galerie figure, .bande, .film { overflow: hidden; }
/* La vidéo porte width="360" en attribut, pour réserver sa place au
   chargement. Sans largeur en CSS, cet attribut devient un plancher : sur un
   écran de 320 px elle imposait 360 px à toute sa colonne, et la page se
   décalait de soixante pixels. */
.film video { width: 100%; height: auto; display: block; }
/* Un item de grille ne descend pas sous son contenu minimal : sans cela la
   vidéo imposait sa largeur d'attribut à toute la colonne. */
.duo > *, .pile > * { min-width: 0; }
/* Toute photo qui s'agrandit, au survol comme pendant sa révélation, est
   rognée par son cadre. Sans cela son échelle élargit la zone de défilement
   du document, et la page se décale de sept pixels sur le côté : invisible à
   l'œil, bien réel au doigt. Le clip-path de la révélation ne suffit pas, il
   masque le rendu sans réduire la boîte. On rogne avec clip et non hidden,
   qui ferait un conteneur de défilement et casserait les éléments collants. */
figure, .mosaique > *, .pile > * { overflow: clip; }
.galerie img { transition: transform 1.1s var(--sortie); }
.galerie figure:hover img { transform: scale(1.035); }
.js .bande[data-parallaxe] { height: clamp(320px, 62vh, 680px); }
.js .bande--haute[data-parallaxe] { height: clamp(420px, 86vh, 900px); }
.js .bande[data-parallaxe] img { height: 114%; position: relative; top: -7%; will-change: transform; }
.plat, .service, .grain { transition: background-color .5s var(--sortie); }
.plat__nom, .service__nom, .grain__nom { display: inline-block; transition: transform .45s var(--sortie); }
.plat:hover .plat__nom, .service:hover .service__nom, .grain:hover .grain__nom { transform: translateX(7px); }

/* Zoom lent sur le média du héros, façon Ken Burns. */
@keyframes respire { from { transform: scale(1); } to { transform: scale(1.07); } }
.js .heros__media img { animation: respire 22s var(--sortie) forwards; }

/* Entrée de page : le contenu se pose, il n'apparaît pas d'un coup. */
@keyframes arrivee { from { opacity: 0; } to { opacity: 1; } }
.js body { animation: arrivee .7s var(--sortie) both; }
.js body.part { opacity: 0; transition: opacity .32s var(--sortie); }

@media (prefers-reduced-motion: reduce) {
  .js [data-leve] { opacity: 1; transform: none; }
  .js figure[data-leve] img, .js .galerie [data-leve] img, .js .bande[data-leve] img { clip-path: none; transform: none; }
  .js .ligne > span { transform: none; }
  .js .heros__media img { animation: none; }
  .js body { animation: none; }
  .js body.part { opacity: 1; transition: none; }
  .js [data-parallaxe] { transform: none !important; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ---------- Petits écrans ---------- */

/* Sous 400 px, la barre porte trop : le bouton passe sur deux lignes et
   l'en-tête enfle à 73 px de haut. Le menu suffit, il contient le même lien. */
@media (max-width: 400px) {
  .entete { padding-inline: 16px; }
  .entete__nom { font-size: 23px; }
  .nav a.bouton { display: none; }
  .nav__menu { font-size: 15px; }
}

@media (max-width: 860px) {
  .nav a:not(.bouton) { display: none; }
  .nav__menu {
    display: inline-flex;
    align-items: center;
    position: relative;
    gap: 0.5em;
    background: none;
    border: 0;
    color: inherit;
    font: inherit;
    font-size: 14.5px;
    font-weight: 700;
    cursor: pointer;
    padding: 6px 0;
  }
  .entete.ouvert .nav { position: fixed; inset: 0; background: var(--espresso); color: var(--texte-sur-plein); flex-direction: column; justify-content: center; gap: var(--s-2); }
  .entete.ouvert .nav a:not(.bouton) { display: block; font-size: 30px; font-family: 'Clash Display', sans-serif; font-weight: 500; }
  .entete.ouvert .nav__menu { position: fixed; top: 18px; right: var(--marge); }
}

/* ---------- Écran couché : la hauteur commande, pas la largeur ----------
   Un iPhone couché fait 844 px de large pour 390 de haut. Une rupture écrite
   sur la seule largeur lui sert la mise en page d'une tablette, dans une
   hauteur qui ne la porte pas. */

@media (orientation: landscape) and (max-height: 560px) {
  :root {
    --s-5: clamp(44px, 11vh, 86px);
    --s-4: clamp(32px, 8vh, 60px);
    --s-3: clamp(24px, 6vh, 44px);
  }
  .heros { min-height: 100svh; }
  .heros h1 { font-size: clamp(2rem, 4.6vw, 3.2rem); max-width: 20ch; margin-bottom: 10px; }
  .heros .surtitre { margin-bottom: 10px; font-size: 13px; }
  .heros__appel { font-size: 15px; max-width: 58ch; margin-bottom: 16px; }
  .heros__contenu { padding-block: 16px 14px; }
  .heros__pied { padding-top: 12px; gap: 16px; }
  .heros__fil { display: none; }

  .scene { min-height: 100svh; }
  .scene .regle__mot { font-size: clamp(2.6rem, 7vw, 5rem); }
  .scene__contenu { padding-block: 24px; }

  .bande img, .bande--haute img { height: clamp(220px, 70vh, 420px); }
  /* Une hauteur imposée sans recadrage étire l'image : en paysage la vidéo
     passait d'un rapport de 0,56 à 1,21, visages écrasés. */
  .film video { height: clamp(200px, 64vh, 380px); object-fit: cover; }
  .titre-section { font-size: clamp(1.8rem, 3.4vw, 2.6rem); }
  .regle__mot { font-size: clamp(2.6rem, 8vw, 5.5rem); }
  .pied__nom { font-size: clamp(2.6rem, 8vw, 5rem); margin-block: var(--s-3) var(--s-2); }
  .galerie { grid-auto-rows: minmax(200px, auto); }
  /* La carte qui remonte sur le héros recouvrait son bouton : en hauteur
     contrainte, elle reste à sa place. */
  .chevauche { margin-top: 0; }
}

/* ---------- Plan du quartier ---------- */
/* Un terrain se montre bord à bord. Le dessin tient dans un SVG, les mots
   restent en HTML par-dessus : ils gardent leur taille quelle que soit
   l'échelle du plan, et un lecteur d'écran les lit. */

.plan-section { padding-block: var(--s-4) 0; background: var(--fond-plein); color: var(--texte-sur-plein); }
.plan-section .surtitre { color: #D8C9BA; }
.plan-section .titre-section { color: var(--texte-sur-plein); margin-bottom: var(--s-3); }

.plan { margin: 0; line-height: 0; }
.plan__cadre { position: relative; }
.plan img { width: 100%; height: auto; display: block; border-radius: 0; }

.plan__mot {
  position: absolute;
  left: var(--x);
  top: var(--y);
  line-height: 1.25;
  font-size: clamp(12.5px, 1.05vw, 16px);
  letter-spacing: 0.02em;
  color: #EDE4DA;
  text-shadow: 0 1px 10px rgba(18, 12, 8, .9), 0 0 22px rgba(18, 12, 8, .7);
  pointer-events: none;
  white-space: nowrap;
}
.plan__mot--lieu {
  font-family: 'Clash Display', sans-serif;
  font-weight: 600;
  font-size: clamp(16px, 1.9vw, 30px);
  color: var(--crema-clair);
  letter-spacing: 0.01em;
}
.plan__mot--rue { color: #B5A79A; font-size: clamp(12px, 0.92vw, 14px); letter-spacing: 0.09em; text-transform: uppercase; }
.plan__mot--marche { color: #EDE4DA; font-weight: 500; }
.plan__mot--metro { color: #EDE4DA; font-weight: 500; }

.plan__echelle {
  position: absolute;
  left: 4%;
  bottom: 8.6%;
  font-size: clamp(12px, 0.85vw, 13px);
  letter-spacing: 0.08em;
  color: #9B9A96;
  pointer-events: none;
}

.plan figcaption {
  line-height: 1.5;
  padding: 16px var(--marge) var(--s-4);
  color: var(--texte-sur-plein-2);
  background: var(--fond-plein);
  flex-wrap: wrap;
}
.plan__lien { color: var(--crema-clair); margin-left: 0.5em; position: relative; display: inline-block; }
.plan__lien::before { content: ''; position: absolute; inset: -13px -10px; min-height: 46px; top: 50%; translate: 0 -50%; }

/* Sur un écran étroit le plan rétrécit mais les mots gardent leur corps :
   les noms de rue passeraient sur le dessin. On ne garde que ce qui situe. */
@media (max-width: 760px) {
  .plan__mot--rue { display: none; }
  .plan__mot--metro { white-space: normal; max-width: 42%; }
}

/* Portrait court : un téléphone de 568 ou 640 px de haut. Le minimum du clamp
   du titre l'emporte sur la largeur disponible, « Le matin commence ici. »
   passe sur trois lignes, et le héros dépasse de 181 px avec son appel sous
   le pli. La rupture regarde donc la hauteur, pas seulement la largeur. */
@media (orientation: portrait) and (max-height: 700px) {
  .heros h1 { font-size: clamp(2.2rem, 11vw, 3.1rem); max-width: 17ch; margin-bottom: 10px; }
  .heros .surtitre { margin-bottom: 8px; font-size: 12.5px; }
  .heros__appel { font-size: 15px; margin-bottom: 14px; }
  .heros__contenu { padding-block: 24px 18px; }
  .heros__pied { padding-top: 12px; gap: 14px; }
  .heros__fil { display: none; }
}
