/* alphaware, fiche produit, gabarit commun aux seize jeux.
   Traduction en classes des styles inline de « alphaware Jeu Rust.dc.html »,
   la maquette ne dessinait que Rust.
   Les valeurs (couleurs, tailles, rayons, transitions) sont celles de la
   maquette : le handoff demande une reproduction fidèle. */

/* Décor de fond, sous le contenu, non interactif. La lueur de la fiche est
   décalée à gauche (42 %), derrière le titre. */
.deco-grid,
.deco-glow {
  position: absolute;
  left: 0;
  right: 0;
  pointer-events: none;
}

.deco-grid {
  top: 0;
  height: 760px;
  background-image:
    linear-gradient(rgba(255, 255, 255, .045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .045) 1px, transparent 1px);
  background-size: 64px 64px;
  -webkit-mask-image: radial-gradient(120% 60% at 50% 0%, #000 0%, rgba(0, 0, 0, .3) 45%, transparent 78%);
  mask-image: radial-gradient(120% 60% at 50% 0%, #000 0%, rgba(0, 0, 0, .3) 45%, transparent 78%);
}

.deco-glow {
  top: -340px;
  height: 720px;
  background: radial-gradient(560px 360px at 42% 50%, var(--glow-fiche), transparent);
}

/* Colonne de contenu. content-box volontaire : la maquette limite la zone de
   contenu à 1080px, les 32px de marge viennent en plus. */
.wrap {
  position: relative;
  box-sizing: content-box;
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 32px;
}

/* Navigation */
.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  height: 78px;
}

/* Le mot de la marque porte un alpha grec, absent des polices du site : il
   retombe sur une police système, nommée dans --titre-marque pour que la
   retombée soit la même d'une machine à l'autre. Voir base.css. */
.nav__brand {
  font: 700 18px var(--titre-marque);
  letter-spacing: -.03em;
  color: var(--text-strong);
}

/* C'est un lien vers l'accueil : il doit réagir comme les autres. */
.nav__brand:hover { color: var(--accent-text) }

/* Les liens font 18px de haut avec leur seul texte, sous le minimum de 24
   pour une cible de pointage. Le rembourrage vertical les y porte sans rien
   changer à l'allure de la barre. */
.nav__links {
  display: flex;
  align-items: center;
  gap: 30px;
  font: 400 14px var(--texte);
  color: var(--text-2);
}

.nav__cta {
  font: 500 13.5px var(--texte);
  color: var(--bg);
  background: var(--btn-light);
  padding: 9px 18px;
  border-radius: 100px;
  white-space: nowrap;
}

.nav__cta:hover {
  color: var(--bg);
  background: var(--btn-light-hover);
}

/* Boutons partagés */
.btn-solid,
.btn-ghost,
.btn-accent {
  font: 500 15px var(--texte);
  border-radius: 100px;
  white-space: nowrap;
}

.btn-solid {
  color: var(--bg);
  background: var(--btn-light);
  padding: 15px 30px;
}

.btn-solid:hover {
  color: var(--bg);
  background: var(--btn-light-hover);
}

.btn-accent {
  color: var(--text-strong);
  background: var(--accent);
  padding: 15px 30px;
}

.btn-accent:hover { background: var(--accent-hover) }

.btn-ghost {
  color: var(--text-ghost);
  border: 1px solid var(--bd-ghost);
  padding: 14px 26px;
}

.btn-ghost:hover {
  color: var(--text-ghost);
  border-color: var(--bd-ghost-hover);
}

/* Hero. Le bloc d'achat vivait à droite du texte, en deuxième colonne. Les
   plans sont passés en trois cartes pleine largeur dessous : le hero n'a plus
   qu'une colonne, et il laissait sa moitié droite vide. Il est donc centré,
   comme sur la boutique du propriétaire.
   Les éléments entrent en cascade, chacun un peu après le précédent. Le retard
   est posé en CSS sur la position dans le bloc : la politique de contenu
   interdit les styles inline, donc aucun délai écrit depuis le script. */
.hero {
  position: relative;
  padding: 72px 0 0;
  text-align: center;
}

/* Couverture du produit, derrière le hero. Elle déborde volontairement du
   conteneur, jusqu'aux bords de la fenêtre : un bandeau qui s'arrête net à
   1080px se lit comme une image posée, pas comme un fond.
   Elle est fondue vers le bas et sur les côtés, sinon le titre passait sur une
   zone claire de l'illustration et devenait illisible. */
.hero__couv {
  position: absolute;
  top: -78px;
  left: 50%;
  width: 100vw;
  max-width: none;
  height: 340px;
  margin-left: -50vw;
  object-fit: cover;
  object-position: center 32%;
  opacity: .34;
  pointer-events: none;
  -webkit-mask-image: radial-gradient(120% 100% at 50% 0%, #000 12%, rgba(0, 0, 0, .45) 48%, transparent 82%);
  mask-image: radial-gradient(120% 100% at 50% 0%, #000 12%, rgba(0, 0, 0, .45) 48%, transparent 82%);
}

/* Le contenu du hero passe devant la couverture. */
.retour,
.hero__col { position: relative; z-index: 1 }

/* Retour au catalogue. Une flèche discrète, calée en tête et à gauche : c'est
   un geste de sortie, il ne doit pas peser autant qu'un bouton d'achat. */
/* Calée en haut à gauche, hors du flux : le hero est centré, une flèche
   centrée avec le reste aurait eu l'air d'un bouton de plus. */
/* Calée en haut à gauche, hors du flux : le hero est centré, une flèche
   centrée avec le reste aurait eu l'air d'un bouton de plus.
   Le rembourrage vertical porte la cible à 24px de haut : le texte seul n'en
   faisait que 16, sous le minimum d'une cible de pointage. */
.retour {
  position: absolute;
  top: 12px;
  left: 0;
  padding: 6px 2px;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font: 400 13.5px var(--texte);
  color: var(--text-4);
  transition: color .2s ease;
}

.retour:hover { color: var(--text) }

.retour__fleche {
  width: 7px;
  height: 7px;
  border-left: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  transition: transform .25s var(--ease);
}

/* La flèche recule d'un cheveu au survol, dans le sens du geste. */
.retour:hover .retour__fleche { transform: rotate(45deg) translate(2px, -2px) }

.hero__col { min-width: 0 }

.hero__logo {
  display: block;
  width: 52px;
  height: 52px;
  margin: 26px auto 0;
}

.hero__title {
  margin-top: 18px;
  font: 600 64px/1.05 var(--titre);
  letter-spacing: -.04em;
  color: var(--text-strong);
}

.hero__text {
  margin: 20px auto 0;
  max-width: 52ch;
  font: 400 16px/1.7 var(--texte);
  color: var(--text-2);
  text-wrap: pretty;
}

/* Entrée en cascade. `both` garde l'état de départ avant le début du retard,
   sinon chaque élément clignote une fois à pleine opacité avant de partir. */
.hero .retour,
.hero__logo,
.hero__title,
.hero__text,
.hero__garantie {
  animation: monte .7s var(--ease) both;
}

.hero .retour { animation-delay: .02s }
.hero__logo { animation-delay: .08s }
.hero__title { animation-delay: .16s }
.hero__text { animation-delay: .24s }
.hero__garantie { animation-delay: .32s }

@keyframes monte {
  from { opacity: 0; transform: translateY(12px) }
  to { opacity: 1; transform: none }
}

/* Le mouvement est un agrément, pas une information : qui demande moins
   d'animation reçoit le contenu en place, sans rien perdre. */
@media (prefers-reduced-motion: reduce) {
  .hero .retour,
  .hero__logo,
  .hero__title,
  .hero__text,
  .hero__garantie { animation: none }

  .retour:hover .retour__fleche { transform: rotate(45deg) }
}


/* Achat. Trois cartes de plan côte à côte, une par palier, reprises de la
   boutique du propriétaire. Le champ mail, le choix du moyen de paiement et
   l'écran de confirmation ont disparu avec le passage à Stripe, qui collecte
   l'adresse et encaisse de son côté. */
.achat { padding: 88px 0 0 }

.plans {
  display: grid;
  /* Autant de colonnes que de plans : un jeu vendu à vie seulement n'en a
     qu'un, le catalogue tranche. Une carte seule ne doit pas s'étirer sur
     toute la largeur, d'où la borne. */
  grid-template-columns: repeat(auto-fit, minmax(0, 340px));
  justify-content: center;
  gap: 20px;
  margin-top: 26px;
}

.plan {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 30px;
  border: 1px solid var(--bd-card);
  border-radius: 20px;
  background: var(--surface-accent);
}

.plan:hover { border-color: var(--bd-card-hover) }

/* Le plan mis en avant par le catalogue, celui du milieu sur trois. */
.plan--fort { border-color: var(--accent-bd-soft) }

/* Le plan sur lequel on a cliqué reste marqué : sans ça, rien ne dit lequel a
   été retenu tant que Stripe n'a pas répondu. */
.plan.is-active { border-color: var(--accent-bd) }

.plan__tete {
  display: flex;
  align-items: baseline;
  gap: 9px;
}

.plan__nom {
  font: 600 13.5px/1.4 var(--texte);
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--text-2);
}

.plan__badge {
  padding: 3px 8px;
  border: 1px solid var(--accent-bd-soft);
  border-radius: 999px;
  font: 600 11px/1.3 var(--texte);
  color: var(--accent-text);
}

/* La période était posée à côté du montant, sur la même ligne. « une fois, pas
   de renouvellement » n'y tenait pas : le montant se coupait, « 100 » restait
   seul et « € » tombait à la ligne. Elle passe dessous, et le montant ne se
   coupe plus. */
.plan__prix { display: block }

.plan__montant {
  display: block;
  font: 700 44px/1 var(--titre);
  letter-spacing: -.02em;
  color: var(--text-strong);
  white-space: nowrap;
}

.plan__periode {
  display: block;
  margin-top: 7px;
  font: 400 13.5px/1.4 var(--texte);
  color: var(--text-3);
}

.plan__args {
  display: flex;
  flex-direction: column;
  gap: 9px;
  margin: 0;
  padding: 0;
  list-style: none;
  /* Les arguments poussent le bouton en bas : sur trois cartes de hauteurs
     différentes, les boutons étaient décalés les uns des autres. */
  flex: 1;
}

.plan__arg {
  position: relative;
  padding-left: 19px;
  font: 400 13.5px/1.5 var(--texte);
  color: var(--text-3);
}

.plan__arg::before {
  content: '';
  position: absolute;
  left: 0;
  top: 8px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent-fill);
}

.plan__cta {
  padding: 13px 18px;
  border-radius: 10px;
  background: var(--btn-light);
  font: 600 14px/1 var(--texte);
  color: var(--bg);
  text-align: center;
}

.plan__cta:hover { background: var(--btn-light-hover) }

/* La garantie, en pastille, à la place de la note du hero. Elle a vécu en
   12,5px gris sous la grille des plans, où personne ne la lisait, puis sur
   chaque carte de plan, ce qui la répétait trois fois à dix centimètres
   d'intervalle. Une seule, en tête de fiche, avant même les prix.
   Le vert des tokens `--ok` la distingue sans crier : ce n'est pas un argument
   de vente de plus, c'est un filet.
   `flex` et non `inline-flex` : un élément de ligne ignore les marges auto et
   la pastille restait collée à gauche. */
.hero__garantie {
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 8px;
  margin: 22px auto 0;
  padding: 8px 15px 8px 12px;
  border: 1px solid var(--ok-bd);
  border-radius: 999px;
  background: var(--ok-bg);
  font: 600 12.5px/1.3 var(--texte);
  color: var(--ok);
}

/* Le bouclier suit la couleur du texte et se met à l'échelle avec lui. */
.garantie__icone {
  flex: none;
  width: 15px;
  height: 15px;
}


/* Ce que coûteraient les mêmes jeux pris un par un, barré au dessus du prix
   du pack. Sur le pack seul : c'est le catalogue qui pose la valeur. */
.plan__avant {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 7px;
}

.plan__barre {
  font: 500 16px var(--texte);
  color: var(--text-4);
  text-decoration-thickness: 1px;
}

.plan__remise {
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--accent-fill);
  /* Le texte est celui du fond du site : blanc sur --accent-fill tombe à 3,9
     pour 1, sous le seuil exigé à cette taille. Le fond sombre donne 5,0. */
  color: var(--bg);
  font: 700 12px/1.4 var(--texte);
  white-space: nowrap;
}

