/* ==========================================================================
   Flexe — site public
   --------------------------------------------------------------------------
   Direction : la séance. Cinéma en plein air, la nuit, en Martinique.
   Trois motifs portent l'identité, tous tirés du logo et du produit :
     · le cadre fin imbriqué du logo, repris comme encadrement de section
     · le point rouge de la marque, repris comme marqueur
     · le faisceau du projecteur et le grain de la pellicule, en atmosphère
   Typographie : Inter (la DA), auto-hébergée, employée sur toute sa plage —
   900 très serré pour les titres, capitales espacées pour les libellés.
   ========================================================================== */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('/fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('/fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Fraunces en display : une serif variable, chaude et légèrement rétro, qui
   sort la page du tout-Inter sans toucher au texte courant. */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/fraunces-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Marque */
  --red: #e50914;
  --red-deep: #a4060e;
  --black: #0b0b0b;

  /* Sol : la nuit tropicale relevée sur les photos — bleutée, jamais noire.
     Le noir pur écrasait tout ; ce bleu profond laisse respirer les images. */
  --ground: #0d1117;
  --ground-deep: #080b10;
  --surface: #141a22;
  --surface-lift: #1c242e;

  /* Encre chaude plutôt que blanc pur — on est à la lumière d'un projecteur */
  --ink: #f4efe9;
  --ink-soft: #b9b2ab;
  --muted: #857d76;

  /* Les quatre couleurs prises dans les prestations elles-mêmes */
  --amber: #f5b14c;        /* les guirlandes lumineuses */
  --amber-soft: #ffd79a;
  --teal: #2e5a63;         /* le lagon au crépuscule */
  --teal-lift: #59a0ac;
  --terracotta: #b4573a;   /* le sable et le plaid rouge */

  --line: rgba(244, 239, 233, 0.13);
  --line-soft: rgba(244, 239, 233, 0.07);

  --font: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-display: 'Fraunces', 'Iowan Old Style', 'Palatino', Georgia, serif;

  --measure: 62ch;
  --gutter: clamp(1.25rem, 5vw, 4rem);
  --radius: 4px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-soft: cubic-bezier(0.33, 1, 0.68, 1);
}

/* ------------------------------------------------------------------ reset */

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

/* `hidden` doit vouloir dire caché.

   Le navigateur ne lui accorde qu'un `display: none` de sa feuille par
   défaut, que n'importe quel `display` déclaré ici emporte. Un champ en
   `display: grid` portait donc l'attribut sans disparaître — masqué pour le
   script, visible pour le visiteur. */
[hidden] {
  display: none !important;
}

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

body {
  margin: 0;
  /* Un dégradé très lent du bleu-nuit vers un fond plus sourd : la page
     s'assombrit en descendant, comme la soirée qu'elle raconte. */
  background: var(--ground);
  background-image: linear-gradient(180deg, #101822 0%, var(--ground) 38%, var(--ground-deep) 100%);
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--font);
  font-size: 1rem;
  line-height: 1.65;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img,
svg,
video {
  display: block;
  max-width: 100%;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  border: 0;
  background: none;
  cursor: pointer;
}

:where(a, button, input, textarea, select, summary):focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 3px;
  border-radius: 2px;
}

/* ---------------------------------------------------------- atmosphere ---
   Le grain de pellicule et le faisceau du projecteur, tous deux non
   interactifs et purement décoratifs. */

.grain {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.32;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
}

/* Faisceau : un cône de lumière chaude qui dérive très lentement. */
.beam {
  position: absolute;
  top: -22vh;
  left: 50%;
  width: min(1500px, 165vw);
  aspect-ratio: 1 / 1;
  translate: -50% 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(closest-side, rgba(229, 9, 20, 0.16), rgba(229, 9, 20, 0) 72%),
    radial-gradient(closest-side, rgba(245, 177, 76, 0.09), rgba(245, 177, 76, 0) 62%);
  filter: blur(28px);
  animation: drift 26s var(--ease) infinite alternate;
}

@keyframes drift {
  from {
    translate: -54% 0;
    scale: 1;
  }
  to {
    translate: -46% 2vh;
    scale: 1.07;
  }
}

/* ------------------------------------------------------------- structure */

.shell {
  position: relative;
  z-index: 2;
}

.wrap {
  width: 100%;
  max-width: 1180px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

section {
  position: relative;
  padding-block: clamp(4.5rem, 11vw, 8.5rem);
}

/* Le cadre imbriqué du logo, repris comme encadrement.
   Deux traits, l'extérieur plus discret que l'intérieur. */
.frame {
  position: relative;
  padding: clamp(1.75rem, 4vw, 3rem);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}

.frame::before {
  content: '';
  position: absolute;
  inset: 7px;
  border: 1px solid var(--line);
  border-radius: 2px;
  pointer-events: none;
}

/* ---------------------------------------------------------- typographie */

h1,
h2 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: 'SOFT' 28, 'WONK' 1, 'opsz' 96;
  letter-spacing: -0.022em;
  line-height: 1.02;
  text-wrap: balance;
}

h3 {
  margin: 0;
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.1;
  text-wrap: balance;
}

h1 {
  /* Plafonné pour que « et un lieu qui devient le vôtre. » tienne sur une
     ligne jusqu'en grand écran, sans mot orphelin. */
  font-size: clamp(2.3rem, 6.6vw, 4.6rem);
}

h2 {
  font-size: clamp(2rem, 5vw, 3.4rem);
}

h3 {
  font-size: clamp(1.15rem, 2vw, 1.4rem);
}

p {
  margin: 0 0 1.15rem;
  color: var(--ink-soft);
}

.lede {
  font-size: clamp(1.05rem, 1.9vw, 1.3rem);
  line-height: 1.55;
  color: var(--ink-soft);
  max-width: var(--measure);
}

.prose {
  max-width: var(--measure);
}

/* Libellé de section : point rouge + capitales espacées. */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 1.4rem;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
}

.eyebrow::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--red);
  box-shadow: 0 0 12px rgba(229, 9, 20, 0.8);
  flex: none;
}

