@charset "UTF-8";
/* ==========================================================================
   CONSTELLATION 50 — Espace public
   ---------------------------------------------------------------------------
   Trois temps :
     1. l'accueil — un « Joyeux anniversaire » qui s'écrit, ballons et rubans ;
     2. le mode cinéma — les cartes pendent à des guirlandes et se balancent ;
     3. le mode grille — les mêmes cartes rangées, filtrables.

   Palette : bleu ciel, blanc, rose du drapeau trans, posés sur une encre
   prune très sombre pour rester festif sans être sucré.

   Note tactile : toutes les animations de survol sont enfermées dans
   @media (hover: hover). Sur iOS et Android, un :hover « colle » après un
   appui — le bouton « Lire la carte » y remplace le survol.
   ========================================================================== */

/* ==========================================================================
   Barre de navigation
   ========================================================================== */
.barre {
  position: sticky;
  top: 0;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-4);
  width: min(100% - 2.5rem, var(--largeur));
  margin-inline: auto;
  padding: var(--e-4) 0;
  transition: padding 0.4s var(--doux);
}
.barre::before {
  content: "";
  position: absolute;
  inset: 0 -50vw;
  background: linear-gradient(180deg, rgba(12, 7, 20, 0.92), rgba(12, 7, 20, 0));
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  opacity: 0;
  transition: opacity 0.4s var(--doux);
  pointer-events: none;
}
.barre.est-collee::before { opacity: 1; }
.barre.est-collee { padding-block: var(--e-3); }

.marque {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--e-3);
  font-family: var(--f-data);
  font-size: var(--t-xs);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--sourdine);
}
.marque:hover { color: var(--blanc); }
.marque-sceau {
  display: grid;
  place-items: center;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 50%;
  background: var(--ruban);
  color: #241536;
  font-family: var(--f-titre);
  font-size: 0.92rem;
  font-weight: 700;
}
.barre-liens { position: relative; display: flex; align-items: center; gap: var(--e-2); }
.barre-lien {
  padding: 0.5rem 0.9rem;
  border-radius: var(--r-full);
  font-size: var(--t-sm);
  color: var(--sourdine);
  transition: color 0.24s var(--doux), background 0.24s var(--doux);
}
.barre-lien:hover { color: var(--texte); background: var(--verre); }

/* ==========================================================================
   1. L'accueil
   ========================================================================== */
.accueil {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--e-5);
  min-height: 78vh;
  min-height: 78svh;
  padding-block: var(--e-7) var(--e-8);
  text-align: center;
}

.accueil-date {
  display: inline-flex;
  align-items: center;
  gap: var(--e-3);
  padding: 0.42rem 1.15rem;
  border: 1px solid var(--trait);
  border-radius: var(--r-full);
  background: var(--verre);
  font-family: var(--f-data);
  font-size: var(--t-xs);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--sourdine);
  animation: monter 0.9s var(--ressort) both;
}
.accueil-date::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--bleu);
  box-shadow: 0 0 12px var(--bleu);
  animation: battre 2.4s ease-in-out infinite;
}

@keyframes battre { 50% { opacity: 0.3; transform: scale(0.65); } }
@keyframes monter { from { opacity: 0; transform: translateY(24px); } }

/* --- Le vœu qui s'écrit --------------------------------------------------- */
.souhait {
  font-family: var(--f-titre);
  font-size: clamp(2.1rem, 1rem + 5.4vw, 5rem);
  font-weight: 300;
  font-variation-settings: "SOFT" 60, "WONK" 1, "opsz" 144;
  line-height: 1.06;
  letter-spacing: -0.01em;
  max-width: 16ch;
}
.souhait .lettre {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.42em) rotate(-6deg);
  animation: lettre-parait 0.75s var(--ressort) forwards;
  animation-delay: calc(var(--i) * 42ms);
}
.souhait .mot-groupe { display: inline-block; white-space: nowrap; }

@keyframes lettre-parait {
  to { opacity: 1; transform: none; }
}