/* Le plan et la comparaison côte à côte, sur le pack seul. Une carte unique
   flottait au milieu d'une section vide, et le seul argument du pack était
   relegué vingt centimètres plus bas, en gris. Un jeu, qui a deux ou trois
   cartes et rien à comparer, garde la grille centrée. */
.achat--pack .achat__duo {
  display: grid;
  grid-template-columns: minmax(0, 350px) minmax(0, 1fr);
  gap: 20px;
  align-items: stretch;
  margin-top: 26px;
}

.achat--pack .plans {
  margin-top: 0;
  grid-template-columns: minmax(0, 1fr);
}

.compare {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 28px 30px;
  border: 1px solid var(--accent-bd-soft);
  border-radius: 20px;
  background:
    radial-gradient(120% 150% at 100% 0%, var(--shot-lueur), transparent 62%),
    var(--surface-accent);
}

.compare__titre {
  margin: 0;
  font: 700 19px/1.2 var(--titre);
  letter-spacing: -.025em;
  color: var(--text-strong);
}

.compare__lignes {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.compare__tete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 9px;
}

.compare__label {
  font: 400 13.5px/1.4 var(--texte);
  color: var(--text-3);
}

.compare__val {
  font: 700 20px/1 var(--titre);
  letter-spacing: -.03em;
  color: var(--text-4);
  white-space: nowrap;
}