/* Employé comme <dt>, le libellé doit occuper sa propre ligne. */
dt.eyebrow {
  display: flex;
}

.section-head {
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
  max-width: 46rem;
}

/* --------------------------------------------------------------- header */

.masthead {
  position: sticky;
  top: 0;
  z-index: 50;
  transition: background 0.3s var(--ease), border-color 0.3s var(--ease);
  border-bottom: 1px solid transparent;
}

.masthead[data-scrolled='true'] {
  background: rgba(13, 17, 23, 0.82);
  backdrop-filter: blur(14px) saturate(1.3);
  border-bottom-color: var(--line-soft);
}

.masthead .wrap {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  height: 76px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-weight: 900;
  font-size: 1.32rem;
  letter-spacing: -0.05em;
  margin-right: auto;
}

.brand .dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--red);
  box-shadow: 0 0 14px rgba(229, 9, 20, 0.9);
  translate: 0 -0.35em;
}

.nav {
  display: none;
  gap: 2rem;
  align-items: center;
}

@media (min-width: 900px) {
  .nav {
    display: flex;
  }
}

.nav a {
  position: relative;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--ink-soft);
  padding-block: 0.35rem;
  transition: color 0.2s var(--ease);
}

.nav a::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: var(--red);
  scale: 0 1;
  transform-origin: left;
  transition: scale 0.32s var(--ease);
}

.nav a:hover,
.nav a[aria-current='page'] {
  color: var(--ink);
}

.nav a:hover::after,
.nav a[aria-current='page']::after {
  scale: 1 1;
}

/* Menu mobile : une bascule CSS pure, sans JavaScript. */
.nav-toggle {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

@media (min-width: 900px) {
  .nav-toggle {
    display: none;
  }
}

.nav-panel {
  display: none;
  border-top: 1px solid var(--line-soft);
  background: rgba(11, 11, 11, 0.96);
  backdrop-filter: blur(14px);
}

.nav-panel[data-open='true'] {
  display: block;
}

.nav-panel a {
  display: block;
  padding: 0.9rem 0;
  font-size: 1.05rem;
  font-weight: 500;
  border-bottom: 1px solid var(--line-soft);
}

.nav-panel a:last-child {
  border-bottom: 0;
}

/* -------------------------------------------------------------- boutons */

.btn {
  --btn-bg: var(--red);
  --btn-ink: #fff;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.85rem 1.6rem;
  border-radius: var(--radius);
  background: var(--btn-bg);
  color: var(--btn-ink);
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  transition: translate 0.25s var(--ease), box-shadow 0.25s var(--ease);
}

.btn:hover {
  translate: 0 -2px;
  box-shadow: 0 10px 30px -8px rgba(229, 9, 20, 0.55);
}

.btn:active {
  translate: 0 0;
}

/* Reflet qui balaie le bouton au survol — la lumière qui passe. */
.btn::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 38%, rgba(255, 255, 255, 0.22) 50%, transparent 62%);
  translate: -110% 0;
  transition: translate 0.6s var(--ease);
}

.btn:hover::after {
  translate: 110% 0;
}

.btn-ghost {
  --btn-bg: transparent;
  --btn-ink: var(--ink);
  border: 1px solid var(--line);
}

.btn-ghost:hover {
  border-color: rgba(244, 239, 233, 0.3);
  box-shadow: none;
}

.btn-sm {
  padding: 0.6rem 1.15rem;
  font-size: 0.85rem;
}

/* ----------------------------------------------------------------- hero */

.hero {
  position: relative;
  padding-block: clamp(4rem, 12vh, 8rem) clamp(4.5rem, 10vw, 7rem);
  overflow: hidden;
}

/* Cadrage cinéma : deux filets qui rappellent le format large. */
.hero-rule {
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--line), transparent);
}

.hero h1 {
  margin-bottom: 1.5rem;
}

.hero h1 em {
  font-style: normal;
  color: var(--red);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
  margin-top: 2.25rem;
}

/* Bandeau de repères sous le hero. */
.marks {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: 1px;
  margin-top: clamp(3rem, 7vw, 5rem);
  background: var(--line-soft);
  border-block: 1px solid var(--line-soft);
}

.mark {
  background: var(--ground);
  padding: 1.4rem 1.25rem;
}

.mark dt {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.45rem;
}

.mark dd {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink);
}

/* ---------------------------------------------------------------- packs */

.packs {
  display: grid;
  gap: clamp(1rem, 2vw, 1.5rem);
  grid-template-columns: 1fr;
}

@media (min-width: 720px) {
  .packs {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1080px) {
  .packs {
    grid-template-columns: repeat(4, 1fr);
  }
}

.pack {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 1.6rem 1.5rem 1.5rem;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease),
    translate 0.3s var(--ease);
}

.pack::before {
  content: '';
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--red), transparent);
  opacity: 0;
  transition: opacity 0.35s var(--ease);
}

.pack:hover {
  translate: 0 -4px;
  background: var(--surface-lift);
  border-color: rgba(244, 239, 233, 0.18);
}

.pack:hover::before {
  opacity: 1;
}

.pack-cat {
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.9rem;
}

.pack h3 {
  margin-bottom: 0.5rem;
}

.pack-tagline {
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--ink-soft);
  margin-bottom: 1.4rem;
}

.pack-price {
  margin-top: auto;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line-soft);
}

.price {
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  font-variant-numeric: tabular-nums;
}

.price b {
  font-size: 1.9rem;
  font-weight: 800;
  letter-spacing: -0.045em;
  color: var(--ink);
}

.price span {
  font-size: 0.82rem;
  color: var(--muted);
}

.price-note {
  margin: 0.35rem 0 0;
  font-size: 0.78rem;
  color: var(--muted);
}

/* Toute la carte est cliquable, sans imbriquer de lien dans un lien. */
.stretch::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* --------------------------------------------------------- liste incluse */

.includes {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.7rem;
}

.includes li {
  position: relative;
  padding-left: 1.4rem;
  font-size: 0.94rem;
  color: var(--ink-soft);
}

