/* ============================================================
   L'ACCROCHE — haut de page.

   Le bloc de réservation change d'état par UNE seule technique :
   des rails masqués dans lesquels les couches glissent
   verticalement. Jamais un fondu, jamais une opacité qui part
   de zéro, jamais une propriété qui touche à la mise en page.

   Chaque rail est une grille où toutes les couches occupent la
   même cellule : sa hauteur est celle de la couche la plus haute
   et ne change donc JAMAIS d'un état à l'autre. Aucun recalcul.
   ============================================================ */

.accroche{
  min-block-size:var(--plein-ecran);
  display:flex; align-items:center;
  padding-block:calc(var(--entete-h) + var(--e-8)) var(--e-12);
}

.accroche__grille{
  display:grid;
  gap:var(--e-12);
  inline-size:100%;
  align-items:center;
}
@media (min-width:1040px){
  .accroche__grille{
    grid-template-columns:minmax(0,1fr) minmax(0,430px);
    gap:var(--e-16);
  }
}

/* ---------- Le titre remplit l'écran ---------- */
.accroche__titre{
  font-size:var(--fs-ecran);
  line-height:var(--lh-ecran);
  letter-spacing:var(--ls-ecran);
  margin-block:var(--e-6) var(--e-8);
  max-width:14ch;
}

/* ============================================================
   LE BLOC — le site du restaurant, éclairé sur l'encre.
   ============================================================ */
.bloc{
  background:var(--bg-leve);
  border:var(--trait) solid var(--rule);
  border-radius:var(--r-4);
  overflow:hidden;
  /* L'objet est éclairé : une lueur très basse, pas une ombre portée. */
  box-shadow:0 0 0 1px rgba(242,241,236,.03), 0 24px 60px -30px rgba(0,0,0,.9);
  transition:transform var(--t-entree) var(--courbe);
}
/* Au moment de la réparation, le bloc se redresse très légèrement. */
.bloc[data-etat="repare"], .bloc[data-etat="confirme"]{ transform:translateY(calc(var(--e-1) * -1)) }

.bloc__tete{
  display:flex; align-items:center; gap:var(--e-3);
  padding:var(--e-3) var(--e-4);
  border-block-end:var(--trait) solid var(--rule);
  background:var(--bg-creux);
}
.bloc__pastille{
  inline-size:var(--e-2); block-size:var(--e-2); flex:none;
  border-radius:var(--r-rond); background:var(--rule-fort);
}
.bloc__url{
  font-family:var(--font-mono); font-size:var(--fs-nano);
  color:var(--ink-3);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}

.bloc__corps{
  padding:var(--e-6);
  display:flex; flex-direction:column; gap:var(--e-5);
}

.bloc__nom{
  font-family:var(--font-titre);
  font-weight:var(--fw-gras);
  font-size:var(--fs-h3);
  letter-spacing:var(--ls-titre);
}

/* ---------- Le rail : la seule technique du site ---------- */
.rail{
  display:grid;
  overflow:hidden;
  /* Le masque doit dépasser un peu pour ne pas rogner les lettres. */
  margin-inline:calc(var(--e-1) * -1);
  padding-inline:var(--e-1);
}
.rail__couche{
  grid-area:1 / 1;
  /* Repos : la couche attend SOUS le masque, pleinement opaque. */
  transform:translateY(101%);
  transition:transform var(--t-etat) var(--courbe);
  min-width:0;
}
.rail__couche[data-actif]{ transform:none }
.rail__couche[data-passe]{ transform:translateY(-101%) }

/* Les couches inactives ne sont ni cliquables ni annoncées : sans cela,
   un lecteur d’écran lit les quatre états du bloc à la suite. */
.rail__couche:not([data-actif]){ pointer-events:none }

/* ---------- Rail 1 : l'information ---------- */
.rail--info{ font-size:var(--fs-small); color:var(--ink-2) }
.rail--info .rail__couche{ display:flex; align-items:center; gap:var(--e-2) }

/* ---------- Rail 2 : le module ---------- */
.rail--module .rail__couche{ display:flex; flex-direction:column; gap:var(--e-3) }

/* La carte du restaurant — état cassé */
.carte-ligne{
  display:flex; align-items:baseline; gap:var(--e-3);
  font-size:var(--fs-small);
  padding-block:var(--e-2);
  border-block-end:var(--trait) solid var(--rule);
}
.carte-ligne:last-child{ border-block-end:0 }
.carte-ligne__nom{ flex:1; min-width:0; color:var(--ink-2) }
.carte-ligne__prix{ font-family:var(--font-mono); font-size:var(--fs-micro); color:var(--ink-3) }

/* L'impasse — état impasse */
.impasse{
  display:flex; flex-direction:column; gap:var(--e-2);
  padding:var(--e-4);
  border:var(--trait) dashed var(--rule-fort);
  border-radius:var(--r-2);
  background:var(--bg-creux);
}
.impasse__quoi{ font-size:var(--fs-small); color:var(--ink-2) }
.impasse__tel{
  font-family:var(--font-mono); font-size:var(--fs-h3);
  font-variant-numeric:tabular-nums;
  color:var(--ink);
}

/* Les créneaux — état réparé */
.creneaux{
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(66px, 1fr));
  gap:var(--e-2);
}
.creneau{
  min-block-size:var(--tap-min);
  display:grid; place-items:center;
  border:var(--trait) solid var(--rule-fort);
  border-radius:var(--r-2);
  background:var(--bg-creux);
  font-family:var(--font-mono);
  font-size:var(--fs-micro);
  font-variant-numeric:tabular-nums;
  color:var(--ink-2);
  transition:transform var(--t-reaction) var(--courbe),
             opacity var(--t-reaction) var(--courbe);
}
.creneau:hover:not(:disabled){ transform:translateY(-1px) }
.creneau:active:not(:disabled){ transform:translateY(0) }
.creneau[aria-pressed="true"]{
  background:var(--ink); color:var(--bg); border-color:var(--ink);
}
.creneau:disabled{ opacity:.34; cursor:not-allowed }
.creneau__h{ pointer-events:none }

