/* ==========================================================================
   Two Padel - les animations de la page restaurant
   Chargee par restaurant.html seule, apres styles.css. Le script qui l'anime
   est assets/anim/restaurant.js. Mis au point dans tests-animations/
   (restaurant-fidele.html), valide et publie par le client le 7 octobre 2026.

   Demande du client le 7 octobre 2026 : la page restaurant actuelle, a
   l'identique, avec des animations au defilement, « comme pour la page
   d'accueil ». Les regles sont celles de l'accueil (assets/anim/accueil.css) :
   1. textes et titres intouchables, au caractere pres : on n'ajoute que des
      attributs, des enveloppes et des illustrations masquees aux lecteurs
      d'ecran (le tampon de la salle, la boite a pizza) ;
   2. le fond reste continu, et la page reste dans son chapitre clair ;
   3. les boutons gardent le soulevement du site ;
   4. pas de rideau sur les photos ni sur la carte.
   Et les lecons de la premiere version restaurant, refusee le 29 septembre
   2026 (« travail bacle, transitions pas belles, information diluee ») :
   rien d'epingle, aucune section ajoutee, aucun dessin a la place des photos.
   Chaque mouvement porte un contenu qui est deja sur la page.

   Les mouvements sont ceux de l'accueil, pour que le site parle une seule
   langue : la capsule qui flotte, la photo qui se pose, les prix qui montent,
   les cartes qui tombent, les mots soulignes, la liste cochee et son tampon,
   la cascade des horaires, les etoiles.

   Sans JavaScript ou sous prefers-reduced-motion, rien ne bouge et chaque
   bloc montre son etat final, celui du HTML : les etats de depart ne
   s'appliquent que sous html.nr, posee par le script.
   ========================================================================== */

:root {
  --spring: cubic-bezier(.2, 1.6, .35, 1);
  --doux: cubic-bezier(.2, .8, .2, 1);
}
.nr-n { font-style: normal; }

/* ======================================================= premier ecran */
/* « tout le monde » flotte dans une capsule de verre clair, comme « 20 min »
   sur l'accueil : trois mouvements independants (monter, deriver, pencher)
   sur des durees qui ne se recoupent pas. Bleu de charte sur blanc : 3,6:1,
   au-dessus du seuil de 3:1 des grands titres (le titre fait au moins 35 px).
   Aucun flou : un flou sur un element qui bouge sans arret se recalcule a
   chaque image (lecon de l'accueil, 6 octobre 2026). Le fond est plus dense
   a la place. */
.hero-s h1 em {
  display: inline-block;
  padding: .09em .17em .04em; line-height: 1; border-radius: .3em;
  background: rgba(255, 255, 255, .92);
  border: 1px solid rgba(0, 134, 255, .35);
  box-shadow: 0 16px 40px rgba(6, 26, 46, .14), inset 0 1px 0 #ffffff;
  rotate: -2deg;
  animation: nr-fy 2.9s ease-in-out infinite alternate, nr-fx 4.3s ease-in-out infinite alternate, nr-fr 3.7s ease-in-out infinite alternate;
}
@keyframes nr-fy { from { translate: 0 .03em; } to { translate: 0 -.06em; } }
@keyframes nr-fx { from { transform: translateX(-.025em); } to { transform: translateX(.03em); } }
@keyframes nr-fr { from { rotate: -3deg; } to { rotate: -.6deg; } }

/* La photo de la salle se pose (leger recul), comme celles du premier ecran
   de l'accueil. Aucune teinte ni aucun rideau : seule l'echelle bouge. Le
   remplissage « backwards » lache l'image une fois l'animation jouee. */
html.nr .hero-s .frame img { animation: nr-pose 1.9s var(--doux) backwards; }
@keyframes nr-pose { from { transform: scale(1.07); } to { transform: none; } }

/* Le point vert du service en cours bat : c'est ouvert, la, maintenant. Un
   anneau qui s'elargit et s'efface, porte par un pseudo-element : seules
   l'echelle et l'opacite bougent. La pastille n'est pas en verre floute, donc
   le battement ne force aucun flou a se recalculer. */
.status i { position: relative; }
html.nr .status[data-state="open"] i::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: #23c552;
  animation: nr-pouls 2.2s ease-out infinite;
}
@keyframes nr-pouls {
  from { transform: scale(1); opacity: .55; }
  70%, to { transform: scale(3.2); opacity: 0; }
}
/* Pendant que la souris bouge, ce qui bouge sans arret s'arrete, et repart
   une seconde apres (html.souris, pose par le script) : la lueur qui suit le
   curseur garde ainsi toute sa fluidite. */