.includes li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--red);
}

/* ------------------------------------------------------------- parcours */

.steps {
  display: grid;
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  overflow: hidden;
  grid-template-columns: 1fr;
}

@media (min-width: 780px) {
  .steps {
    grid-template-columns: repeat(3, 1fr);
  }
}

.step {
  background: var(--ground);
  padding: 2rem 1.75rem;
}

.step-n {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  color: var(--red);
  font-variant-numeric: tabular-nums;
  margin-bottom: 1rem;
}

.step h3 {
  margin-bottom: 0.6rem;
}

.step p {
  font-size: 0.92rem;
  margin: 0;
}

/* ---------------------------------------------------------- témoignages */

.quote {
  font-size: clamp(1.15rem, 2.4vw, 1.6rem);
  line-height: 1.4;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-wrap: balance;
  margin: 0 0 1.25rem;
}

.quote-by {
  font-size: 0.82rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ---------------------------------------------------------------- forms */

.field {
  display: grid;
  gap: 0.45rem;
  /* Les lignes gardent leur hauteur naturelle. Sans cela, le champ d'une
     colonne s'étire jusqu'à la hauteur de la colonne voisine : une aide de
     trois lignes à droite donnait à gauche une case à date deux fois trop
     haute. */
  align-content: start;
}

.field label {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.field input,
.field textarea,
.field select {
  width: 100%;
  padding: 0.8rem 0.95rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  font: inherit;
  font-size: 0.95rem;
  transition: border-color 0.2s var(--ease), background 0.2s var(--ease);
}

.field input::placeholder,
.field textarea::placeholder {
  color: var(--muted);
}

.field input:focus,
.field textarea:focus,
.field select:focus {
  border-color: rgba(229, 9, 20, 0.55);
  background: var(--surface-lift);
  outline: none;
}

.field-error {
  font-size: 0.82rem;
  color: #ff6b6b;
}

/* Ce qu'on installe : un film, un karaoké, ou les deux.

   Trois choix courts, alignés, et nettement détachés des cartes de formule
   au-dessus : c'est une autre question que « laquelle », et la confondre avec
   le choix de la formule ferait cocher une réponse pour l'autre. */
.seance {
  margin-top: 2.25rem;
  padding: 1.5rem 0 0;
  border: 0;
  border-top: 1px solid var(--line);
}

.seance legend {
  padding: 0 0.85rem 0 0;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.seance-choices {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-top: 1rem;
}

.seance-choice {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.7rem 1.05rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  font-size: 0.92rem;
  cursor: pointer;
  transition: border-color 0.2s var(--ease), background 0.2s var(--ease);
}

.seance-choice:hover {
  background: var(--surface-lift);
}

.seance-choice:has(input:checked) {
  border-color: rgba(229, 9, 20, 0.55);
  background: var(--surface-lift);
}

.seance-choice input {
  accent-color: #e50914;
}

/* Repli pour les navigateurs sans :has() — le point reste coché et lisible,
   seul le cadre ne réagit pas. */
.seance-choice input:focus-visible {
  outline: 2px solid rgba(229, 9, 20, 0.55);
  outline-offset: 2px;
}

/* Une réponse déjà donnée, et non une question.

   L'heure de début est imposée : elle s'aligne sur les champs voisins pour ne
   pas trouer la grille, mais sans bordure de saisie ni fond d'entrée. Un
   champ en lecture seule gardait son cadre et son curseur, et invitait à
   cliquer sur ce qui ne se décide pas. */
.field-label {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
}

.field-fixed {
  padding: 0.8rem 0;
  margin: 0;
  font-size: 1.15rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}

.form-grid {
  display: grid;
  gap: 1.1rem;
  grid-template-columns: 1fr;
}

@media (min-width: 700px) {
  .form-grid {
    grid-template-columns: 1fr 1fr;
  }
  .form-grid .span-2 {
    grid-column: 1 / -1;
  }
}

.alert {
  padding: 0.95rem 1.15rem;
  border-radius: var(--radius);
  font-size: 0.92rem;
  border: 1px solid;
  margin-bottom: 1.5rem;
}

.alert-ok {
  border-color: rgba(15, 185, 129, 0.35);
  background: rgba(15, 185, 129, 0.1);
  color: #6ee7b7;
}

.alert-bad {
  border-color: rgba(229, 9, 20, 0.4);
  background: rgba(229, 9, 20, 0.1);
  color: #ff9c9c;
}

/* --------------------------------------------------------------- footer */

.footer {
  border-top: 1px solid var(--line-soft);
  padding-block: clamp(3rem, 6vw, 4.5rem) 2.5rem;
  background: var(--ground-deep);
}

.footer-grid {
  display: grid;
  gap: 2.5rem;
  grid-template-columns: 1fr;
  margin-bottom: 3rem;
}

@media (min-width: 760px) {
  .footer-grid {
    grid-template-columns: 1.4fr 1fr 1fr;
  }
}

.footer h4 {
  margin: 0 0 1rem;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}

.footer ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.6rem;
}

.footer a {
  font-size: 0.92rem;
  color: var(--ink-soft);
  transition: color 0.2s var(--ease);
}

.footer a:hover {
  color: var(--red);
}

.footer-base {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  justify-content: space-between;
  padding-top: 1.75rem;
  border-top: 1px solid var(--line-soft);
  font-size: 0.8rem;
  color: var(--muted);
}

/* ------------------------------------------------------------- révélations
   Apparition au défilement, pilotée par un IntersectionObserver.
   Sans JavaScript ou en mouvement réduit, tout reste visible. */

/* Le contenu est visible par défaut. C'est le script qui, seulement s'il peut
   réellement animer, pose `js-reveal` sur <html> et masque avant d'observer —
   ainsi rien ne disparaît si le JavaScript échoue ou n'est pas exécuté. */
.js-reveal .reveal {
  opacity: 0;
  translate: 0 18px;
  transition: opacity 0.7s var(--ease), translate 0.7s var(--ease);
}

.js-reveal .reveal.is-in {
  opacity: 1;
  translate: 0 0;
}

.js-reveal .reveal:nth-child(2) {
  transition-delay: 60ms;
}
.js-reveal .reveal:nth-child(3) {
  transition-delay: 120ms;
}
.js-reveal .reveal:nth-child(4) {
  transition-delay: 180ms;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .beam {
    animation: none;
  }
}

/* ---------------------------------------------------------------- divers */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  background: var(--red);
  color: #fff;
  font-weight: 600;
  translate: 0 -110%;
  transition: translate 0.2s var(--ease);
}

.skip:focus {
  translate: 0 0;
}

/* Page d'un pack : contenu à gauche, tarif épinglé à droite sur large écran. */
@media (min-width: 940px) {
  .pack-layout {
    grid-template-columns: minmax(0, 1.55fr) minmax(300px, 1fr);
  }
}

/* --------------------------------------------------------- pages légales
   Documents lus en continu : mesure resserrée, hiérarchie discrète. */

.legal-doc h2 {
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin: 2.75rem 0 0.9rem;
  color: var(--ink);
}

.legal-doc h2:first-child {
  margin-top: 0;
}

.legal-doc p {
  font-size: 0.96rem;
  line-height: 1.7;
}

.legal-doc a {
  color: var(--red);
}

.legal-list {
  display: grid;
  gap: 0;
  margin: 0;
  border-top: 1px solid var(--line-soft);
}

.legal-list dt {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  padding-top: 0.85rem;
}

.legal-list dd {
  margin: 0 0 0.85rem;
  padding-bottom: 0.85rem;
  border-bottom: 1px solid var(--line-soft);
  color: var(--ink);
  font-size: 0.96rem;
}

@media (min-width: 620px) {
  .legal-list {
    grid-template-columns: 15rem 1fr;
    align-items: baseline;
  }
  .legal-list dt {
    padding-bottom: 0.85rem;
    border-bottom: 1px solid var(--line-soft);
    margin-bottom: 0;
  }
  .legal-list dd {
    padding-top: 0.85rem;
    margin-bottom: 0;
  }
}

.legal-updated {
  margin-top: 3rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line-soft);
  font-size: 0.85rem;
  color: var(--muted);
}