/* Le prénom, en ruban du drapeau */
.souhait-nom {
  display: block;
  margin-top: 0.12em;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: linear-gradient(103deg,
      var(--bleu) 0%, #cfeefb 26%, var(--blanc) 48%, var(--rose-clair) 70%, var(--rose) 100%);
  background-size: 220% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: ruban-glisse 9s ease-in-out infinite;
}
@keyframes ruban-glisse {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}

/* --- L'âge, en grand, très discret derrière ------------------------------- */
.accueil-age {
  position: absolute;
  top: 46%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: -1;
  font-family: var(--f-titre);
  font-size: clamp(14rem, 8rem + 30vw, 34rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.04em;
  color: transparent;
  -webkit-text-stroke: 1px rgba(255, 255, 255, 0.06);
  pointer-events: none;
  user-select: none;
  animation: respirer 11s ease-in-out infinite;
}
@keyframes respirer {
  0%, 100% { opacity: 0.85; transform: translate(-50%, -50%) scale(1); }
  50%      { opacity: 1;    transform: translate(-50%, -50%) scale(1.035); }
}

.accueil-mot {
  max-width: 40ch;
  font-family: var(--f-titre);
  font-size: clamp(1rem, 0.9rem + 0.6vw, 1.3rem);
  font-style: italic;
  font-weight: 300;
  line-height: 1.55;
  color: var(--sourdine);
  animation: monter 1s 0.9s var(--ressort) both;
}

/* --- Le bouton qui déroule la carte --------------------------------------- */
.accueil-actions {
  display: flex;
  gap: var(--e-3);
  flex-wrap: wrap;
  justify-content: center;
  animation: monter 1s 1.05s var(--ressort) both;
}

.btn-derouler {
  position: relative;
  padding: 1.05rem 2.3rem;
  font-size: var(--t-md);
  font-weight: 650;
  letter-spacing: 0.01em;
}
.btn-derouler .btn-icone-rouleau {
  display: inline-block;
  transition: transform 0.5s var(--ressort);
}
@media (hover: hover) {
  .btn-derouler:hover .btn-icone-rouleau { transform: rotate(-22deg) translateY(2px); }
}
/* Halo lent, pour attirer l'œil sans clignoter */
.btn-derouler::before {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: var(--r-full);
  background: var(--ruban);
  opacity: 0.28;
  filter: blur(14px);
  z-index: -1;
  animation: halo-lent 4.5s ease-in-out infinite;
}
@keyframes halo-lent {
  0%, 100% { opacity: 0.2;  transform: scale(0.97); }
  50%      { opacity: 0.42; transform: scale(1.05); }
}

/* --- Compte à rebours ----------------------------------------------------- */
.accueil-pied {
  display: flex;
  align-items: center;
  gap: var(--e-5);
  flex-wrap: wrap;
  justify-content: center;
  margin-top: var(--e-5);
  animation: monter 1s 1.2s var(--ressort) both;
}
.rebours { display: flex; gap: var(--e-4); }
.rebours-bloc { text-align: center; min-width: 3.2rem; }
.rebours-bloc b {
  display: block;
  font-family: var(--f-data);
  font-size: var(--t-xl);
  font-weight: 500;
  color: var(--texte);
  font-variant-numeric: tabular-nums;
}
.rebours-bloc span {
  font-size: 0.6rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--sourdine-2);
}

.jauge { width: min(100%, 22rem); }
.jauge-chiffres {
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: 0.35em;
  margin-bottom: var(--e-2);
  text-align: center;
  font-family: var(--f-data);
  font-size: var(--t-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sourdine-2);
}
.jauge-chiffres b { font-size: var(--t-lg); font-weight: 600; color: var(--texte); }
.jauge-piste {
  height: 3px;
  border-radius: var(--r-full);
  background: rgba(255, 255, 255, 0.1);
  overflow: hidden;
}
.jauge-remplie {
  display: block;
  height: 100%;
  width: 0;
  border-radius: inherit;
  background: var(--ruban);
  box-shadow: 0 0 16px rgba(245, 169, 184, 0.55);
  transition: width 1.8s 0.6s var(--doux);
}

/* ==========================================================================
   Le vestibule : bascule accueil → cartes
   ========================================================================== */
.cartes-zone {
  display: none;
  padding-bottom: var(--e-8);
}
.cartes-zone.est-ouverte {
  display: block;
  animation: rideau 0.85s var(--doux) both;
}
@keyframes rideau {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: none; }
}

body.carte-deroulee .accueil {
  min-height: auto;
  padding-block: var(--e-6) var(--e-5);
  gap: var(--e-4);
}
body.carte-deroulee .accueil-mot,
body.carte-deroulee .accueil-pied,
body.carte-deroulee .accueil-age { display: none; }
body.carte-deroulee .souhait { font-size: clamp(1.6rem, 1rem + 3vw, 3rem); }
body.carte-deroulee .btn-derouler { display: none; }

/* En-tête commun aux deux modes */
.cartes-tete {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--e-5);
  flex-wrap: wrap;
  margin-bottom: var(--e-6);
}
.cartes-titre {
  font-family: var(--f-titre);
  font-size: var(--t-2xl);
  font-weight: 400;
  font-variation-settings: "SOFT" 40, "WONK" 1, "opsz" 72;
  line-height: 1.12;
}
.cartes-titre em { font-style: italic; color: var(--rose-clair); }
.cartes-sous { max-width: 46ch; margin-top: var(--e-2); color: var(--sourdine); font-size: var(--t-sm); }

/* ==========================================================================
   2. Mode cinéma — les cartes pendent aux guirlandes
   ========================================================================== */
.cinema { display: none; }
.cinema.est-actif { display: block; }

.guirlande {
  position: relative;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: clamp(0.8rem, 2.4vw, 2.4rem);
  padding-top: 56px;
  margin-bottom: clamp(2rem, 5vw, 4rem);
}