html.souris .hero-s h1 em,
html.souris .status[data-state="open"] i::after { animation-play-state: paused; }

/* ===================================================== mots soulignes */
/* Le mot en avant de chaque titre de section recoit un trait bleu qui se
   tire de gauche a droite quand le titre arrive. */
html.nr .band h2 em {
  background: linear-gradient(var(--blue), var(--blue)) 0 100% / 0% 3px no-repeat;
  padding-bottom: .03em;
  transition: background-size 1s var(--doux) .35s;
}
html.nr .band h2.nr-trait em { background-size: 100% 3px; }

/* ===================================================== les familles */
/* Les quatre familles de la carte tombent l'une apres l'autre, en ressort et
   legerement de biais, comme les cartes de l'accueil. Le script leur retire
   la revelation ordinaire du site, pour que les deux ne se marchent pas
   dessus. */
html.nr .taste[data-vu] > .taste-cat {
  transition: opacity .45s var(--doux), transform 1s var(--spring);
  transition-delay: calc(var(--i, 0) * 90ms);
}
html.nr .taste[data-vu]:not(.vu) > .taste-cat {
  opacity: 0;
  transform: translate(var(--cx, 0), 70px) rotate(var(--cr, 5deg)) scale(.88);
}
.taste > :nth-child(odd) { --cr: 6deg; --cx: -30px; }
.taste > :nth-child(even) { --cr: -5deg; --cx: 30px; }
/* Sur telephone, une carte par ligne : elles montent sans venir de cote, et
   penchent a peine. Venues de cote, elles depasseraient l'ecran le temps de
   leur arrivee (meme lecon que le tableau des creneaux de l'accueil). */
@media (max-width: 760px) {
  .taste > :nth-child(n) { --cr: 2deg; --cx: 0px; }
}

/* ======================================= LA SALLE, COCHEE LIGNE A LIGNE */
/* Chaque ligne se coche, puis le tampon « Ouvert à tous » tombe sur la liste.
   Repris de la liste du complexe, sur l'accueil. On ne raye rien : ce sont
   des atouts, pas des corvees. */
.spec { position: relative; }
.spec.is-live .spec-row { position: relative; }
.spec.is-live .spec-row::after {
  content: ""; position: absolute; left: 15px; top: calc(var(--s-3) - 10px);
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--blue) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23001628' stroke-width='3.4' stroke-linecap='square'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5'/%3E%3C/svg%3E") center / 12px no-repeat;
  box-shadow: 0 0 0 3px var(--ground);
  transform: scale(0); transition: transform .5s var(--spring);
}
.spec.is-live .spec-row.done::after { transform: scale(1); }
.spec-stamp {
  position: absolute; right: 0; bottom: -30px; z-index: 3;
  display: inline-flex; align-items: center; gap: 10px;
  padding: 9px 20px 9px 9px; border-radius: 999px;
  background: rgba(0, 22, 40, .86); color: #ffffff;
  border: 1px solid rgba(255, 255, 255, .2);
  font-family: var(--font-head); font-weight: 800; font-variation-settings: "wdth" 78;
  font-size: clamp(1rem, 1.9vw, 1.45rem); letter-spacing: .01em; line-height: 1;
  text-transform: uppercase; white-space: nowrap;
  box-shadow: 0 0 0 3px var(--blue), 0 0 40px rgba(0, 134, 255, .35), 0 26px 50px -16px rgba(6, 26, 46, .45);
  transform: rotate(-7deg);
}
.spec-stamp i {
  display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%;
  background: var(--blue); color: #001628;
}
.spec-stamp .ico { width: 20px; height: 20px; }
.spec-stamp b { font: inherit; }
/* Le tampon grossit depuis son bord droit, colle a celui de la page : agrandi
   depuis son centre, il deborderait et creerait un defilement lateral. */
.spec.is-live .spec-stamp {
  transform-origin: 92% 50%;
  opacity: 0; transform: scale(1.7) rotate(0deg);
  transition: opacity .2s, transform .5s cubic-bezier(.22, 1.4, .36, 1);
}
.spec.is-live .spec-stamp.on { opacity: 1; transform: scale(1) rotate(-7deg); }
/* Le tampon deborde sous la liste : l'ecart ordinaire avant les photos
   (38 a 62 px) le laissait a 4 px du premier cadre sur telephone, et le
   faisait mordre dessus a 900 px. A 80 px, il en reste une trentaine a toutes
   les largeurs (74 px pour la liste du complexe, sur l'accueil). La mosaique
   porte sa marge en style en ligne, d'ou !important ; la regle ne vaut que
   la ou le tampon existe. */