.compare__ligne--fort .compare__label { color: var(--text-2) }

.compare__ligne--fort .compare__val {
  font-size: 28px;
  color: var(--text-strong);
}

/* La barre est un progress : sa longueur vient de sa valeur posée en attribut,
   et non d'une largeur écrite en style inline, que la politique de contenu du
   site interdit. Elle redit ce que disent les montants à côté, d'où
   aria-hidden sur l'élément. */
.compare__jauge {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  height: 10px;
  border: 0;
  border-radius: 999px;
  background: var(--field);
}

.compare__jauge::-webkit-progress-bar {
  background: var(--field);
  border-radius: 999px;
}

.compare__jauge::-webkit-progress-value {
  background: var(--bd-ghost-hover);
  border-radius: 999px;
}

.compare__jauge::-moz-progress-bar {
  background: var(--bd-ghost-hover);
  border-radius: 999px;
}

.compare__ligne--fort .compare__jauge::-webkit-progress-value {
  background: linear-gradient(90deg, var(--accent-fill), var(--accent-fill-bd));
}

.compare__ligne--fort .compare__jauge::-moz-progress-bar {
  background: var(--accent-fill);
}

.compare__chiffres {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
  padding-top: 20px;
  border-top: 1px solid var(--bd-inner);
}

.compare__chiffre {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.compare__gros {
  font: 700 25px/1 var(--titre);
  letter-spacing: -.035em;
  color: var(--accent-text);
  white-space: nowrap;
}

.compare__leg {
  font: 400 12.5px/1.4 var(--texte);
  color: var(--text-3);
}

.compare__note {
  font: 400 12.5px/1.6 var(--texte);
  color: var(--text-foot);
  text-wrap: pretty;
}

/* La note sous les plans : l'attente pendant l'ouverture de la caisse, le
   retour de Stripe, et les ennuis. Le vert est le cas normal, l'ambre dit
   qu'il y a quelque chose à lire. */
.plans__note {
  margin-top: 18px;
  text-align: center;
  font: 400 13px/1.55 var(--texte);
  color: var(--ok);
}

.plans__note--souci { color: var(--warn) }

/* Le bouton reste enfoncé le temps de la réponse : sans ça un clic impatient
   ouvre deux sessions de paiement. */
.plan__cta[disabled] {
  cursor: progress;
  opacity: .72;
}

.fineprint {
  margin-top: 12px;
  text-align: center;
  font: 400 12.5px/1.55 var(--texte);
  color: var(--text-foot);
}

/* Aperçu du build. Les visuels n'existent pas encore : chaque case est un
   emplacement au format 16 sur 10, prêt à recevoir sa capture. */
.apercu { padding: 88px 0 0 }

/* Aperçu du build, en sections alternées. Une image d'un côté, le titre et le
   paragraphe de l'autre, et le côté s'inverse d'un bloc au suivant. Tout
   empiler dans une seule rangée de vignettes noyait les sujets. */
.apercu { padding: 88px 0 0 }

.sections {
  display: flex;
  flex-direction: column;
  gap: 72px;
  margin-top: 34px;
}

.bloc {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  align-items: center;
  gap: 48px;
}

/* Un bloc sur deux a son image à droite. L'ordre visuel change, pas l'ordre du
   balisage : au clavier et au lecteur d'écran, l'image précède toujours son
   texte. */
.bloc--inverse .bloc__media { order: 2 }

.bloc__titre {
  font: 600 26px/1.2 var(--titre);
  letter-spacing: -.02em;
  color: var(--text-strong);
}

.bloc__para {
  margin-top: 14px;
  max-width: 46ch;
  font: 400 15.5px/1.7 var(--texte);
  color: var(--text-2);
  text-wrap: pretty;
}

.vue {
  margin: 0;
  border: 1px solid var(--bd-card-soft);
  border-radius: 14px;
  overflow: hidden;
}

/* Le cadre prenait un format fixe et l'image était posée entière dedans. Les
   captures n'ayant pas toutes le même format, ça laissait de larges bandes
   vides de chaque côté : la carte du jeu est presque carrée, elle flottait au
   milieu d'un cadre large. Le cadre suit donc l'image, il n'y a plus de bande.
   Le format fixe ne reste que sans image, le placeholder n'ayant pas de
   hauteur propre. */
.vue__media {
  position: relative;
  display: block;
  background: var(--field);
  overflow: hidden;
}

.vue__media:not(:has(.vue__img)) { aspect-ratio: 16 / 10 }

.vue__img {
  display: block;
  width: 100%;
  height: auto;
}

/* Dans un carrousel, les vues défilent côte à côte : elles doivent partager une
   hauteur, sinon la piste sursaute d'une capture à l'autre. Les trois onglets
   du menu sont au même format à 2 % près, le rognage ne se voit pas. */
.carrousel__piste .vue__media { aspect-ratio: 16 / 10 }

.carrousel__piste .vue__img {
  height: 100%;
  object-fit: cover;
}

/* Carrousel, à l'intérieur d'une section qui a plusieurs images du même sujet.
   Le défilement porte tout : accroche horizontale, les flèches et les puces ne
   font que faire défiler la piste. Aucun style n'est posé depuis le script, ce
   que la politique de contenu interdirait. */
.carrousel { position: relative }

.carrousel__piste {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  /* La piste prend le focus pour être parcourue aux flèches du clavier. Le
     contour par défaut collerait à la vue, il est décalé vers l'extérieur. */
  outline-offset: 4px;
  scrollbar-width: none;
}

.carrousel__piste::-webkit-scrollbar { display: none }

/* Une vue par écran dans un carrousel : la section montre un sujet à la fois,
   pas une rangée de vignettes. */
.carrousel__piste .vue {
  flex: 0 0 100%;
  scroll-snap-align: start;
}

/* Flèches posées par dessus les bords de la piste : elles ne prennent pas de
   place et ne décalent rien quand elles se grisent. */
.carrousel__fleche {
  position: absolute;
  top: calc(50% - 22px);
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border: 1px solid var(--bd-ghost);
  border-radius: 999px;
  background: var(--surface-accent);
  transition: border-color .2s ease, background-color .2s ease;
}

.carrousel__fleche:hover { border-color: var(--bd-ghost-hover) }
.carrousel__fleche--prec { left: 10px }
.carrousel__fleche--suiv { right: 10px }

.carrousel__chevron {
  width: 9px;
  height: 9px;
  border-left: 2px solid var(--text-soft);
  border-bottom: 2px solid var(--text-soft);
}

.carrousel__fleche--prec .carrousel__chevron {
  transform: rotate(45deg);
  margin-left: 3px;
}

.carrousel__fleche--suiv .carrousel__chevron {
  transform: rotate(-135deg);
  margin-right: 3px;
}

.carrousel__puces {
  display: flex;
  justify-content: center;
  gap: 7px;
  margin-top: 14px;
}

/* La cible tactile fait 24px, la pastille visible 7px : au doigt, une pastille
   de 7px se rate une fois sur deux. */
.puce {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 999px;
}

.puce::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--bd-dot);
  transition: background-color .2s ease, transform .2s var(--ease);
}