/* Le fil : une bordure arrondie fait un joli affaissement */
.guirlande::before {
  content: "";
  position: absolute;
  left: -2%;
  right: -2%;
  top: 6px;
  height: 46px;
  border-bottom: 2px solid rgba(255, 255, 255, 0.22);
  border-radius: 0 0 50% 50% / 0 0 100% 100%;
  pointer-events: none;
}
/* Petits fanions bleu/blanc/rose posés sur le fil */
.guirlande::after {
  content: "";
  position: absolute;
  left: -2%;
  right: -2%;
  top: 6px;
  height: 46px;
  border-bottom: 2px solid transparent;
  border-radius: 0 0 50% 50% / 0 0 100% 100%;
  background-image: var(--ruban);
  -webkit-mask-image: repeating-linear-gradient(90deg,
      #000 0 12px, transparent 12px 46px);
  mask-image: repeating-linear-gradient(90deg,
      #000 0 12px, transparent 12px 46px);
  opacity: 0.5;
  pointer-events: none;
}

/* --- La carte suspendue --------------------------------------------------- */
.pendu {
  --teinte: 197;
  --corde: 30px;
  --duree: 5s;
  --delai: 0s;
  --amplitude: 2.4deg;

  position: relative;
  flex: 0 1 clamp(9.5rem, 21vw, 15.5rem);
  margin-top: var(--corde);
  transform-origin: 50% -30px;
  animation: balancer var(--duree) var(--balancier) var(--delai) infinite alternate;
  will-change: transform;
}

@keyframes balancer {
  from { transform: rotate(calc(var(--amplitude) * -1)); }
  to   { transform: rotate(var(--amplitude)); }
}

/* La ficelle et la pince */
.pendu::before {
  content: "";
  position: absolute;
  left: 50%;
  top: calc(-1 * var(--corde));
  width: 1px;
  height: var(--corde);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.42), rgba(255, 255, 255, 0.16));
  transform: translateX(-50%);
}
.pendu-pince {
  position: absolute;
  left: 50%;
  top: -9px;
  width: 15px;
  height: 19px;
  transform: translateX(-50%);
  border-radius: 3px;
  background: linear-gradient(160deg, #f3e6ea, #c9b3bd);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.45);
  z-index: 3;
}
.pendu-pince::after {
  content: "";
  position: absolute;
  left: 2px; right: 2px; top: 8px;
  height: 1px;
  background: rgba(0, 0, 0, 0.28);
}

/* La carte elle-même */
.pendu-carte {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--trait);
  border-radius: var(--r-md);
  background:
    linear-gradient(158deg, hsla(var(--teinte), 78%, 66%, 0.14), transparent 62%),
    rgba(255, 255, 255, 0.055);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 16px 34px -18px rgba(0, 0, 0, 0.85);
  transition: box-shadow 0.4s var(--doux), border-color 0.4s var(--doux);
}

.pendu-photo {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  background: rgba(12, 7, 20, 0.6);
}
/* Repli si aspect-ratio n'est pas gérée (iOS < 15) */
@supports not (aspect-ratio: 4 / 3) {
  .pendu-photo { height: 8.5rem; }
}

.pendu-corps { padding: var(--e-3) var(--e-4) var(--e-4); }

