/* ==========================================================================
   Menu — l'écran d'accueil après le hero
   Registre éditorial : fond crème, angles droits, filets d'un pixel, aucune
   ombre portée. Les entrées n'ont pas le même poids, donc pas la même
   surface. Le RSVP est la seule action primaire et le seul aplat rouge.
   ========================================================================== */

.menu {
  position: relative;
  min-height: 100dvh;
  padding: clamp(3rem, 9vh, 6rem) var(--gutter) clamp(4rem, 10vh, 7rem);
  background: var(--cream);
  overflow: hidden;
}

/* Le verre a besoin de quelque chose derrière lui, sinon il n'est qu'un
   rectangle plus clair. Le paysage revient donc ici, délavé jusqu'au crème :
   la page reste blanc cassé, mais les tuiles ont matière à filtrer.
   Pour un fond parfaitement uni, supprimer ce bloc. */
.menu::before {
  content: "";
  position: absolute;
  inset: -2%;
  background-image: url("../img/fond.jpg");
  background-size: cover;
  background-position: center 45%;
  filter: saturate(0.14) brightness(1.34) blur(3px) sepia(0.16);
  opacity: 0.28;
  pointer-events: none;
}

.menu__inner {
  position: relative;
  z-index: 1;
  max-width: var(--max-w);
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: clamp(2.5rem, 6vh, 4.5rem);
}

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

.menu__head {
  text-align: center;
}

.menu__names {
  font-family: var(--font-display);
  font-size: var(--t-2xl);
  line-height: 1.02;
  color: var(--accent);
}

.menu__meta {
  margin-top: var(--s-3);
  font-size: var(--t-sm);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* --- Compte à rebours ------------------------------------------------------
   Un tableau d'affichage d'aéroport : chaque chiffre est un volet qui fait
   défiler la série 0-9 avant de s'arrêter sur sa valeur. Les volets
   s'immobilisent de gauche à droite, comme sur les vrais panneaux.
   --------------------------------------------------------------------------- */

.countdown {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  margin-top: var(--s-5);
  color: var(--ink-soft);
  font-size: var(--t-sm);
}

.countdown__flaps {
  display: inline-flex;
  gap: 3px;
}

.flap {
  --flap-h: 2.6rem;
  position: relative;
  display: block;
  width: 1.7rem;
  height: var(--flap-h);
  overflow: hidden;
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background: var(--white);
  font-size: 1.45rem;
  font-weight: 700;
  line-height: var(--flap-h);
  text-align: center;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* La charnière : le trait qui fait lire la case comme un volet et non comme
   une simple boîte. */
.flap::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1px;
  background: var(--line);
  z-index: 1;
  pointer-events: none;
}

.flap__strip {
  display: block;
  will-change: transform;
}

.flap__strip span {
  display: block;
  height: var(--flap-h);
}

.countdown__label {
  max-width: 12ch;
  line-height: 1.25;
}

/* --- Grille ---------------------------------------------------------------
   Des dalles de verre séparées par un interstice : le paysage délavé passe
   entre elles, ce qui donne au flou quelque chose à filtrer.

   Éclairage : un seul point lumineux, en coordonnées viewport (--x / --y,
   écrits sur :root par menu.js). Les fonds sont en background-attachment:
   fixed, donc le point ne bouge pas d'une dalle à l'autre : c'est la même
   lampe qui balaie toute la grille, et chaque dalle n'en révèle que la part
   qui la traverse. C'est ce qui distingue cet effet d'un halo par carte.
   ------------------------------------------------------------------------- */

.menu__grid {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: clamp(0.5rem, 1vw, 0.75rem);
}

.tile {
  /* Réglages de la lampe, par dalle. La lumière est blanche : un point rouge
     suivant le curseur se lisait comme un halo collé à la souris, pas comme
     un reflet sur du verre. Le rouge reste réservé aux textes et à la case
     Répondre. */
  --border-size: 1.5px;
  --spot: 300px;
  --spot-fill: rgba(255, 255, 255, 0.5);
  --spot-edge: rgba(255, 255, 255, 1);
  --spot-light: rgba(255, 255, 255, 0.9);
  --tile-bg: rgba(253, 250, 243, 0.45);

  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-3);
  min-height: 11rem;
  padding: clamp(1.25rem, 2.4vw, 1.85rem);
  border: var(--border-size) solid rgba(255, 255, 255, 0.5);
  border-radius: var(--r-lg);
  color: var(--ink);
  text-align: left;
  text-decoration: none;

  background-color: var(--tile-bg);
  background-image: radial-gradient(
    var(--spot) var(--spot) at calc(var(--x, 0) * 1px) calc(var(--y, 0) * 1px),
    var(--spot-fill),
    transparent 72%
  );
  background-attachment: fixed;
  background-repeat: no-repeat;
  background-size: calc(100% + (2 * var(--border-size)))
    calc(100% + (2 * var(--border-size)));
  background-position: 50% 50%;

  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9),
    inset 0 -1px 0 rgba(90, 26, 16, 0.08);
  backdrop-filter: blur(26px) saturate(135%) brightness(1.06);
  -webkit-backdrop-filter: blur(26px) saturate(135%) brightness(1.06);
  transition: background-color var(--d-base) var(--ease-out-quart),
    box-shadow var(--d-base) var(--ease-out-quart);
}