.spec[data-coche] + .mosaic { margin-top: 80px !important; }
@media (max-width: 600px) {
  .spec-stamp { right: 4px; bottom: -34px; font-size: .9rem; padding: 7px 14px 7px 7px; }
  .spec-stamp i { width: 28px; height: 28px; }
  .spec-stamp .ico { width: 16px; height: 16px; }
}

/* ================================================= LA BOITE A PIZZA ==== */
/* Redemandee par le client le 7 octobre 2026 (« j'aimais bien la boite a
   pizza », vue dans la version du 29 septembre). Une illustration masquee
   aux lecteurs d'ecran, posee a cote du texte de la section : aucun mot de la
   page ne change. Une vraie pizza de la maison, vue de haut (IMG_6173,
   detouree par tests-animations/detourer-pizza.py, sans aucune trace
   d'assiette, assets/img/pizza-a-emporter.webp), tombe dans
   la boite ouverte a son arrivee. Quand la section passe le centre de
   l'ecran, c'est le point de bascule : le script pose .ferme, le couvercle
   se rabat d'un geste, puis le tampon « A emporter » tombe ; en remontant,
   la boite se rouvre. Sans JavaScript, elle reste ouverte, pizza visible,
   sans tampon. */
.nr-emporter { display: grid; gap: var(--s-5); align-items: center; }
@media (min-width: 900px) {
  .nr-emporter { grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); }
  /* Le texte garde ses deux tiers de page : la regle des deux tiers ne
     s'applique pas une seconde fois a l'interieur de sa colonne. */
  .nr-emporter .band-head { max-width: none; }
}
.nr-boite-zone { display: grid; place-items: center; padding: 10px 0; }
/* La boite suit aussi la hauteur de l'ecran : au point de bascule, elle doit
   tenir entiere, ouverte, entre l'en-tete et le bas. A 500 px sur un
   portable de 600 px utiles, elle n'y tenait pas (client, 7 octobre 2026).
   svh : la hauteur avec les barres du navigateur, sur telephone. */
.boite {
  position: relative; aspect-ratio: 1 / 2;
  width: min(250px, 24vw, 32vh);
  width: min(250px, 24vw, 32svh);
  perspective: 1300px;
}
@media (max-width: 899px) {
  .boite { width: min(210px, 52vw, 30vh); width: min(210px, 52vw, 30svh); }
}
.bt-base {
  position: absolute; left: 0; right: 0; bottom: 0; height: 50%;
  border-radius: 8px; background: #0b2a4a;
  box-shadow: inset 0 0 0 7px #001628, inset 0 0 0 8px rgba(255, 255, 255, .1), 0 26px 50px -22px rgba(0, 22, 40, .6);
}
.bt-pizza { position: absolute; z-index: 1; left: 6%; right: 6%; bottom: 3%; }
.bt-pizza > img { display: block; width: 100%; height: auto; filter: drop-shadow(0 10px 14px rgba(0, 0, 0, .45)); }
html.nr .nr-boite-zone .bt-pizza { transition: opacity .5s, transform 1.1s cubic-bezier(.3, 1.3, .5, 1) .2s; }
html.nr .nr-boite-zone:not(.vu) .bt-pizza { opacity: 0; transform: translateY(-40%) scale(1.15) rotate(-14deg); }
/* Ouvert, le couvercle est rabattu vers le haut (180 degres) ; ferme, il
   recouvre la pizza. Le geste prend 0,9 s, lent au depart, comme une main
   qui rabat un carton. */
.bt-lid {
  position: absolute; z-index: 2; left: 0; right: 0; bottom: 0; height: 50%;
  transform-origin: 50% 0; transform: rotateX(180deg);
  transform-style: preserve-3d;
  transition: transform .9s cubic-bezier(.55, 0, .25, 1);
}
html.nr .boite.ferme .bt-lid { transform: rotateX(0deg); }
.bt-in, .bt-out {
  position: absolute; inset: 0; border-radius: 8px;
  -webkit-backface-visibility: hidden; backface-visibility: hidden;
}
/* L'interieur du couvercle, visible boite ouverte : imprime comme une vraie
   boite, pour ne pas laisser un grand aplat sombre au-dessus de la pizza. */