.pendu-extrait {
  font-family: var(--f-titre);
  font-size: 0.85rem;
  font-weight: 300;
  line-height: 1.5;
  color: #f0e9f5;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.pendu-qui {
  display: flex;
  align-items: center;
  gap: var(--e-2);
  margin-top: var(--e-3);
  padding-top: var(--e-3);
  border-top: 1px solid rgba(255, 255, 255, 0.09);
}
.pendu-nom {
  flex: 1;
  min-width: 0;
  font-size: var(--t-xs);
  font-weight: 600;
  color: var(--texte);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pendu-relation {
  display: block;
  font-size: 0.62rem;
  font-weight: 400;
  color: var(--sourdine-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pendu-lire {
  width: 100%;
  margin-top: var(--e-3);
  padding: 0.5rem;
  border: 1px solid var(--trait);
  border-radius: var(--r-full);
  background: rgba(255, 255, 255, 0.06);
  color: var(--texte);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  cursor: pointer;
  transition: background 0.26s var(--doux), border-color 0.26s var(--doux);
}
.pendu-lire:hover,
.pendu-lire:focus-visible {
  background: var(--ruban);
  border-color: transparent;
  color: #241536;
}

/* Jeton média discret */
.pendu-jeton {
  position: absolute;
  top: var(--e-2);
  right: var(--e-2);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 0.16rem 0.5rem;
  border-radius: var(--r-full);
  background: rgba(12, 7, 20, 0.78);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  font-size: 0.6rem;
  color: var(--bleu-clair);
}

/* --- Le survol change d'animation ---------------------------------------
   Au repos la carte se balance. Au survol, le balancement s'arrête net,
   la carte se redresse, monte et se présente de face. */
@media (hover: hover) and (pointer: fine) {
  .pendu:hover {
    animation-play-state: paused;
    z-index: 5;
  }
  .pendu:hover .pendu-carte {
    animation: se-presenter 0.85s var(--ressort) forwards;
    border-color: hsla(var(--teinte), 82%, 70%, 0.55);
    box-shadow: 0 34px 62px -26px hsla(var(--teinte), 80%, 50%, 0.55),
                0 0 0 1px hsla(var(--teinte), 82%, 70%, 0.3);
  }
  .pendu:hover .pendu-photo { transform: scale(1.06); }

  /* Un reflet balaie la carte au survol */
  .pendu-carte::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(108deg, transparent 34%,
                rgba(255, 255, 255, 0.28) 50%, transparent 66%);
    transform: translateX(-130%);
    pointer-events: none;
  }
  .pendu:hover .pendu-carte::after {
    animation: reflet 0.95s 0.15s var(--doux) forwards;
  }
}

.pendu-photo { transition: transform 0.7s var(--doux); }

@keyframes se-presenter {
  0%   { transform: translateY(0) rotate(0) scale(1); }
  55%  { transform: translateY(-16px) rotate(1.5deg) scale(1.07); }
  100% { transform: translateY(-11px) rotate(0) scale(1.05); }
}
@keyframes reflet { to { transform: translateX(130%); } }

/* Au clavier, même mise en avant */
.pendu:focus-within { animation-play-state: paused; z-index: 5; }
.pendu:focus-within .pendu-carte {
  transform: translateY(-11px) scale(1.04);
  border-color: hsla(var(--teinte), 82%, 70%, 0.55);
}

/* Entrée en scène, carte par carte */
.pendu.est-tombe { animation: tomber 0.9s var(--ressort) both, balancer var(--duree) var(--balancier) 0.9s infinite alternate; }
@keyframes tomber {
  from { opacity: 0; transform: translateY(-46px) rotate(-8deg); }
  to   { opacity: 1; transform: none; }
}

/* --- Responsive des guirlandes -------------------------------------------- */
@media (max-width: 900px) {
  .guirlande { gap: clamp(0.6rem, 3vw, 1.4rem); padding-top: 44px; }
  .guirlande::before, .guirlande::after { height: 34px; }
  .pendu { flex-basis: clamp(8.5rem, 40vw, 12rem); --corde: 22px; transform-origin: 50% -22px; }
  .pendu::before { top: -22px; height: 22px; }
}
@media (max-width: 560px) {
  .pendu { flex-basis: calc(50% - 0.6rem); --amplitude: 1.6deg; }
  .pendu-extrait { -webkit-line-clamp: 2; }
}

/* ==========================================================================
   3. Mode grille
   ========================================================================== */
.grille-mode { display: none; }
.grille-mode.est-actif { display: block; }

.filtres { display: flex; gap: var(--e-1); flex-wrap: wrap; }
.filtre {
  padding: 0.44rem 1rem;
  border: 1px solid var(--trait);
  border-radius: var(--r-full);
  background: transparent;
  color: var(--sourdine);
  font-size: var(--t-xs);
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: color 0.24s var(--doux), border-color 0.24s var(--doux), background 0.24s var(--doux);
}
.filtre:hover { color: var(--texte); border-color: rgba(255, 255, 255, 0.28); }
.filtre[aria-pressed="true"] {
  background: var(--ruban);
  border-color: transparent;
  color: #241536;
  font-weight: 650;
}

.recherche { position: relative; }
.recherche .saisie { padding-left: 2.5rem; width: min(14rem, 60vw); }
.recherche::before {
  content: "";
  position: absolute;
  left: 0.95rem; top: 50%;
  width: 14px; height: 14px;
  margin-top: -7px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23c3b3d2' stroke-width='2'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.5-3.5' stroke-linecap='round'/%3E%3C/svg%3E") center/contain no-repeat;
  pointer-events: none;
}

.grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17.5rem, 1fr));
  gap: var(--e-5);
  align-items: start;
  perspective: 1200px;
}

/* --- La carte en grille : autre animation au survol ----------------------- */
.voeu {
  --teinte: 197;
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--trait);
  border-radius: var(--r-lg);
  background:
    linear-gradient(155deg, hsla(var(--teinte), 78%, 66%, 0.13), transparent 60%),
    rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: var(--ombre-douce);
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 0.7s var(--doux), transform 0.55s var(--ressort),
              border-color 0.35s var(--doux), box-shadow 0.35s var(--doux);
  transform-style: preserve-3d;
}
.voeu.est-visible { opacity: 1; transform: none; }