.puce:hover::before { background: var(--bd-ghost-hover) }

.puce[aria-current='true']::before {
  background: var(--accent-fill);
  transform: scale(1.25);
}

/* Bon à savoir. Ce bloc vivait en bas de la page paiement, il a suivi la caisse
   sur la fiche : c'est ici qu'on se demande ce qu'il faut pour faire tourner le
   build. */
.infos { padding: 88px 0 0 }

.infos__grille {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  margin-top: 24px;
}

.info {
  border: 1px solid var(--bd);
  border-radius: 14px;
  padding: 22px 24px;
}

.info__title {
  font: 500 14px var(--texte);
  color: var(--accent-text);
}

.info__text {
  margin-top: 8px;
  font: 400 14px/1.65 var(--texte);
  color: var(--text-on-accent);
}

/* En-tête de section */
.sec-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
}

.sec-aside {
  font: 400 13.5px var(--texte);
  color: var(--text-4);
}

.sec-title {
  font: 600 30px var(--titre);
  letter-spacing: -.03em;
  color: var(--text-strong);
}

.sec-title--center { text-align: center }

/* Cibles des ancres internes, #etapes et #questions. */
.ancre { scroll-margin-top: 24px }

.sec-sub {
  margin-top: 8px;
  font: 400 14.5px var(--texte);
  color: var(--text-3);
}