/* ------------------------------------------------------------------ galerie
   Mosaïque : la première photo occupe deux colonnes, le reste suit. La
   légende n'apparaît qu'au survol, mais reste lisible par les lecteurs
   d'écran via l'attribut alt de l'image. */

.mosaic {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: clamp(0.5rem, 1.2vw, 1rem);
  grid-template-columns: repeat(2, 1fr);
}

@media (min-width: 780px) {
  .mosaic {
    grid-template-columns: repeat(3, 1fr);
  }
  .mosaic-cell:first-child {
    grid-column: span 2;
    grid-row: span 2;
  }
}

.mosaic-cell {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  background: var(--surface);
  aspect-ratio: 4 / 3;
}

.mosaic-cell img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: scale 0.7s var(--ease), filter 0.5s var(--ease);
  filter: saturate(0.92);
}

.mosaic-cell:hover img {
  scale: 1.05;
  filter: saturate(1.05);
}

.mosaic-caption {
  position: absolute;
  inset: auto 0 0;
  padding: 2.5rem 1rem 0.9rem;
  font-size: 0.85rem;
  color: var(--ink);
  background: linear-gradient(transparent, rgba(6, 6, 7, 0.9));
  opacity: 0;
  translate: 0 0.5rem;
  transition: opacity 0.35s var(--ease), translate 0.35s var(--ease);
}

.mosaic-cell:hover .mosaic-caption,
.mosaic-cell:focus-within .mosaic-caption {
  opacity: 1;
  translate: 0 0;
}

/* ================================================================== tunnel
   Six étapes, une question par écran. La colonne de droite récapitule ce qui
   est déjà décidé pour que le visiteur ne perde jamais le fil. */

.funnel-count {
  font-family: inherit;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 1.75rem 0 0.75rem;
  font-variant-numeric: tabular-nums;
}

.funnel-grid {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem);
  grid-template-columns: 1fr;
  align-items: start;
}

@media (min-width: 940px) {
  .funnel-grid {
    grid-template-columns: minmax(0, 1.5fr) minmax(290px, 1fr);
  }
}

.funnel h1 {
  font-size: clamp(1.9rem, 4.4vw, 3rem);
}

/* ------------------------------------------------------------ progression */

.progress {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 0.35rem;
  overflow-x: auto;
  scrollbar-width: none;
}

.progress::-webkit-scrollbar {
  display: none;
}

.progress-step {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.75rem 0.4rem 0.55rem;
  border-radius: 999px;
  border: 1px solid var(--line-soft);
  white-space: nowrap;
  font-size: 0.78rem;
  color: var(--muted);
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease),
    background 0.3s var(--ease);
}

.progress-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.5;
  flex: none;
}

.progress-step.is-done {
  color: var(--ink-soft);
  border-color: var(--line);
}