/* Ici le survol bascule la carte en 3D, là où la carte suspendue se redressait */
@media (hover: hover) and (pointer: fine) {
  .voeu.est-visible:hover {
    transform: translateY(-8px) rotateX(5deg) rotateY(-4deg) scale(1.015);
    border-color: hsla(var(--teinte), 82%, 70%, 0.5);
    box-shadow: 0 34px 66px -28px hsla(var(--teinte), 80%, 48%, 0.55), var(--ombre-douce);
  }
  .voeu.est-visible:hover .media-image { transform: scale(1.05); }
  .voeu.est-visible:hover .voeu-texte { color: #fff; }
}

.voeu-media { position: relative; overflow: hidden; }
.media-image, .media-video {
  display: block;
  width: 100%;
  height: auto;
  background: rgba(12, 7, 20, 0.6);
  transition: transform 0.75s var(--doux);
}
.media-video { aspect-ratio: 16 / 9; object-fit: cover; }

.voeu-corps { padding: var(--e-5); }

.voeu-texte {
  font-family: var(--f-titre);
  font-size: 1.02rem;
  font-weight: 300;
  font-variation-settings: "SOFT" 40, "opsz" 24;
  line-height: 1.6;
  color: #efe9f5;
  white-space: pre-line;
  overflow-wrap: break-word;
  transition: color 0.35s var(--doux);
}

.voeu-pied {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  margin-top: var(--e-4);
  padding-top: var(--e-3);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.pastille {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.3rem; height: 2.3rem;
  border-radius: 50%;
  background: linear-gradient(140deg, hsl(var(--teinte), 80%, 74%), hsl(calc(var(--teinte) + 26), 74%, 60%));
  color: #241536;
  font-weight: 700;
  font-size: var(--t-sm);
}
.voeu-qui { flex: 1; min-width: 0; }
.voeu-auteur {
  display: block;
  font-weight: 600;
  font-size: var(--t-sm);
  color: var(--texte);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.voeu-meta { font-size: var(--t-xs); color: var(--sourdine-2); }
.voeu-index {
  flex: none;
  font-family: var(--f-data);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  color: hsla(var(--teinte), 76%, 74%, 0.9);
}

.voeu.est-en-avant { border-color: var(--trait-rose); }
.voeu.est-en-avant::after {
  content: "Coup de cœur";
  position: absolute;
  top: var(--e-4);
  right: calc(-1 * var(--e-2));
  padding: 0.2rem 0.7rem;
  border-radius: var(--r-full) 0 0 var(--r-full);
  background: var(--ruban);
  color: #241536;
  font-size: 0.58rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Média secondaire */
.media-audio {
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
  margin: 0 var(--e-5) var(--e-4);
  padding: var(--e-3) var(--e-4);
  border: 1px solid hsla(var(--teinte), 66%, 62%, 0.3);
  border-radius: var(--r-md);
  background: hsla(var(--teinte), 66%, 52%, 0.1);
}
.media-audio-etiquette {
  font-family: var(--f-data);
  font-size: 0.6rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: hsl(var(--teinte), 76%, 78%);
}
.media-audio audio { width: 100%; height: 2.2rem; }

.media-lien {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  margin: 0 var(--e-5) var(--e-4);
  padding: 0.55rem 1rem;
  border: 1px solid var(--trait);
  border-radius: var(--r-full);
  background: rgba(255, 255, 255, 0.05);
  color: var(--texte);
  font-size: var(--t-sm);
  font-weight: 500;
}
.media-lien:hover { border-color: var(--trait-rose); background: rgba(245, 169, 184, 0.12); }
.media-lien-icone {
  display: grid;
  place-items: center;
  width: 1.5rem; height: 1.5rem;
  border-radius: 50%;
  background: var(--rose);
  color: #241536;
  font-size: 0.6rem;
  padding-left: 2px;
}
.media-lien-fleche { color: var(--sourdine-2); font-size: var(--t-xs); }

/* --- Vide / suite --------------------------------------------------------- */
.mur-vide {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e-4);
  padding: var(--e-8) var(--e-5);
  text-align: center;
  border: 1px dashed var(--trait);
  border-radius: var(--r-lg);
}
.mur-vide-titre { font-family: var(--f-titre); font-size: var(--t-xl); font-weight: 400; }
.mur-vide p { max-width: 40ch; color: var(--sourdine); font-size: var(--t-sm); }

.mur-suite { display: flex; justify-content: center; margin-top: var(--e-6); }

/* ==========================================================================
   Le lecteur — « Lire la carte »
   ========================================================================== */
.lecteur {
  position: fixed;
  inset: 0;
  z-index: 150;
  display: grid;
  place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
  background: rgba(8, 5, 14, 0.9);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.45s var(--doux), visibility 0.45s;
  overscroll-behavior: contain;
}
.lecteur.est-ouvert { opacity: 1; visibility: visible; }

.lecteur-carte {
  --teinte: 197;
  position: relative;
  width: min(100%, 46rem);
  max-height: 88vh;
  max-height: 88svh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--trait);
  border-radius: var(--r-xl);
  background:
    linear-gradient(158deg, hsla(var(--teinte), 78%, 66%, 0.16), transparent 52%),
    var(--fond-800);
  box-shadow: 0 40px 90px -34px rgba(0, 0, 0, 0.95);
  transform: translateY(22px) scale(0.97);
  transition: transform 0.5s var(--ressort);
}
.lecteur.est-ouvert .lecteur-carte { transform: none; }

.lecteur-media img,
.lecteur-media video {
  display: block;
  width: 100%;
  max-height: 46vh;
  object-fit: cover;
  background: rgba(12, 7, 20, 0.6);
}
.lecteur-corps { padding: clamp(1.4rem, 4vw, 2.4rem); }

.lecteur-message {
  font-family: var(--f-titre);
  font-size: clamp(1.05rem, 0.95rem + 0.7vw, 1.5rem);
  font-weight: 300;
  font-variation-settings: "SOFT" 50, "opsz" 48;
  line-height: 1.62;
  color: #fbf6fd;
  white-space: pre-line;
  overflow-wrap: break-word;
}
.lecteur-message .mot {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.4em);
  animation: mot-parait 0.55s var(--ressort) forwards;
}
@keyframes mot-parait { to { opacity: 1; transform: none; } }

.lecteur-signature {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  margin-top: var(--e-5);
  padding-top: var(--e-4);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
}
.lecteur-nom { font-weight: 650; }
.lecteur-relation { font-size: var(--t-xs); color: var(--sourdine-2); }

.lecteur-barre {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-3);
  margin-top: var(--e-5);
}
.lecteur-compteur {
  min-width: 5rem;
  text-align: center;
  font-family: var(--f-data);
  font-size: var(--t-xs);
  letter-spacing: 0.12em;
  color: var(--sourdine);
}
.lecteur-fermer {
  position: absolute;
  top: var(--e-3);
  right: var(--e-3);
  z-index: 4;
  background: rgba(12, 7, 20, 0.72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.lecteur-aide {
  margin-top: var(--e-4);
  text-align: center;
  font-family: var(--f-data);
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  color: var(--sourdine-2);
}
@media (max-width: 720px) { .lecteur-aide { display: none; } }

/* ==========================================================================
   Bascule de mode — en bas à gauche
   ========================================================================== */
.bascule-mode {
  position: fixed;
  left: var(--e-5);
  bottom: var(--e-5);
  z-index: 95;
  display: none;
  padding: 0.3rem;
  border: 1px solid var(--trait);
  border-radius: var(--r-full);
  background: rgba(21, 13, 34, 0.92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: var(--ombre-douce);
}
body.carte-deroulee .bascule-mode { display: flex; gap: 0.2rem; }

.bascule-choix {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  padding: 0.52rem 1.05rem;
  border: 0;
  border-radius: var(--r-full);
  background: transparent;
  color: var(--sourdine);
  font-size: var(--t-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: color 0.24s var(--doux), background 0.3s var(--doux);
}
.bascule-choix:hover { color: var(--texte); }
.bascule-choix[aria-pressed="true"] {
  background: var(--ruban);
  color: #241536;
}
.bascule-choix span[aria-hidden] { font-size: 0.95em; }

@media (max-width: 560px) {
  .bascule-mode { left: 50%; transform: translateX(-50%); bottom: var(--e-4); }
  .bascule-choix { padding: 0.5rem 0.85rem; }
}

/* ==========================================================================
   Ballons et rubans — couche décorative
   ========================================================================== */
.decor {
  position: fixed;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
}

/* --- Ballons --------------------------------------------------------------
   Deux animations combinées : une montée verticale, et un balancement
   horizontal indépendant, pour que la trajectoire ne soit jamais rectiligne. */
.ballon {
  position: absolute;
  bottom: -26vh;
  left: var(--x);
  width: var(--taille);
  animation: ballon-monte var(--duree) linear var(--delai) infinite;
  will-change: transform;
}
.ballon-oscille {
  animation: ballon-oscille calc(var(--duree) / 5.5) ease-in-out infinite alternate;
}
.ballon-corps {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 5;
  border-radius: 50% 50% 48% 48% / 42% 42% 58% 58%;
  background:
    radial-gradient(circle at 32% 26%, rgba(255, 255, 255, 0.75), transparent 42%),
    radial-gradient(circle at 50% 42%, var(--couleur), var(--couleur-2) 78%);
  opacity: 0.68;
  filter: saturate(1.05);
}
@supports not (aspect-ratio: 4 / 5) {
  .ballon-corps { height: 0; padding-bottom: 125%; }
}
/* Le nœud */
.ballon-corps::after {
  content: "";
  position: absolute;
  left: 50%; bottom: -6px;
  width: 9px; height: 8px;
  transform: translateX(-50%);
  border-radius: 3px 3px 50% 50%;
  background: var(--couleur-2);
  opacity: 0.85;
}
/* La ficelle */
.ballon-fil {
  display: block;
  width: 1px;
  height: 4.2rem;
  margin: 6px auto 0;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.38), transparent);
}

@keyframes ballon-monte {
  from { transform: translateY(0)      rotate(-3deg); }
  to   { transform: translateY(-135vh) rotate(3deg); }
}
@keyframes ballon-oscille {
  from { margin-left: -22px; }
  to   { margin-left: 22px; }
}

/* --- Rubans qui ondulent en haut de page ---------------------------------- */
.rubans {
  position: absolute;
  inset: 0 0 auto 0;
  height: 42vh;
  opacity: 0.5;
}
.ruban-brin {
  position: absolute;
  top: -12vh;
  left: var(--x);
  width: var(--large);
  height: 58vh;
  border-radius: var(--r-full);
  background: var(--teinte-ruban);
  filter: blur(0.4px);
  transform-origin: top center;
  animation: ruban-ondule var(--duree) ease-in-out var(--delai) infinite alternate;
  opacity: 0.55;
}
@keyframes ruban-ondule {
  from { transform: rotate(-7deg) scaleY(0.92) translateX(-8px); }
  to   { transform: rotate(7deg)  scaleY(1.06) translateX(8px); }
}

/* --- Serpentins tombants (fins, en arrière-plan) --------------------------- */
.serpentin {
  position: absolute;
  top: -18vh;
  left: var(--x);
  width: 3px;
  height: 34vh;
  border-radius: var(--r-full);
  background: repeating-linear-gradient(180deg,
      var(--couleur) 0 14px, transparent 14px 26px);
  opacity: 0.35;
  animation: serpentin-flotte var(--duree) ease-in-out var(--delai) infinite alternate;
}
@keyframes serpentin-flotte {
  from { transform: translateY(-14px) rotate(-4deg); }
  to   { transform: translateY(14px)  rotate(4deg); }
}

/* La couche de festivités par-dessus tout */
#toile-fete { position: fixed; inset: 0; z-index: 60; pointer-events: none; }

/* ==========================================================================
   Appel final et pied de page
   ========================================================================== */
.appel {
  position: relative;
  margin-block: var(--e-8);
  padding: clamp(2.4rem, 1rem + 6vw, 4.6rem) var(--e-5);
  border: 1px solid var(--trait);
  border-radius: var(--r-xl);
  background:
    radial-gradient(80% 130% at 20% 0%, rgba(91, 206, 250, 0.14), transparent 60%),
    radial-gradient(80% 130% at 80% 0%, rgba(245, 169, 184, 0.14), transparent 60%),
    rgba(255, 255, 255, 0.03);
  text-align: center;
  overflow: hidden;
}
.appel::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: var(--ruban);
}
.appel-titre {
  font-family: var(--f-titre);
  font-size: var(--t-2xl);
  font-weight: 300;
  font-variation-settings: "SOFT" 50, "WONK" 1, "opsz" 72;
  line-height: 1.16;
}
.appel-titre em { font-style: italic; color: var(--bleu-clair); }
.appel p { max-width: 48ch; margin: var(--e-4) auto var(--e-5); color: var(--sourdine); }

.pied {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--e-4);
  flex-wrap: wrap;
  padding-block: var(--e-6);
  border-top: 1px solid var(--trait);
  font-size: var(--t-xs);
  color: var(--sourdine-2);
}
.pied a { color: var(--sourdine); }
.pied a:hover { color: var(--rose-clair); }