.sec-sub--center {
  margin: 8px auto 0;
  max-width: 46ch;
  text-align: center;
}

.etapes {
  padding: 88px 0 0;
  text-align: center;
}

.etapes__grille {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  margin-top: 26px;
  text-align: left;
}

.etape {
  border: 1px solid var(--bd);
  border-radius: 14px;
  padding: 22px 24px;
}

/* Les trois étapes se révèlent l'une après l'autre au défilement, quand le
   navigateur sait animer sur la position dans la vue. Sinon elles sont là. */
.etapes__grille > :nth-child(2) { --i: 1 }
.etapes__grille > :nth-child(3) { --i: 2 }

@supports (animation-timeline: view()) {
  .etapes__grille .etape {
    animation: rise .8s var(--ease) both;
    animation-timeline: view();
    animation-range: entry calc(2% + var(--i, 0) * 7%) cover calc(18% + var(--i, 0) * 7%);
  }
}

.etape__num {
  font: 400 13px var(--texte);
  color: var(--accent-text);
}

.etape__texte {
  margin-top: 8px;
  font: 400 14.5px/1.65 var(--texte);
  color: var(--text-on-accent);
}

/* Questions */
.faq { padding: 88px 0 0 }

.faq__list {
  max-width: 720px;
  margin: 22px auto 0;
}

.faq__item { border-top: 1px solid var(--bd) }

.faq__q {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 20px;
  width: 100%;
  padding: 20px 0;
  text-align: left;
}

.faq__item.is-open .faq__q { padding-bottom: 12px }

.faq__label {
  font: 500 16px var(--texte);
  color: var(--text-alt);
  transition: color .2s ease;
}

/* Le survol d'une question dit qu'elle s'ouvre au clic. */
.faq__q:hover .faq__label { color: var(--text-strong) }
.faq__q:hover .faq__signe { color: var(--accent-text) }

.faq__signe {
  font: 400 17px var(--texte);
  color: var(--text-3);
}

.faq__r {
  max-width: 58ch;
  padding-bottom: 20px;
  font: 400 14.5px/1.75 var(--texte);
  color: var(--text-2);
}