.bt-in {
  display: grid; place-content: center; justify-items: center; gap: 6px;
  transform: rotateX(180deg);
  background-color: #0b2a4a;
  background-image:
    repeating-linear-gradient(0deg, rgba(255, 255, 255, .05) 0 1px, transparent 1px 18px),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, .05) 0 1px, transparent 1px 18px);
  box-shadow: inset 0 0 0 7px #001628, inset 0 0 0 8px rgba(255, 255, 255, .1);
}
.bt-in b {
  font-family: var(--font-h1); font-weight: 400; text-transform: uppercase;
  font-size: clamp(1.3rem, 2vw, 1.7rem); line-height: .9; letter-spacing: -.01em;
  color: #ffffff; text-align: center;
}
.bt-in small {
  font-family: var(--font-head); font-weight: 800; font-size: .54rem;
  letter-spacing: .22em; text-transform: uppercase; color: var(--blue-clair);
}
/* le logo dans le haut du couvercle : le bas reste libre pour le tampon */
.bt-out {
  display: grid; align-content: start; justify-content: center; justify-items: center; gap: 10px;
  padding-top: 24%;
  background-color: #001628;
  background-image:
    radial-gradient(90% 70% at 70% 20%, rgba(0, 134, 255, .35), transparent 70%),
    repeating-linear-gradient(0deg, rgba(255, 255, 255, .06) 0 1px, transparent 1px 18px),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, .06) 0 1px, transparent 1px 18px);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .16), 0 22px 44px -20px rgba(0, 22, 40, .6);
}
.bt-out img { width: 58%; height: auto; }
.bt-out small {
  font-family: var(--font-head); font-weight: 800; font-size: .56rem;
  letter-spacing: .22em; text-transform: uppercase; color: rgba(255, 255, 255, .8);
}
.bt-tampon {
  position: absolute; z-index: 3; left: 50%; bottom: 6%; translate: -50% 0;
  padding: 9px 16px; border-radius: 999px; white-space: nowrap;
  background: var(--blue); color: #001628;
  font-family: var(--font-head); font-weight: 800; font-size: .82rem;
  letter-spacing: .08em; text-transform: uppercase;
  box-shadow: 0 0 0 3px #001628, 0 18px 36px -12px rgba(0, 22, 40, .6);
  transform: rotate(-8deg);
  transition: opacity .2s, transform .5s cubic-bezier(.22, 1.4, .36, 1);
}
html.nr .boite:not(.ferme) .bt-tampon { opacity: 0; transform: scale(1.9) rotate(0deg); }
/* le tampon attend que le couvercle soit rabattu ; il part tout de suite a
   la reouverture (le retard ne vaut que vers l'etat ferme) */
html.nr .boite.ferme .bt-tampon { transition-delay: .8s; }
/* sans JavaScript, la boite reste ouverte : pas de tampon sur la pizza */
html:not(.nr) .bt-tampon { display: none; }

/* ========================================================= les horaires */
/* Les jours arrivent en cascade, comme les horaires de l'accueil, puis les
   services ouverts s'allument : le midi, puis le soir, jour apres jour. */
html.nr .service[data-vu] .service-row { transition: opacity .4s, transform .6s var(--doux); transition-delay: calc(var(--i, 0) * 60ms); }
html.nr .service[data-vu]:not(.vu) .service-row { opacity: 0; transform: translateX(-18px); }
.service-row > span:nth-child(3) { --j: 1; }
html.nr .service[data-vu] .service-cell.on i {
  transition: transform .5s var(--spring);
  transition-delay: calc(var(--i, 0) * 60ms + var(--j, 0) * 140ms + 420ms);
}
html.nr .service[data-vu]:not(.vu) .service-cell.on i { transform: scale(0); }

/* ============================================================ les avis */
/* Les cinq etoiles du bouton s'allument l'une apres l'autre. */
html.nr .avis-entete[data-vu] .stars .ico { transition: transform .5s var(--spring); transition-delay: calc(var(--i, 0) * 90ms + 300ms); }
html.nr .avis-entete[data-vu]:not(.vu) .stars .ico { transform: scale(0) rotate(-40deg); }

/* ============================================= mouvements reduits ===== */
@media (prefers-reduced-motion: reduce) {
  .hero-s h1 em { animation: none; }
}