/* ==========================================================================
   Page « déposer un vœu »
   ========================================================================== */
.atelier {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
  gap: clamp(2rem, 4vw, 4rem);
  align-items: start;
  padding-block: var(--e-7) var(--e-8);
}
@media (max-width: 900px) { .atelier { grid-template-columns: 1fr; } }

.atelier-tete { margin-bottom: var(--e-6); }
.atelier-titre {
  font-family: var(--f-titre);
  font-size: var(--t-3xl);
  font-weight: 300;
  font-variation-settings: "SOFT" 55, "WONK" 1, "opsz" 144;
  line-height: 1.06;
}
.atelier-titre em { font-style: italic; color: var(--rose-clair); }
.atelier-tete p { max-width: 46ch; margin-top: var(--e-4); color: var(--sourdine); }

.formulaire { display: flex; flex-direction: column; gap: var(--e-5); }
.formulaire-duo { display: grid; grid-template-columns: 1fr 1fr; gap: var(--e-4); }
@media (max-width: 560px) { .formulaire-duo { grid-template-columns: 1fr; } }

.compteur-signes {
  font-family: var(--f-data);
  font-size: var(--t-xs);
  color: var(--sourdine-2);
  font-variant-numeric: tabular-nums;
}
.compteur-signes.est-limite { color: var(--rose); }