/* Les deux liserés éclairés. Le masque ne laisse voir le dégradé que dans
   l'épaisseur de la bordure : la zone « border-box » moins la zone
   « padding-box ». */
.tile::before,
.tile::after {
  content: "";
  position: absolute;
  pointer-events: none;
  inset: calc(var(--border-size) * -1);
  border: var(--border-size) solid transparent;
  border-radius: inherit;
  background-attachment: fixed;
  background-repeat: no-repeat;
  background-size: calc(100% + (2 * var(--border-size)))
    calc(100% + (2 * var(--border-size)));
  background-position: 50% 50%;
  -webkit-mask: linear-gradient(#fff, #fff) padding-box,
    linear-gradient(#fff, #fff) border-box;
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff, #fff) padding-box,
    linear-gradient(#fff, #fff) border-box;
  mask-composite: exclude;
  transition: opacity var(--d-base) var(--ease-out-quart);
}

/* Le liseré rouge, cœur de la lampe. */
.tile::before {
  background-image: radial-gradient(
    calc(var(--spot) * 0.75) calc(var(--spot) * 0.75) at
      calc(var(--x, 0) * 1px) calc(var(--y, 0) * 1px),
    var(--spot-edge),
    transparent 100%
  );
  opacity: 0.55;
}

/* Le cœur blanc, plus resserré : c'est lui qui donne l'impression de verre
   plutôt que de néon. */
.tile::after {
  background-image: radial-gradient(
    calc(var(--spot) * 0.45) calc(var(--spot) * 0.45) at
      calc(var(--x, 0) * 1px) calc(var(--y, 0) * 1px),
    var(--spot-light),
    transparent 100%
  );
  opacity: 0.5;
}

.tile:hover,
.tile:focus-visible {
  --tile-bg: rgba(254, 252, 247, 0.68);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 1),
    inset 0 -1px 0 rgba(90, 26, 16, 0.1);
}

.tile:hover::before,
.tile:focus-visible::before {
  opacity: 1;
}

.tile:hover::after,
.tile:focus-visible::after {
  opacity: 0.9;
}

/* Repli : sans mask-composite, les liserés couvriraient toute la dalle et
   noieraient le texte. On les retire et on garde le verre seul. */
@supports not ((mask-composite: exclude) or (-webkit-mask-composite: xor)) {
  .tile::before,
  .tile::after {
    display: none;
  }
}

/* --- Aquarelle au survol ---------------------------------------------------
   Une image par dalle, en fond très transparent, qui se pose en se
   rapprochant. Les fichiers ne sont demandés au serveur qu'au premier survol
   (règle :hover), donc un téléphone ne les télécharge jamais.

   `inset: 0` cadre sur la boîte de rembourrage, pas sur la bordure : les deux
   liserés éclairés restent visibles par-dessus.
   --------------------------------------------------------------------------- */

.tile__art {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity 1100ms var(--ease-out-quart);
}

.tile__art::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--art);
  background-size: cover;
  background-position: var(--art-pos, center center);
  /* Le zoom reste discret : 6 % d'écart suffisent à donner le mouvement de
     mise au point sans faire perdre la moitié du cadrage. */
  transform: scale(1.06);
  transition: transform 1400ms var(--ease-out-expo);
}

/* 0,28 est le plafond : au-delà, le lavis le plus dense fait passer le
   sous-texte sous le seuil de 4,5:1. */
.tile:hover .tile__art,
.tile:focus-visible .tile__art {
  opacity: 0.28;
}

.tile:hover .tile__art::before,
.tile:focus-visible .tile__art::before {
  transform: scale(1);
}

/* Ces dalles sont des bandeaux larges et bas : l'aquarelle y descend, ce qui
   revient à cadrer sur son haut, là où se trouve le motif. `--art-pos` est
   posé sur la dalle, pas sur le survol, pour valoir aussi dans le repli
   tactile. Le second nombre monte l'image, donc découvre son bas. */
.tile--liste {
  --art-pos: center top;
}

/* Guerzido : sa plage et son soleil sont trop haut placés dans l'image pour
   un cadrage collé au bord, sans aller jusqu'au tiers. */
.tile--hebergement {
  --art-pos: center 28%;
}

/* Une aquarelle par entrée. Pour en changer, il suffit d'échanger deux
   chemins ci-dessous. */
.tile--organisation:hover .tile__art,
.tile--organisation:focus-visible .tile__art {
  --art: url("../img/art/anse-rouge.png");
}

.tile--hebergement:hover .tile__art,
.tile--hebergement:focus-visible .tile__art {
  --art: url("../img/art/guerzido.png");
}

.tile--liste:hover .tile__art,
.tile--liste:focus-visible .tile__art {
  --art: url("../img/art/carmel.png");
}