/* Appel final */
.cta {
  margin-top: 88px;
  padding: 44px 0;
  border-top: 1px solid var(--bd);
  text-align: center;
}

.cta__title {
  font: 600 32px var(--titre);
  letter-spacing: -.035em;
  color: var(--text-strong);
}

.cta__actions {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 14px;
  margin-top: 24px;
}

/* Pied de page */
.foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 26px 0 40px;
  font: 400 13px var(--texte);
  color: var(--text-foot);
}

.foot__links {
  display: flex;
  gap: 20px;
}

/* Portage responsive. La maquette est pensée desktop : hero en une colonne,
   grilles resserrées, conteneur en 0 20px. */
@media (max-width: 900px) {
  .hero { padding-top: 44px }

  .hero__title { font-size: 44px }
  .etapes, .faq, .apercu, .infos { padding-top: 72px }
  /* Les blocs passent en une colonne, l'image au dessus de son texte : à
     cette largeur, deux colonnes donnaient une image trop petite pour qu'on y
     lise un menu, et un paragraphe en colonne étroite. */
  .bloc { grid-template-columns: 1fr; gap: 22px }
  .bloc--inverse .bloc__media { order: 0 }
  .bloc__titre { font-size: 22px }
  .sections { gap: 52px }
  .infos__grille { grid-template-columns: 1fr }
  .cta { margin-top: 72px }
}

@media (max-width: 640px) {
  .wrap { padding: 0 20px }
  /* Cibles tactiles : ces liens faisaient 16 à 20px de haut au doigt. Le fil
     d'Ariane de la fiche reste tel quel, c'est un lien dans une ligne de texte. */
  .nav__links a, .foot__links a { padding: 10px 0 }
  .nav__brand { padding: 8px 0 }

  .nav {
    height: auto;
    padding: 16px 0;
    flex-wrap: wrap;
    gap: 14px;
  }

  .nav__links {
    gap: 16px;
    font-size: 13px;
    flex-wrap: wrap;
  }

  .hero__title { font-size: 38px }

  /* Sur petit écran, ces deux liens repoussaient les tarifs hors du premier
     écran alors que la barre de navigation mène déjà aux mêmes endroits. */

  /* Une carte de plan par écran, et moins de rembourrage : à 390px, trois
     colonnes de 340px sortaient du conteneur. */
  .plans { grid-template-columns: minmax(0, 1fr) }
  .plan { padding: 22px }
  .plan__montant { font-size: 38px }
  .etapes__grille { grid-template-columns: 1fr }

  .sections { gap: 44px }
  .carrousel__fleche { width: 36px; height: 36px }

  .sec-title { font-size: 26px }
  .cta__title { font-size: 26px }

  .btn-solid, .btn-accent { padding: 14px 24px }
  .btn-ghost { padding: 13px 22px }

  .faq__label { font-size: 15px }

  .foot {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
  }
}

/* Cibles de pointage. Le texte seul donnait 16 à 20px de haut : sous les 24px
   qu'une cible doit faire au minimum, on rate le lien une fois sur deux. Le
   rembourrage agrandit la zone cliquable sans déplacer le texte. */
.nav__links a:not(.nav__cta) { padding: 4px 2px }
.nav__brand { padding: 3px 0 }
.foot__links a { padding: 5px 2px }


/* Ce que le pack ouvre. Les vignettes menaient chacune vers la fiche de son
   jeu : lire ce que contient le pack faisait quitter sa page, treize fois.
   Ce sont des onglets, et le détail du jeu ouvert s'affiche dessous. La
   grille est donc un sélecteur, pas un second catalogue : les jaquettes non
   retenues sont estompées, celle qui est ouverte revient à pleine lumière. */
.inclus { padding: 88px 0 0 }

.inclus__grille {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 12px;
  margin-top: 28px;
}

.ouvert {
  display: block;
  border: 1px solid var(--bd-card-soft);
  border-radius: 12px;
  overflow: hidden;
  text-align: left;
  transition: border-color .2s ease;
}

.ouvert:hover { border-color: var(--bd-card-hover) }
.ouvert.is-active { border-color: var(--accent-bd) }

.ouvert__media {
  position: relative;
  display: block;
  aspect-ratio: 16 / 10;
  background: var(--field);
  overflow: hidden;
}

.ouvert__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Estompées tant qu'elles ne sont pas retenues : sur treize jaquettes
     toutes à pleine lumière, rien ne dit laquelle est ouverte. */
  opacity: .5;
  transition: opacity .3s ease, transform .5s var(--ease);
}

.ouvert:hover .ouvert__img,
.ouvert.is-active .ouvert__img { opacity: 1 }

.ouvert.is-active .ouvert__img { transform: scale(1.04) }

/* Le nom par dessus la jaquette, comme au catalogue, en plus petit puisque la
   vignette l'est aussi. */
.ouvert__media::after {
  content: '';
  position: absolute;
  inset: 45% 0 0;
  background: linear-gradient(180deg, transparent, rgba(6, 7, 11, .86) 80%);
  pointer-events: none;
}