/* --- Cases « Vous êtes… » -------------------------------------------------- */
.champ-groupe { border: 0; margin: 0; padding: 0; min-width: 0; }
.champ-groupe legend {
  padding: 0;
  margin-bottom: var(--e-3);
  font-size: var(--t-sm);
  font-weight: 500;
  color: var(--texte);
}
.champ-groupe legend .aide { margin-left: var(--e-2); }

.cases { display: flex; flex-wrap: wrap; gap: var(--e-2); }
.case {
  display: inline-flex;
  align-items: center;
  gap: var(--e-3);
  padding: 0.62rem 1.15rem 0.62rem 0.9rem;
  border: 1px solid var(--trait);
  border-radius: var(--r-full);
  background: rgba(12, 7, 20, 0.42);
  cursor: pointer;
  user-select: none;
  transition: border-color 0.24s var(--doux), background 0.24s var(--doux);
}
.case:hover { border-color: rgba(255, 255, 255, 0.3); }
.case input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.case-marque {
  position: relative;
  flex: none;
  width: 1.15rem; height: 1.15rem;
  border: 1.5px solid var(--sourdine-2);
  border-radius: 5px;
  transition: background 0.2s var(--doux), border-color 0.2s var(--doux);
}
.case-marque::after {
  content: "";
  position: absolute;
  left: 50%; top: 46%;
  width: 0.32rem; height: 0.6rem;
  margin: -0.34rem 0 0 -0.16rem;
  border: solid #241536;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0);
  transition: transform 0.22s var(--ressort);
}
.case-texte { font-size: var(--t-sm); font-weight: 500; color: var(--sourdine); transition: color 0.2s var(--doux); }
.case input:checked ~ .case-marque { background: var(--bleu); border-color: var(--bleu); }
.case input:checked ~ .case-marque::after { transform: rotate(45deg) scale(1); }
.case input:checked ~ .case-texte { color: var(--texte); }
.case input:focus-visible ~ .case-marque { outline: 2px solid var(--bleu); outline-offset: 3px; }
.case:has(input:checked) { border-color: var(--trait-vif); background: rgba(91, 206, 250, 0.1); }