.progress-step.is-done .progress-dot {
  background: var(--ok, #0fb981);
  opacity: 1;
}

.progress-step.is-current {
  color: var(--ink);
  border-color: rgba(229, 9, 20, 0.5);
  background: rgba(229, 9, 20, 0.08);
}

.progress-step.is-current .progress-dot {
  background: var(--red);
  opacity: 1;
  box-shadow: 0 0 10px rgba(229, 9, 20, 0.9);
}

/* Sur petit écran, seule l'étape en cours porte son libellé. */
@media (max-width: 720px) {
  .progress-step:not(.is-current) .progress-label {
    display: none;
  }
  .progress-step:not(.is-current) {
    padding: 0.4rem 0.55rem;
  }
}

/* ----------------------------------------------------------------- choix */

.choices {
  display: grid;
  gap: 0.7rem;
}

.choice {
  position: relative;
  display: block;
  cursor: pointer;
}

.choice input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.choice-body {
  display: block;
  padding: 1.05rem 1.25rem;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  background: var(--surface);
  transition: border-color 0.25s var(--ease), background 0.25s var(--ease),
    translate 0.25s var(--ease);
}

.choice:hover .choice-body {
  border-color: rgba(244, 239, 233, 0.2);
  translate: 0 -1px;
}

.choice input:checked + .choice-body {
  border-color: var(--red);
  background: rgba(229, 9, 20, 0.07);
}

.choice input:focus-visible + .choice-body {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}

.choice-body b {
  display: block;
  font-size: 1.02rem;
  font-weight: 650;
  letter-spacing: -0.02em;
  color: var(--ink);
}

.choice-body em {
  display: block;
  font-style: normal;
  font-size: 0.88rem;
  color: var(--ink-soft);
  margin-top: 0.2rem;
}

.choice-badge {
  display: inline-block;
  margin-bottom: 0.5rem;
  padding: 0.15rem 0.5rem;
  border-radius: 3px;
  background: var(--red);
  color: #fff;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.choice-price {
  display: block;
  margin-top: 0.75rem;
  padding-top: 0.65rem;
  border-top: 1px solid var(--line-soft);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.choice-price small {
  display: block;
  font-size: 0.78rem;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--muted);
  margin-top: 0.1rem;
}

/* -------------------------------------------------------------- actions */

.funnel-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2.25rem;
}

/* --------------------------------------------------------- récapitulatif */

.recap {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.4rem 1rem;
  margin: 0 0 1.25rem;
  font-size: 0.88rem;
}

.recap dt {
  color: var(--muted);
}

.recap dd {
  margin: 0;
  color: var(--ink);
  text-align: right;
}

.recap-lines {
  border-top: 1px solid var(--line-soft);
  padding-top: 0.85rem;
}

.recap-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.45rem 0;
  font-size: 0.88rem;
  color: var(--ink-soft);
}

.recap-line em {
  display: block;
  font-style: normal;
  font-size: 0.78rem;
  color: var(--muted);
}

.recap-line b {
  color: var(--ink);
  font-weight: 600;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.recap-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 0.5rem;
  padding-top: 0.85rem;
  border-top: 1px solid var(--line);
  font-size: 0.85rem;
  color: var(--muted);
}

.recap-total b {
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.04em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.recap-note {
  margin: 0.75rem 0 0;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--muted);
}

.recap-reset {
  display: inline-block;
  margin-top: 1.5rem;
  font-size: 0.8rem;
  color: var(--muted);
  border-bottom: 1px solid var(--line);
  transition: color 0.2s var(--ease);
}

.recap-reset:hover {
  color: var(--red);
}

/* Première étape : pas encore de récapitulatif, la question occupe la largeur. */
.funnel-grid.is-single {
  grid-template-columns: minmax(0, 1fr);
  max-width: 46rem;
}

/* -------------------------------------------------------- espace client */

.next-grid {
  grid-template-columns: 1fr;
}

@media (min-width: 760px) {
  .next-grid {
    grid-template-columns: 1.4fr 1fr;
    gap: 2.5rem;
  }
}

.countdown {
  padding: 1rem 1.25rem;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  background: var(--surface);
  text-align: center;
}

.countdown b {
  display: block;
  font-size: 2.6rem;
  font-weight: 800;
  letter-spacing: -0.05em;
  line-height: 1;
  color: var(--red);
  font-variant-numeric: tabular-nums;
}

.countdown span {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.8rem;
  color: var(--muted);
}

.pill-status {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  white-space: nowrap;
  background: rgba(244, 239, 233, 0.07);
  color: var(--ink-soft);
}

.pill-confirmed,
.pill-scheduled,
.pill-packed {
  background: rgba(15, 185, 129, 0.14);
  color: #4ade9f;
}

.pill-paid,
.pill-done {
  background: rgba(245, 177, 76, 0.14);
  color: var(--amber);
}

.pill-cancelled {
  background: rgba(229, 9, 20, 0.14);
  color: #ff8a8a;
}

/* ==========================================================================
   La séance — couche vitrine
   --------------------------------------------------------------------------
   Tout ce qui suit sert un seul propos : montrer le produit au lieu de le
   décrire. Les photos et les vidéos portent la couleur ; le fond ne fait que
   les tenir. Chaque effet est écrit pour se désactiver proprement — sans JS,
   sans IntersectionObserver ou en mouvement réduit, la page reste lisible et
   entièrement visible, elle cesse simplement de bouger.
   ========================================================================== */

/* ------------------------------------------------------------ atmosphère */

/* Quelques lueurs qui dérivent en fond, à la manière des lanternes hors champ.
   Purement CSS : aucune boucle JS ne tourne pour ça. */
.bokeh {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}

.bokeh i {
  position: absolute;
  display: block;
  border-radius: 50%;
  filter: blur(60px);
  opacity: 0.5;
}

.bokeh i:nth-child(1) {
  width: 38vw; height: 38vw; top: 6%; left: -8%;
  background: radial-gradient(circle, rgba(245, 177, 76, 0.22), transparent 70%);
  animation: float-a 34s var(--ease-soft) infinite alternate;
}
.bokeh i:nth-child(2) {
  width: 30vw; height: 30vw; top: 48%; right: -6%;
  background: radial-gradient(circle, rgba(46, 90, 99, 0.42), transparent 70%);
  animation: float-b 41s var(--ease-soft) infinite alternate;
}
.bokeh i:nth-child(3) {
  width: 24vw; height: 24vw; bottom: 4%; left: 28%;
  background: radial-gradient(circle, rgba(180, 87, 58, 0.24), transparent 70%);
  animation: float-a 47s var(--ease-soft) infinite alternate-reverse;
}

@keyframes float-a { from { translate: 0 0; scale: 1; } to { translate: 6vw -4vh; scale: 1.18; } }
@keyframes float-b { from { translate: 0 0; scale: 1.1; } to { translate: -5vw 5vh; scale: 0.92; } }

/* Halo qui suit la souris : la lampe qu'on promène sur la page.
   Positionné par JS via --mx / --my, inerte tant qu'ils ne sont pas posés. */