/* Sur l'aplat rouge, l'aquarelle est blanche — donc elle éclaircit le fond
   et dégrade le texte blanc. Le rouge de survol descend d'autant, ce qui rend
   la dalle plus lisible en survol qu'au repos au lieu de l'inverse. */
.tile--rsvp:hover .tile__art,
.tile--rsvp:focus-visible .tile__art {
  --art: url("../img/art/bakers-beach.png");
  opacity: 0.22;
}

/* Sans souris, il n'y a pas de survol : l'aquarelle s'installe discrètement
   et sans mouvement, plutôt que de ne jamais apparaître. */
@media (hover: none) {
  .tile__art {
    opacity: 0.24;
  }
  .tile__art::before {
    transform: none;
  }
  .tile--organisation .tile__art {
    --art: url("../img/art/anse-rouge.png");
  }
  .tile--hebergement .tile__art {
    --art: url("../img/art/guerzido.png");
  }
  .tile--liste .tile__art {
    --art: url("../img/art/carmel.png");
  }
  /* Sans survol, le fond de la dalle Répondre ne s'assombrit pas : le lavis
     blanc y reste donc très en retrait, sous peine de noyer le texte. */
  .tile--rsvp .tile__art {
    --art: url("../img/art/bakers-beach.png");
    opacity: 0.1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .tile__art::before {
    transform: none;
  }
}

.tile__title {
  font-size: var(--t-lg);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.15;
  color: var(--ink);
}

.tile__desc {
  font-size: var(--t-sm);
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 36ch;
}

/* Pied de dalle : un fait, pas une décoration. C'est ce qui remplace le
   pictogramme, et c'est aussi ce qui occupe le bas de la case. */
.tile__meta {
  margin-top: auto;
  padding-top: var(--s-3);
  border-top: 1px solid var(--line);
  width: 100%;
  font-size: var(--t-xs);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* --- Poids des tuiles ----------------------------------------------------- */

.tile--organisation {
  grid-column: span 4;
  min-height: 16rem;
}

/* Seul aplat rouge du site : l'action attendue des invités.
   Le rouge est légèrement assombri pour que le texte blanc tienne le
   seuil AA (5,1:1 au lieu de 4,3:1 sur #DC4430). */
.tile--rsvp {
  grid-column: span 2;
  min-height: 16rem;
  /* Sur l'aplat rouge, la lampe passe en blanc : un rouge sur du rouge ne se
     verrait pas. Longhands uniquement, pour ne pas réinitialiser
     background-attachment ni background-size hérités de .tile. */
  --spot-fill: rgba(255, 255, 255, 0.18);
  --spot-edge: rgba(255, 255, 255, 0.9);
  --spot-light: rgba(255, 255, 255, 1);
  --tile-bg: var(--accent-strong);
  background-color: var(--tile-bg);
  color: var(--on-accent);
  border-color: rgba(255, 255, 255, 0.3);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35),
    inset 0 -1px 0 rgba(60, 10, 4, 0.25);
}

.tile--rsvp .tile__title {
  color: var(--on-accent);
}

.tile--rsvp .tile__desc,
.tile--rsvp .tile__meta {
  color: var(--on-accent-soft);
}

.tile--rsvp .tile__meta {
  border-top-color: rgba(255, 255, 255, 0.28);
}

.tile--rsvp:hover,
.tile--rsvp:focus-visible {
  --tile-bg: #8e2416;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45),
    inset 0 -1px 0 rgba(60, 10, 4, 0.3);
}

.tile--hebergement,
.tile--liste {
  grid-column: span 3;
}

.tile--photos {
  grid-column: span 6;
  min-height: 0;
  flex-direction: row;
  align-items: center;
  gap: var(--s-5);
  padding-block: var(--s-5);
}

.tile--photos .tile__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
}

.tile--photos .tile__title {
  font-size: var(--t-md);
}

.tile__badge {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-1) var(--s-3);
  border-radius: var(--r-sm);
  border: 1px solid var(--line-strong);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--ink-soft);
}

.tile__badge svg {
  width: 0.85rem;
  height: 0.85rem;
}

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

.menu__foot {
  text-align: center;
  font-size: var(--t-sm);
  color: var(--ink-soft);
}

.menu__foot a {
  font-weight: 600;
  color: var(--accent-deep);
}

/* --- Adaptation ----------------------------------------------------------- */

@media (max-width: 900px) {
  .menu__grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .tile--organisation,
  .tile--rsvp,
  .tile--photos {
    grid-column: span 2;
  }
  .tile--organisation {
    min-height: 13rem;
  }
  .tile--rsvp {
    min-height: 11rem;
  }
  /* Les entrées secondaires restent côte à côte : la hiérarchie de la
     grille survit au passage sur petit écran. */
  .tile--hebergement,
  .tile--liste {
    grid-column: span 1;
    min-height: 9rem;
  }
  .tile--hebergement .tile__title,
  .tile--liste .tile__title {
    font-size: var(--t-md);
  }
}

@media (max-width: 460px) {
  .tile {
    padding: var(--s-4);
  }
  .tile--photos {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--s-3);
  }
}