.ouvert__nom {
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: 8px;
  z-index: 1;
  font: 700 14px/1.1 var(--titre);
  letter-spacing: -.02em;
  color: var(--text-ghost);
  text-shadow: 0 2px 10px rgba(0, 0, 0, .6);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: color .2s ease;
}

.ouvert.is-active .ouvert__nom,
.ouvert:hover .ouvert__nom { color: var(--text-strong) }

/* Le détail du jeu ouvert. Il porte ce qu'on vient y chercher : à quoi
   ressemble le build, ce qu'il fait, et ce que ce jeu coûterait seul. */
.detail {
  display: grid;
  grid-template-columns: minmax(0, 460px) minmax(0, 1fr);
  gap: 30px;
  align-items: center;
  margin-top: 14px;
  padding: 22px;
  border: 1px solid var(--bd-card);
  border-radius: 20px;
  background: var(--surface-accent);
}

.detail__media {
  border: 1px solid var(--bd-inner);
  border-radius: 14px;
  background: var(--field);
  aspect-ratio: 16 / 9;
  overflow: hidden;
}

/* Posée entière, pas rognée : une capture de menu, une carte de jeu et un
   rendu en partie n'ont pas le même format, les rogner toutes pareil les
   mutilait. */
.detail__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  animation: fade .3s ease both;
}

.detail__media .shot {
  width: 100%;
  height: 100%;
}

.detail__tete {
  display: flex;
  align-items: baseline;
  gap: 11px;
  flex-wrap: wrap;
}

.detail__nom {
  margin: 0;
  font: 700 27px/1.1 var(--titre);
  letter-spacing: -.035em;
  color: var(--text-strong);
}

.detail__cat {
  padding: 3px 9px;
  border: 1px solid var(--bd-card);
  border-radius: 999px;
  font: 500 11.5px/1.5 var(--texte);
  color: var(--text-3);
  white-space: nowrap;
}

.detail__pitch {
  margin-top: 12px;
  font: 400 14.5px/1.65 var(--texte);
  color: var(--text-2);
  text-wrap: pretty;
}

.detail__traits {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
}

.detail__trait {
  padding: 5px 11px;
  border: 1px solid var(--accent-bd-soft);
  border-radius: 999px;
  font: 500 12.5px/1.4 var(--texte);
  color: var(--accent-text);
}

/* Ce que ce jeu coûte seul, et ce qu'il coûte avec le pack. C'est la
   question que se pose quelqu'un qui hésite entre un jeu et les treize. */
.detail__prix {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin-top: 18px;
}

.detail__case {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 14px;
  border: 1px solid var(--bd-inner);
  border-radius: 12px;
  background: var(--field);
}

.detail__case--pack {
  border-color: var(--accent-bd-soft);
  background: var(--shot-lueur);
}

.detail__label {
  font: 400 12px/1.4 var(--texte);
  color: var(--text-4);
}

.detail__val {
  font: 700 19px/1.15 var(--titre);
  letter-spacing: -.02em;
  color: var(--text-strong);
}

.detail__case--pack .detail__val { color: var(--accent-text) }

/* Le seul lien du panneau : la fiche complète, pour qui veut en lire plus.
   Le pack ne remplace pas ces pages, mais il ne force plus à y aller. */
.detail__lien {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-top: 18px;
  padding: 6px 0;
  font: 500 13.5px var(--texte);
  color: var(--text-2);
}

.detail__lien::after {
  content: '';
  width: 6px;
  height: 6px;
  border-right: 1.5px solid currentColor;
  border-top: 1.5px solid currentColor;
  transform: rotate(45deg);
  transition: transform .2s var(--ease);
}

.detail__lien:hover { color: var(--text-strong) }
.detail__lien:hover::after { transform: rotate(45deg) translate(2px, -2px) }

@media (max-width: 980px) {
  .achat--pack .achat__duo { grid-template-columns: minmax(0, 1fr) }
  .achat--pack .plans { justify-content: center }
  .detail { grid-template-columns: minmax(0, 1fr); gap: 22px }
}

@media (max-width: 900px) {
  .inclus__grille { grid-template-columns: repeat(4, 1fr) }
  .inclus { padding-top: 72px }
}

@media (max-width: 640px) {
  /* Sur téléphone la grille devient un rayon qui se fait glisser. En trois
     colonnes les noms se coupaient (« Counter-St… »), en deux les treize
     jeux poussaient le panneau à sept rangées de là. Une seule rangée qui
     défile garde les noms entiers et le détail juste dessous. */
  .inclus__grille {
    display: flex;
    gap: 10px;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    /* Déborde jusqu'au bord de l'écran, comme un rayon : une tuile coupée à
       droite dit qu'il y en a d'autres. Le rembourrage rend la marge, donc
       rien ne dépasse du conteneur. */
    margin-inline: -20px;
    padding-inline: 20px;
    scrollbar-width: none;
  }

  .inclus__grille::-webkit-scrollbar { display: none }

  .ouvert {
    flex: 0 0 168px;
    scroll-snap-align: center;
  }

  .ouvert__nom { font-size: 13px }
  .compare { padding: 22px 20px }
  .compare__chiffres { grid-template-columns: minmax(0, 1fr); gap: 12px }
  .compare__chiffre { flex-direction: row; align-items: baseline; gap: 9px }
  .compare__gros { font-size: 22px }
  .detail { padding: 16px }
  .detail__nom { font-size: 23px }
  .detail__prix { grid-template-columns: minmax(0, 1fr) }
}