.glow {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1;
  width: 46rem;
  height: 46rem;
  pointer-events: none;
  translate: calc(var(--mx, 50vw) - 50%) calc(var(--my, 50vh) - 50%);
  background: radial-gradient(circle, rgba(245, 177, 76, 0.09), transparent 62%);
  opacity: 0;
  transition: opacity 0.6s var(--ease);
}

.js-motion .glow { opacity: 1; }

/* ------------------------------------------------------------- le rideau */

/* Transition entre les pages : un fondu au noir court, à la coupure de bobine.
   Le voile ne bloque jamais les clics, et une page qui n'aboutit pas se
   redécouvre toute seule au retour arrière. */
.pageveil {
  position: fixed;
  inset: 0;
  z-index: 9998;
  pointer-events: none;
  background: var(--ground-deep);
  opacity: 0;
  transition: opacity 0.3s var(--ease);
}

.pageveil.is-on { opacity: 1; }

/* --------------------------------------------------------------- curseur */

/* Un anneau qui suit le pointeur et s'ouvre sur ce qui est cliquable.
   Réservé aux pointeurs précis : au doigt, il n'existe pas. */
.cursor,
.cursor-dot {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9997;
  pointer-events: none;
  border-radius: 50%;
  opacity: 0;
}

.cursor {
  width: 34px;
  height: 34px;
  border: 1px solid rgba(245, 177, 76, 0.55);
  transition: width 0.3s var(--ease), height 0.3s var(--ease),
    background 0.3s var(--ease), border-color 0.3s var(--ease), opacity 0.3s;
}

.cursor-dot {
  width: 5px;
  height: 5px;
  background: var(--amber);
  transition: opacity 0.3s, scale 0.3s var(--ease);
}

.cursor.is-live,
.cursor-dot.is-live { opacity: 1; }

.cursor.is-hot {
  width: 62px;
  height: 62px;
  background: rgba(245, 177, 76, 0.1);
  border-color: rgba(245, 177, 76, 0.9);
}

.cursor-dot.is-hot { scale: 0; }

@media (hover: none), (pointer: coarse) {
  .cursor, .cursor-dot, .glow { display: none; }
}

/* ------------------------------------------------------------------ hero */

/* Plein cadre, vidéo au fond. C'est la première chose que voit un client :
   autant lui montrer une vraie soirée plutôt qu'une phrase. */
.stage {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 100svh;
  padding: 0;
  overflow: hidden;
  isolation: isolate;
}

.stage-media {
  position: absolute;
  inset: 0;
  z-index: -2;
}

.stage-media video,
.stage-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Un très léger repoussoir : la vidéo doit rester un décor, pas rivaliser
     avec le texte posé dessus. */
  filter: saturate(1.05) contrast(1.03);
}

/* Le voile : ce qui rend le texte lisible quelle que soit l'image dessous. */
.stage-veil {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(
      180deg,
      rgba(13, 17, 23, 0.74) 0%,
      rgba(13, 17, 23, 0.26) 34%,
      rgba(13, 17, 23, 0.64) 70%,
      var(--ground) 100%
    ),
    radial-gradient(115% 75% at 18% 70%, rgba(13, 17, 23, 0) 26%, rgba(13, 17, 23, 0.62) 100%);
}

.stage .wrap {
  padding-block: clamp(6rem, 14vh, 9rem) clamp(2.5rem, 6vh, 4rem);
}

.stage h1 {
  font-size: clamp(2.5rem, 7.6vw, 5.4rem);
  margin-bottom: 1.5rem;
}

.stage h1 em {
  font-style: normal;
  color: var(--amber);
  text-shadow: 0 0 42px rgba(245, 177, 76, 0.4);
}

.stage .lede { max-width: 40ch; }

/* Le titre monte mot à mot. L'état masqué n'existe que si le JS a pris la
   main : sinon la phrase est simplement là, immobile. */
.wordmask { display: inline-block; overflow: hidden; vertical-align: bottom; }
.wordmask > span { display: inline-block; }

.js-motion .stage h1 .wordmask > span {
  translate: 0 110%;
  animation: word-rise 1s var(--ease) both;
  animation-delay: calc(var(--i, 0) * 65ms + 120ms);
}

@keyframes word-rise {
  from { translate: 0 110%; }
  to { translate: 0 0; }
}

/* Invitation à descendre : un trait qui se remplit en boucle. */
.stage-cue {
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  margin-top: 2.5rem;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
}

.stage-cue::after {
  content: '';
  width: 1px;
  height: 46px;
  background: linear-gradient(180deg, var(--amber), transparent);
  transform-origin: top;
  animation: cue 2.4s var(--ease-soft) infinite;
}

@keyframes cue {
  0%   { scale: 1 0; opacity: 0; }
  35%  { scale: 1 1; opacity: 1; }
  100% { scale: 1 1; opacity: 0; translate: 0 18px; }
}

/* Le son se coupe et se rallume — la vidéo est muette par défaut, mais on
   laisse la main plutôt que de l'imposer. */
.stage-controls {
  position: absolute;
  right: var(--gutter);
  bottom: clamp(2.5rem, 6vh, 4rem);
  display: flex;
  gap: 0.5rem;
  z-index: 3;
}

.stage-controls button {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: rgba(13, 17, 23, 0.55);
  backdrop-filter: blur(8px);
  color: var(--ink-soft);
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease);
}

.stage-controls button:hover {
  border-color: rgba(245, 177, 76, 0.6);
  color: var(--amber);
}

/* --------------------------------------------------------------- bandeau */

/* Un bandeau qui défile sans fin, comme un générique. Il tient lieu de
   respiration entre deux sections et rappelle ce qui est compris. */
.ticker {
  padding: 0;
  overflow: hidden;
  border-block: 1px solid var(--line-soft);
  background: rgba(20, 26, 34, 0.55);
}

.ticker-track {
  display: flex;
  align-items: center;
  gap: 2.75rem;
  width: max-content;
  padding-block: 1rem;
  white-space: nowrap;
}

.js-motion .ticker-track { animation: slide 42s linear infinite; }
.ticker:hover .ticker-track { animation-play-state: paused; }