/* --- Nuancier -------------------------------------------------------------- */
.nuancier { display: flex; gap: var(--e-2); flex-wrap: wrap; }
.nuancier input { position: absolute; opacity: 0; pointer-events: none; }
.nuancier label {
  display: grid;
  place-items: center;
  width: 2.5rem; height: 2.5rem;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform 0.24s var(--ressort), border-color 0.24s var(--doux);
}
.nuancier label span {
  width: 1.6rem; height: 1.6rem;
  border-radius: 50%;
  background: linear-gradient(140deg, hsl(var(--teinte), 80%, 74%), hsl(calc(var(--teinte) + 26), 74%, 60%));
}
.nuancier label:hover { transform: scale(1.12); }
.nuancier input:checked + label { border-color: var(--texte); transform: scale(1.12); }
.nuancier input:focus-visible + label { outline: 2px solid var(--bleu); outline-offset: 2px; }

/* --- Dépôt de fichier ------------------------------------------------------ */
.depot { position: relative; }
.depot-champ { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.depot-zone {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-3);
  padding: var(--e-6) var(--e-5);
  border: 1.5px dashed var(--trait);
  border-radius: var(--r-md);
  background: rgba(12, 7, 20, 0.32);
  color: var(--sourdine);
  font-size: var(--t-sm);
  font-weight: 500;
  cursor: pointer;
  text-align: center;
  transition: border-color 0.24s var(--doux), background 0.24s var(--doux), color 0.24s var(--doux);
}
.depot-zone:hover,
.depot.est-survole .depot-zone {
  border-color: var(--bleu);
  background: rgba(91, 206, 250, 0.08);
  color: var(--texte);
}
.depot-champ:focus-visible + .depot-zone { outline: 2px solid var(--bleu); outline-offset: 3px; }
.depot-icone { font-size: 1.15rem; }
.depot.est-rempli .depot-zone { display: none; }

.depot-photo .depot-zone {
  border-color: var(--trait-vif);
  background: rgba(91, 206, 250, 0.06);
  color: var(--bleu-clair);
}

.depot-choisi {
  display: flex;
  align-items: center;
  gap: var(--e-4);
  padding: var(--e-3);
  border: 1px solid var(--trait-vif);
  border-radius: var(--r-md);
  background: rgba(91, 206, 250, 0.08);
  animation: monter 0.4s var(--ressort) both;
}
.depot-vignette {
  display: grid;
  place-items: center;
  flex: none;
  width: 3.6rem; height: 3.6rem;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: rgba(12, 7, 20, 0.55);
  font-size: 1.35rem;
}
.depot-vignette img { width: 100%; height: 100%; object-fit: cover; }
.depot-infos { flex: 1; min-width: 0; }
.depot-infos b {
  display: block;
  font-size: var(--t-sm);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.depot-infos .donnee { font-size: var(--t-xs); color: var(--sourdine-2); }

/* --- Aperçu vivant --------------------------------------------------------- */
.apercu { position: sticky; top: 6rem; display: flex; flex-direction: column; gap: var(--e-4); }
.apercu-legende {
  font-family: var(--f-data);
  font-size: var(--t-xs);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--sourdine-2);
}
.apercu .voeu { opacity: 1; transform: none; }
@media (max-width: 900px) { .apercu { position: static; order: -1; } }

/* --- Confirmation ---------------------------------------------------------- */
.confirmation {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e-4);
  padding: clamp(2.4rem, 6vw, 4.4rem) var(--e-5);
  text-align: center;
  border: 1px solid var(--trait);
  border-radius: var(--r-xl);
  background:
    radial-gradient(80% 120% at 20% 0%, rgba(91, 206, 250, 0.16), transparent 58%),
    radial-gradient(80% 120% at 80% 0%, rgba(245, 169, 184, 0.16), transparent 58%);
  animation: monter 0.8s var(--ressort) both;
}
.confirmation-etoile {
  font-size: 3rem;
  line-height: 1;
  filter: drop-shadow(0 0 22px rgba(245, 169, 184, 0.75));
  animation: scintille 2.6s ease-in-out infinite;
}
@keyframes scintille { 50% { transform: scale(1.14) rotate(8deg); } }
.confirmation-titre {
  font-family: var(--f-titre);
  font-size: var(--t-2xl);
  font-weight: 300;
  font-variation-settings: "SOFT" 50, "WONK" 1;
}
.confirmation p { max-width: 44ch; color: var(--sourdine); }

/* ==========================================================================
   Mouvement réduit — on garde la mise en page, on coupe le mouvement
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .souhait .lettre { opacity: 1; transform: none; animation: none; }
  .pendu, .pendu.est-tombe { animation: none; }
  .ballon, .ballon-oscille, .ruban-brin, .serpentin,
  .accueil-age, .souhait-nom, .btn-derouler::before { animation: none; }
  .voeu { opacity: 1; transform: none; }
  .lecteur-message .mot { opacity: 1; transform: none; animation: none; }
}