/* ---------- Rail 3 : le libellé du bouton ---------- */
.bloc__action{
  inline-size:100%;
  min-block-size:var(--tap-min);
  display:grid; place-items:center;
  border-radius:var(--r-2);
  border:var(--trait) solid var(--rule-fort);
  background:var(--bg-creux);
  font-family:var(--font-titre);
  font-weight:var(--fw-gras);
  font-size:var(--fs-small);
  transition:transform var(--t-reaction) var(--courbe),
             opacity var(--t-reaction) var(--courbe),
             background-color var(--t-etat) var(--courbe),
             border-color var(--t-etat) var(--courbe),
             color var(--t-etat) var(--courbe);
  padding-inline:var(--e-4);
}
.bloc__action:active{ transform:translateY(1px) }

/* ---------- L'appel au clic ----------
   Rien de toute la page ne se produit si personne ne touche ce bouton.
   Il doit donc se signaler — sans un mot de plus, la page en a déjà
   assez. Un halo qui respire, et qui s'éteint DÉFINITIVEMENT au premier
   geste : une fois qu'on a compris, l'insistance devient du bruit.

   Seuls l'opacité et la transformation sont animées : le compositeur
   s'en charge, la boucle ne coûte rien au fil principal. */
.bloc__action{ position:relative }
.bloc__action::after{
  content:"";
  position:absolute; inset:calc(var(--trait) * -1);
  border-radius:inherit;
  border:var(--trait) solid var(--ink);
  opacity:0;
  pointer-events:none;
}
.bloc[data-etat="casse"]:not([data-touche]) .bloc__action::after{
  animation:appel var(--t-appel) var(--courbe) infinite;
}
@keyframes appel{
  0%  { opacity:0;   transform:scale(1) }
  30% { opacity:.5 }
  100%{ opacity:0;   transform:scale(1.07) }
}

/* Mouvement réduit : l'anneau reste, il cesse simplement de respirer.
   L'indication ne doit pas disparaître avec l'animation. */
@media (prefers-reduced-motion: reduce){
  .bloc[data-etat="casse"]:not([data-touche]) .bloc__action::after{
    animation:none;
    opacity:.45;
  }
}
/* Le bouton mort : présent, cliquable, mais il ne mène nulle part. */
.bloc[data-etat="impasse"] .bloc__action{ color:var(--ink-3); cursor:default }
/* Le bouton vivant. */
.bloc[data-etat="repare"] .bloc__action,
.bloc[data-etat="confirme"] .bloc__action{
  background:var(--ink); color:var(--bg); border-color:var(--ink);
}
.bloc__action:disabled{ opacity:.5 }

/* ---------- Rail 4 : le pied du bloc ---------- */
.rail--pied{ font-size:var(--fs-micro); color:var(--ink-3) }
.rail--pied .rail__couche{ display:flex; align-items:center; gap:var(--e-3); flex-wrap:wrap }

/* ---------- Reprise ---------- */
.bloc__reprise{
  display:flex; justify-content:flex-end;
  margin-block-start:var(--e-3);
}
.bloc__reprise button{
  min-block-size:var(--tap-min);
  padding-inline:var(--e-3);
  font-family:var(--font-mono);
  font-size:var(--fs-nano);
  letter-spacing:var(--ls-caps);
  text-transform:uppercase;
  color:var(--ink-3);
  transition:opacity var(--t-reaction) var(--courbe);
}
.bloc__reprise button:hover{ opacity:.7 }
/* La reprise n'existe qu'une fois la séquence jouée. */
.bloc__reprise{ visibility:hidden }
.bloc[data-etat="repare"] ~ .bloc__reprise,
.bloc[data-etat="confirme"] ~ .bloc__reprise,
.bloc[data-etat="impasse"] ~ .bloc__reprise{ visibility:visible }

/* ============================================================
   LE MOMENT DE LA RÉPARATION
   C'est le point le plus important de la page. Les créneaux ne
   surgissent pas d'un bloc : ils se posent l'un après l'autre,
   en cascade, pendant que la couche finit d'arriver. Le module
   a l'air de s'assembler.

   Uniquement transform. Aucune opacité qui part de zéro : au
   repos, un créneau est déjà entièrement opaque, simplement
   décalé et très légèrement réduit.
   ============================================================ */
.creneau{
  transform:translateY(var(--e-2)) scale(.94);
  transition:transform var(--t-etat) var(--courbe);
}
/* La cascade ne se déclenche qu'au moment de la réparation. */
.bloc[data-etat="repare"] .creneau,
.bloc[data-etat="confirme"] .creneau{
  transform:none;
  transition-delay:calc(var(--i, 0) * var(--cascade));
}
/* Le survol et la sélection reprennent la main sans à-coup. */
.bloc[data-etat="repare"] .creneau:hover:not(:disabled){
  transform:translateY(-1px);
  transition-delay:0ms;
}
.bloc[data-etat="repare"] .creneau[aria-pressed="true"]{
  transform:none;
  transition-delay:0ms;
}

/* Le bloc se redresse et s'éclaire un peu au moment où il repart. */
.bloc{ transition:transform var(--t-entree) var(--courbe) }
.bloc[data-etat="repare"],
.bloc[data-etat="confirme"]{
  transform:translateY(calc(var(--e-1) * -1));
}