@keyframes slide { to { translate: -50% 0; } }

.ticker-item {
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.ticker-item::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--amber);
  box-shadow: 0 0 10px rgba(245, 177, 76, 0.9);
  flex: none;
}

/* --------------------------------------------------------------- parcours */

/* Le récit d'une soirée, déroulé au défilement : le texte descend pendant que
   l'image reste, et change à chaque étape. C'est la partie qui explique. */
.journey {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 6vw, 5rem);
  align-items: start;
}

.journey-media {
  position: sticky;
  top: 110px;
  aspect-ratio: 4 / 5;
  border-radius: 8px;
  overflow: hidden;
  background: var(--ground-deep);
  border: 1px solid var(--line-soft);
}

.journey-shot {
  position: absolute;
  inset: 0;
  opacity: 0;
  scale: 1.07;
  transition: opacity 0.8s var(--ease), scale 2.4s var(--ease);
}

html:not(.js) .journey-shot:first-child,
.journey-shot:first-child { opacity: 1; scale: 1; }
.journey-shot.is-on { opacity: 1; scale: 1; }

.journey-shot img,
.journey-shot video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Numéro de l'étape, incrusté sur l'image. */
.journey-tag {
  position: absolute;
  left: 1.25rem;
  bottom: 1.25rem;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.5rem 0.95rem;
  border-radius: 100px;
  background: rgba(13, 17, 23, 0.7);
  backdrop-filter: blur(10px);
  border: 1px solid var(--line);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.journey-steps { display: flex; flex-direction: column; }

.journey-step {
  min-height: 72vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-block: 2rem;
  transition: opacity 0.6s var(--ease);
}

/* La mise en retrait n'existe que si quelque chose vient les rallumer :
   sans JS, ou en mouvement réduit, toutes les étapes restent lisibles. */
.js-motion .journey-step { opacity: 0.32; }
.js-motion .journey-step.is-on { opacity: 1; }

.journey-step h3 {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  margin-bottom: 0.9rem;
}

.journey-n {
  font-family: var(--font-display);
  font-size: 0.85rem;
  letter-spacing: 0.2em;
  color: var(--amber);
  margin-bottom: 1rem;
}

@media (max-width: 900px) {
  .journey { grid-template-columns: 1fr; }
  .journey-media { position: relative; top: auto; aspect-ratio: 3 / 2; }
  .journey-step { min-height: 0; padding-block: 1.5rem; opacity: 1; }
}

/* -------------------------------------------------------------- formules */

/* Les cartes formule montrent d'abord une photo. Le prix vient après :
   personne ne choisit une soirée sur un tarif. */
.packs { align-items: stretch; }

.pack {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  background: var(--surface);
  transition: translate 0.45s var(--ease), border-color 0.45s var(--ease),
    box-shadow 0.45s var(--ease);
}

.pack::before { display: none; }

.pack:hover {
  translate: 0 -6px;
  border-color: rgba(245, 177, 76, 0.35);
  box-shadow: 0 26px 60px -30px rgba(0, 0, 0, 0.9);
}

.pack-media {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--ground-deep);
}

.pack-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: scale 1.1s var(--ease);
}

.pack:hover .pack-media img { scale: 1.07; }

/* L'aperçu vidéo ne se charge qu'au survol, et seulement là où survoler
   veut dire quelque chose. */
.pack-media video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.6s var(--ease);
}

.pack:hover .pack-media video { opacity: 1; }

.pack-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(13, 17, 23, 0) 40%, rgba(20, 26, 34, 0.95) 100%);
}

.pack-body {
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: clamp(1.25rem, 2.5vw, 1.75rem);
}

.pack-cat {
  position: absolute;
  top: 1rem;
  left: 1rem;
  z-index: 2;
  margin: 0;
  padding: 0.4rem 0.8rem;
  border-radius: 100px;
  background: rgba(13, 17, 23, 0.72);
  backdrop-filter: blur(10px);
  border: 1px solid var(--line);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
}

.pack-price {
  margin-top: auto;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line-soft);
}

.pack .price b { color: var(--amber); }

/* --------------------------------------------------------- le sélecteur */

/* Un avant-goût du tunnel, posé sur la page d'accueil : on choisit l'occasion,
   la formule conseillée apparaît. Ce n'est pas un gadget — la réponse est
   emportée dans le tunnel, la question n'est pas posée deux fois. */
.picker {
  border: 1px solid var(--line-soft);
  border-radius: 12px;
  background: linear-gradient(160deg, var(--surface), rgba(13, 17, 23, 0.6));
  padding: clamp(1.5rem, 4vw, 2.5rem);
}

.picker-options {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-bottom: 1.75rem;
}

.picker-options button {
  padding: 0.7rem 1.15rem;
  border: 1px solid var(--line);
  border-radius: 100px;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--ink-soft);
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease),
    background 0.25s var(--ease);
}

.picker-options button:hover {
  border-color: rgba(245, 177, 76, 0.5);
  color: var(--ink);
}

.picker-options button[aria-pressed='true'] {
  background: rgba(245, 177, 76, 0.12);
  border-color: var(--amber);
  color: var(--amber);
}

.picker-result {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line-soft);
}

/* Les photos de prestation sont en paysage : un carré les massacre. */
.picker-result img {
  width: 132px;
  aspect-ratio: 4 / 3;
  border-radius: 8px;
  object-fit: cover;
  flex: none;
}

@media (max-width: 700px) {
  .picker-result img { width: 92px; }
}

.picker-result b {
  display: block;
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 600;
}

.picker-result span { color: var(--ink-soft); font-size: 0.9rem; }
.picker-result .price b { color: var(--amber); font-family: var(--font); }

@media (max-width: 700px) {
  .picker-result { grid-template-columns: auto 1fr; }
  .picker-result .btn { grid-column: 1 / -1; }
}

/* Sans JS le sélecteur n'a pas de sens : on le remplace par le lien direct. */
html:not(.js) .picker-live { display: none; }
.js .picker-static { display: none; }

/* ------------------------------------------------- galerie en travelling */