@media (prefers-reduced-motion: reduce) {
  .ouvert.is-active .ouvert__img { transform: none }
  .detail__img { animation: none }
}

/* Fenêtre d'ajout du spoofer, ouverte au moment de payer sur les paliers qui
   ne le comprennent pas. C'est un <dialog> natif : le piège au clavier, la
   fermeture par Échap, le retour du focus et le fond modal viennent avec, là
   où une div déguisée en fenêtre demanderait de tout écrire.
   Elle tient en quatre éléments : ce que c'est et ce que ça coûte, pourquoi,
   et les deux réponses avec leur total. Elle a porté un moment trois arguments
   à puces, une part d'acheteurs, un récapitulatif à trois lignes et une montée
   en gamme : personne ne lit ça un doigt sur le bouton. */
.ajout {
  position: relative;
  width: min(400px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  padding: 30px 30px 24px;
  border: 1px solid var(--accent-bd-soft);
  border-radius: 20px;
  background:
    radial-gradient(90% 130% at 100% 0%, var(--shot-lueur), transparent 62%),
    var(--surface-accent);
  color: var(--text);
  box-shadow: var(--shadow-hero);
}

.ajout::backdrop {
  background: rgba(4, 5, 8, .74);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
}

.ajout[open] { animation: ajoutMonte .24s var(--ease) both }

@keyframes ajoutMonte {
  from { opacity: 0; transform: translateY(12px) scale(.98) }
  to   { opacity: 1; transform: none }
}

/* Fermer sans rien acheter. La croix fait 34px au doigt, pas la taille du
   trait qu'elle dessine. */
.ajout__fermer {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--text-3);
  transition: background-color .2s ease, color .2s ease;
}

.ajout__fermer:hover {
  background: var(--field);
  color: var(--text-strong);
}

.ajout__croix {
  position: relative;
  width: 13px;
  height: 13px;
}

.ajout__croix::before,
.ajout__croix::after {
  content: '';
  position: absolute;
  top: 6px;
  left: 0;
  width: 13px;
  height: 1.5px;
  background: currentColor;
}

.ajout__croix::before { transform: rotate(45deg) }
.ajout__croix::after { transform: rotate(-45deg) }

/* Le titre porte le prix de l'option : c'est la première chose qu'on cherche,
   elle n'a pas à attendre une ligne de plus. */
.ajout__titre {
  margin: 0 40px 0 0;
  font: 700 21px/1.25 var(--titre);
  letter-spacing: -.03em;
  color: var(--text-strong);
  text-wrap: balance;
}

/* Le motif, en deux phrases. Personne n'ajoute une option dont il ne comprend
   pas à quoi elle sert, et le motif est ici très concret. */
.ajout__raison {
  margin-top: 12px;
  font: 400 14.5px/1.6 var(--texte);
  color: var(--text-2);
  text-wrap: pretty;
}

/* Les deux réponses sont sur le même pied : même largeur, même taille, et le
   refus annonce son prix lui aussi. Un bouton de refus étroit, gris ou
   culpabilisant fait fermer la page, pas acheter. */
.ajout__actions {
  display: flex;
  flex-direction: column;
  gap: 9px;
  margin-top: 22px;
}

.ajout__oui,
.ajout__non {
  padding: 13px 18px;
  border-radius: 10px;
  font: 600 14px/1.2 var(--texte);
  text-align: center;
}

.ajout__oui {
  background: var(--btn-light);
  color: var(--bg);
}

.ajout__oui:hover { background: var(--btn-light-hover) }

.ajout__non {
  border: 1px solid var(--bd-ghost);
  color: var(--text-soft);
}

.ajout__non:hover { border-color: var(--bd-ghost-hover) }

/* Le total, en petit et sous les boutons. Il a d'abord été posé sur le bouton
   lui même : un montant collé à « Ajouter » se lit comme le prix de ce qu'on
   ajoute, et le spoofer avait l'air d'en coûter trente-cinq. */
.ajout__total {
  margin-top: 14px;
  text-align: center;
  font: 400 12.5px/1.55 var(--texte);
  color: var(--text-foot);
}

@media (max-width: 640px) {
  .ajout { padding: 26px 20px 20px }
  .ajout__titre { font-size: 20px }
}

@media (prefers-reduced-motion: reduce) {
  .ajout[open] { animation: none }
}