/* Une bande de photos qui défile latéralement pendant que la page descend.
   Sans JS c'est un simple défilement horizontal au doigt : rien ne casse. */
.rail { padding: 0; }

.rail-head { padding-block: clamp(4.5rem, 11vw, 8.5rem) clamp(2rem, 4vw, 3rem); }
.rail-head .section-head { margin-bottom: 0; }

/* La suite de la galerie, une fois la bande parcourue. */
.rail-after { padding-block: clamp(2.5rem, 6vw, 4rem) clamp(4.5rem, 11vw, 8.5rem); }

.rail-pin {
  display: flex;
  align-items: center;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  padding-block: clamp(3rem, 8vw, 5rem);
}

.rail-pin::-webkit-scrollbar { display: none; }
.rail-pin { scrollbar-width: none; }

.rail-track {
  display: flex;
  gap: clamp(0.9rem, 1.8vw, 1.5rem);
  padding-inline: var(--gutter);
}

/* Le travelling n'est pas gratuit : il confisque le défilement vertical le
   temps de traverser la bande. Sur une souris on comprend, on peut reprendre
   la main d'un cran. Au doigt non : on pousse vers le haut et ce sont les
   photos qui partent sur le côté, la page semble bloquée. La classe n'est
   donc posée que là où le procédé se tient — pointeur fin, écran large — et
   partout ailleurs la bande redevient ce qu'elle est au repos : un simple
   défilement latéral au doigt, avec son calage sur les photos. */
.rail.is-pinned .rail-pin {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  padding-block: 0;
}

.rail.is-pinned .rail-track { will-change: transform; }

.rail-card {
  position: relative;
  /* Les cartes se dimensionnent par la hauteur : la bande occupe un écran
     entier, une largeur imposée y laissait deux tiers de vide. */
  flex: 0 0 auto;
  height: min(58svh, 480px);
  aspect-ratio: 3 / 4;
  /* <figure> conserve sa marge de 40 px par défaut, qui creusait un trou de
     quatre-vingts pixels entre chaque photo. */
  margin: 0;
  border-radius: 8px;
  overflow: hidden;
  scroll-snap-align: center;
  background: var(--ground-deep);
  border: 1px solid var(--line-soft);
}

.rail-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: scale 1.2s var(--ease);
}

.rail-card:hover img { scale: 1.05; }

.rail-card figcaption {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  padding: 2.5rem 1.1rem 1.1rem;
  background: linear-gradient(180deg, transparent, rgba(8, 11, 16, 0.92));
  font-size: 0.82rem;
  line-height: 1.4;
  color: var(--ink-soft);
}

/* ---------------------------------------------------------- les chiffres */

.figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  overflow: hidden;
}

.figure {
  background: rgba(20, 26, 34, 0.7);
  padding: clamp(1.5rem, 3.5vw, 2.25rem);
}

.figure b {
  display: block;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.2rem, 5vw, 3.4rem);
  line-height: 1;
  color: var(--amber);
  font-variant-numeric: tabular-nums;
}

.figure span {
  display: block;
  margin-top: 0.6rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}

/* --------------------------------------------------------- apparitions */

/* Décalage d'apparition : chaque élément porte son rang en --i. */
.js-reveal .reveal { transition-delay: calc(var(--i, 0) * 80ms); }

/* Bandeau final : une photo pleine largeur, et une seule chose à faire. */
.closer {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.closer-media {
  position: absolute;
  inset: 0;
  z-index: -2;
}

.closer-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.closer::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(90deg, rgba(8, 11, 16, 0.94) 8%, rgba(8, 11, 16, 0.55) 62%, rgba(8, 11, 16, 0.8) 100%);
}

/* ------------------------------------------------------- mouvement réduit */

@media (prefers-reduced-motion: reduce) {
  .bokeh i,
  .ticker-track,
  .stage-cue::after,
  .beam {
    animation: none !important;
  }

  .glow { display: none; }

  .journey-shot { transition-duration: 0.01ms; }
}

/* ------------------------------------------------- le choix de la formule

   L'étape « formule » est la seule décision du tunnel qui se prend à l'œil :
   on y ajoute la photo de la formule, à gauche du texte. Les autres étapes
   gardent leur choix en texte seul — y coller une image serait décoratif. */

.choice-body.has-shot {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1.15rem;
  align-items: start;
  padding: 1rem;
}

.choice-shot {
  width: 108px;
  height: 108px;
  border-radius: 6px;
  object-fit: cover;
  background: var(--ground-deep);
}

.choice:hover .choice-shot { filter: brightness(1.08); }

@media (max-width: 520px) {
  .choice-body.has-shot { grid-template-columns: auto 1fr; gap: 0.9rem; }
  .choice-shot { width: 76px; height: 76px; }
}

/* Ouverture d'une page intérieure : même principe que le hero, en plus court.
   Une image plutôt qu'une vidéo — sur une page de formule, ce qui compte est
   de reconnaître la formule, pas d'être ébloui. */
.stage-short {
  min-height: min(62svh, 34rem);
  justify-content: flex-end;
}

.stage-short .wrap {
  padding-block: clamp(5rem, 12vh, 7rem) clamp(2rem, 5vh, 3rem);
}

.stage-short h1 { font-size: clamp(2.2rem, 5.6vw, 4rem); }

/* Une photo de formule peut être claire — sable, drap blanc, plaid rouge vif.
   Le voile du hero, calibré pour une vidéo de nuit, n'y suffit pas : on ajoute
   un dégradé latéral pour que la colonne de texte reste lisible quelle que
   soit l'image dessous. */
.stage-short .stage-veil {
  background:
    linear-gradient(
      180deg,
      rgba(13, 17, 23, 0.7) 0%,
      rgba(13, 17, 23, 0.42) 38%,
      rgba(13, 17, 23, 0.88) 86%,
      var(--ground) 100%
    ),
    linear-gradient(
      90deg,
      rgba(8, 11, 16, 0.9) 0%,
      rgba(8, 11, 16, 0.55) 42%,
      rgba(8, 11, 16, 0.12) 78%
    );
}
