/*
 * Le site public de Comptoir+.
 *
 * Même charte que l'application — rouge et rose, Anton en capitales sur les
 * titres, neutres chauds — mais une feuille SÉPARÉE, et c'est un choix.
 * Importer `apps/web/src/styles.css` amènerait mille trois cents lignes de
 * jetons pensés pour une caisse : les états de commande, les paliers de
 * consigne, les grilles tarifaires. Une page de vente n'en utilise pas un
 * dixième, et un site vitrine qui traîne le CSS d'une PWA met une seconde de
 * plus à s'afficher — sur la seule page que verra quelqu'un qui ne connaît pas
 * encore le produit.
 *
 * Ce qui est repris est ce qui fait reconnaître la marque : les deux rouges
 * rentrés de cinq pour cent (#d9303c, #d61e74), le dégradé à 135°, Anton, et
 * des neutres chauds plutôt que gris.
 *
 * AUCUNE POLICE DISTANTE, comme dans l'application. Les .woff2 sont copiés
 * depuis apps/web/public/polices par le Dockerfile : une seule source pour les
 * deux images, et pas de requête vers Google au chargement de la page.
 */

@font-face {
  font-family: 'Anton';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/polices/anton-latin.woff2') format('woff2');
}

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/polices/space-grotesk-latin.woff2') format('woff2');
}

:root {
  --police-texte: 'Space Grotesk', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --police-titre: 'Anton', Impact, 'Haettenschweiler', sans-serif;
  color-scheme: light;

  --fond: #f5f1ec;
  --fond-2: #fffdfa;
  --fond-3: #ece6de;
  --bord: rgb(26 21 24 / 0.16);

  --texte: #1a1518;
  --texte-doux: #453d39;

  --accent: #d9303c;
  --accent-fort: #a81624;
  --accent-doux: #fdeceb;
  --accent-texte: #ffffff;
  --ambre: #b45309;

  --degrade: linear-gradient(135deg, #d9303c, #d61e74);
  /*
   * LE DÉGRADÉ DES BOUTONS, un cran plus sombre que celui de la marque. Blanc
   * sur #d9303c donne 4,7:1 et sur le rose 4,5:1 — tout juste, et sur le
   * papier clair l'œil le trouvait pâle. Rentrés de dix pour cent, les deux
   * rouges passent 5,8:1 et 5,6:1 ; le logo et le mot en dégradé gardent, eux,
   * les couleurs vives.
   */
  --degrade-bouton: linear-gradient(135deg, #c2202c, #bd1a66);

  --rayon-sm: 0.75rem;
  --rayon: 0.875rem;
  --rayon-lg: 1.375rem;

  --halo-1: color-mix(in srgb, #e63946 10%, transparent);
  --halo-2: color-mix(in srgb, #a855f7 8%, transparent);

  /*
   * Le mouvement d'iOS : part vite, se pose lentement. Une seule courbe pour
   * tout ce qui bouge, et rien ne bouge plus de trois quarts de seconde.
   */
  --mouvement: cubic-bezier(0.32, 0.72, 0, 1);
  --rayon-xl: 1.75rem;
  --ombre-carte: 0 1px 2px rgb(26 21 24 / 0.04), 0 14px 36px -18px rgb(26 21 24 / 0.22);
  --ombre-bouton: 0 10px 24px -12px rgb(217 48 60 / 0.6);
  --succes: #15803d;
}

/*
 * De nuit, la charte de la caisse : un fond presque noir traversé de deux
 * halos, des surfaces translucides qui se posent dessus. C'est ce que voient
 * les bénévoles un soir de fête, et c'est la version que reconnaîtra le comité
 * qui a déjà vu le produit tourner quelque part.
 */
/*
 * LA NUIT, EN DEUX EXEMPLAIRES JUMEAUX : « le système est sombre et rien n'a
 * été choisi » et « la personne a choisi sombre » ne s'écrivent pas dans le
 * même sélecteur, et un même bloc ne peut pas vivre à la fois dans une
 * @media et hors d'elle. Les deux listes sont IDENTIQUES et doivent le rester.
 * La bascule est dans theme.js : elle pose data-theme sur <html>.
 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='clair']) {
    color-scheme: dark;
    --fond: #17131a;
    --fond-2: rgb(38 31 39 / 0.86);
    --fond-3: rgb(46 38 47 / 0.7);
    --bord: rgb(255 253 250 / 0.14);

    --texte: #fffdfa;
    --texte-doux: #c9bfc4;

    --accent: #f4626b;
    --accent-fort: #f9959a;
    --accent-doux: rgb(217 48 60 / 0.16);
    --ambre: #fbbf24;

    --halo-1: color-mix(in srgb, #e63946 18%, transparent);
    --halo-2: color-mix(in srgb, #a855f7 14%, transparent);

    --ombre-carte: 0 1px 2px rgb(0 0 0 / 0.3), 0 18px 44px -20px rgb(0 0 0 / 0.65);
    --ombre-bouton: 0 12px 28px -12px rgb(244 98 107 / 0.55);
    --succes: #4ade80;

    /* De nuit, le bouton reprend le dégradé de la marque : le fond est sombre, le blanc y tient. */
    --degrade-bouton: var(--degrade);
  }
}

:root[data-theme='sombre'] {
  color-scheme: dark;
    --fond: #17131a;
    --fond-2: rgb(38 31 39 / 0.86);
    --fond-3: rgb(46 38 47 / 0.7);
    --bord: rgb(255 253 250 / 0.14);

    --texte: #fffdfa;
    --texte-doux: #c9bfc4;

    --accent: #f4626b;
    --accent-fort: #f9959a;
    --accent-doux: rgb(217 48 60 / 0.16);
    --ambre: #fbbf24;

    --halo-1: color-mix(in srgb, #e63946 18%, transparent);
    --halo-2: color-mix(in srgb, #a855f7 14%, transparent);

    --ombre-carte: 0 1px 2px rgb(0 0 0 / 0.3), 0 18px 44px -20px rgb(0 0 0 / 0.65);
    --ombre-bouton: 0 12px 28px -12px rgb(244 98 107 / 0.55);
    --succes: #4ade80;

    /* De nuit, le bouton reprend le dégradé de la marque : le fond est sombre, le blanc y tient. */
    --degrade-bouton: var(--degrade);
}

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

/*
 * `hidden` CACHE VRAIMENT, et cette ligne n'est pas de la ceinture-bretelles.
 *
 * L'attribut ne vaut qu'un `display: none` de la feuille du navigateur, que
 * n'importe quelle règle d'auteur portant `display` écrase — et nos blocs de
 * formulaire sont en `display: flex`, nos cartes tarifaires aussi. Sans ceci,
 * `element.hidden = true` ne cache RIEN : le bloc d'adresse de facturation
 * resterait affiché pour une buvette réglée par carte, et une carte tarifaire
 * retirée de la grille continuerait de proposer son bouton.
 *
 * Le `!important` est le seul moyen de battre une règle de classe à coup sûr,
 * et c'est l'usage exact pour lequel il existe : une décision binaire que rien
 * ne doit pouvoir contredire.
 */
[hidden] {
  display: none !important;
}

body {
  margin: 0;
  font-family: var(--police-texte);
  color: var(--texte);
  background-color: var(--fond);
  /*
   * Les deux halos de l'ancienne caisse. Ils empêchent l'aplat de paraître plat.
   *
   * Ils DÉFILENT avec la page et ne sont plus fixés : iOS ignore `fixed` de
   * toute façon, Chromium repeint tout le fond à chaque défilement quand il
   * l'honore, et le résultat était deux pages différentes selon l'appareil. Les
   * halos éclairent le haut — le héros, là où l'on décide — et laissent le
   * papier tranquille en dessous.
   */
  background-image:
    radial-gradient(60rem 40rem at 15% -10%, var(--halo-1), transparent),
    radial-gradient(50rem 35rem at 90% 5%, var(--halo-2), transparent);
  background-repeat: no-repeat;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  font-family: var(--police-titre);
  text-transform: uppercase;
  letter-spacing: 0.01em;
  line-height: 1.05;
  margin: 0 0 0.5em;
  font-weight: 400;
}

h1 {
  font-size: clamp(2.5rem, 7vw, 4.5rem);
}
h2 {
  font-size: clamp(1.75rem, 4vw, 2.5rem);
}
h3 {
  font-size: 1.125rem;
}

p {
  margin: 0 0 1rem;
  color: var(--texte-doux);
}

a {
  color: var(--accent-fort);
}

.enveloppe {
  max-width: 68rem;
  margin: 0 auto;
  padding: 0 1.5rem;
}

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

.entete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1.5rem 0;
  flex-wrap: wrap;
}

.marque {
  display: inline-flex;
  align-items: center;
  font-family: var(--police-titre);
  text-transform: uppercase;
  font-size: 1.5rem;
  text-decoration: none;
  color: var(--texte);
  border-radius: 0.5rem;
}

.marque:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 6px;
}

/*
 * LE LOGO EST UN MASQUE, PAS UNE IMAGE — la même mécanique que dans
 * l'application. Le trait vient du PNG détouré, l'encre vient de la charte :
 * ici le dégradé rouge-rose, le seul endroit du site où il se pose sur la
 * marque. Un PNG orange affiché tel quel poserait une troisième couleur au
 * milieu d'une page qui n'en a que deux.
 */
.marque-logo {
  display: block;
  width: 8.25rem;
  aspect-ratio: 651 / 202;
  background: var(--degrade);
  -webkit-mask: url('/marque/logo.png') center / contain no-repeat;
  mask: url('/marque/logo.png') center / contain no-repeat;
}

.navigation {
  display: flex;
  gap: 1.5rem;
  align-items: center;
  flex-wrap: wrap;
}

.navigation a {
  color: var(--texte-doux);
  text-decoration: none;
  font-weight: 500;
}

.navigation a:hover {
  color: var(--texte);
}

/*
 * LE BOUTON DU MENU GARDE SON ENCRE BLANCHE. `.navigation a` bat `.bouton` à
 * la spécificité, et le seul appel de l'en-tête s'affichait en gris foncé sur
 * son dégradé rouge — illisible de jour. Les deux règles ci-dessous rendent
 * au bouton sa couleur, au repos et au survol.
 */
.navigation a.bouton,
.navigation a.bouton:hover {
  color: var(--accent-texte);
}

.navigation a:not(.bouton) {
  transition: color 0.32s var(--mouvement);
  border-radius: 0.375rem;
}

.navigation a:not(.bouton):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}

/* ─────────────────────────────── Boutons ─────────────────────────────── */

.bouton {
  display: inline-block;
  padding: 0.75rem 1.5rem;
  border-radius: var(--rayon);
  background: var(--degrade-bouton);
  color: var(--accent-texte);
  text-decoration: none;
  font-weight: 600;
  border: 0;
  cursor: pointer;
  font-size: 1rem;
  font-family: inherit;
  line-height: 1.4;
  box-shadow: var(--ombre-bouton);
  transition:
    transform 0.32s var(--mouvement),
    box-shadow 0.32s var(--mouvement),
    background-color 0.32s var(--mouvement);
}

.bouton:hover {
  transform: translateY(-1px);
}

.bouton:active {
  transform: translateY(0) scale(0.99);
}

.bouton:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.bouton-discret {
  background: transparent;
  color: var(--texte);
  border: 1px solid var(--bord);
  box-shadow: none;
}

.bouton-discret:hover {
  background: var(--fond-2);
}

/* Le grand format des appels de page : plus haut, plus rond, jamais plus criard. */
.bouton-grand {
  padding: 1rem 1.75rem;
  font-size: 1.0625rem;
  border-radius: 1.125rem;
}

/*
 * L'APPEL VERS LA DÉMONSTRATION : un bouton discret qui porte le signe d'une
 * vidéo — un disque de lecture dans le dégradé de la marque — et sa durée.
 * Après `.bouton-grand`, pour lui prendre ses retraits : le disque fait office
 * de bord gauche, et la hauteur reste celle du grand bouton d'à côté — un demi
 * rem de chaque côté d'un disque de deux rem et demi, soit ses 56 pixels.
 */
.bouton-demo {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 1.5rem 0.5rem 0.5rem;
}

.bouton-demo-lecture {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  background: var(--degrade-bouton);
  color: #fff;
  box-shadow: var(--ombre-bouton);
}

.bouton-demo-lecture svg {
  width: 1rem;
  height: 1rem;
  margin-left: 0.1rem;
  fill: currentColor;
}

.bouton-demo small {
  margin-left: 0.5rem;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--texte-doux);
}

/* ──────────────────────────────── Héros ──────────────────────────────── */

.heros {
  padding: 4rem 0 3rem;
  max-width: 46rem;
}

.accroche {
  font-size: clamp(1.125rem, 2.5vw, 1.375rem);
  color: var(--texte-doux);
  margin-bottom: 2rem;
}

/*
 * Un héros plus court pour les pages où le contenu commence tout de suite —
 * l'inscription, la page d'après. Quatre rem de blanc au-dessus d'un formulaire
 * font défiler avant d'avoir rien fait, sur le seul écran où l'on veut que la
 * personne commence.
 */
.heros-court {
  padding: 2.5rem 0 1.5rem;
}

/* La ligne d'appel qui suit l'accroche : même famille, une taille en dessous. */
.accroche-suite {
  font-size: 1.0625rem;
  color: var(--texte-doux);
  margin-bottom: 0;
}

/*
 * Les boutons d'une rangée se centrent au lieu de s'étirer : un appel plus
 * haut que son voisin — la pastille de la démo — ne doit pas le faire grandir
 * avec son texte resté en haut.
 */
.actions {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}

/* ──────────────────────────────── Cartes ─────────────────────────────── */

.grille {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.25rem;
  margin: 2rem 0 4rem;
}

.carte {
  background: var(--fond-2);
  border: 1px solid var(--bord);
  border-radius: var(--rayon-lg);
  padding: 1.5rem;
}

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

.carte p {
  margin: 0;
  font-size: 0.9375rem;
}

/*
 * L'ADRESSE DE L'ESPACE, sur la page d'après : c'est la seule chose de cette
 * page qu'on recopie, et souvent la seule qu'on retient. Elle est donc en
 * grand, seule sur sa ligne, et jamais coupée par une césure — une adresse
 * scindée au milieu se recopie de travers.
 */
.carte-espace {
  margin: 0 0 2rem;
}

.carte-espace p {
  margin: 0 0 0.75rem;
}

.carte-espace p:last-child {
  margin-bottom: 0;
}

/*
 * `p.adresse-espace` et non `.adresse-espace` seul : il doit battre `.carte p`,
 * qui ramène le texte des cartes à 0.9375rem. Sans le sélecteur de type, cette
 * ligne perd la spécificité et l'adresse — la seule chose de la page qu'on
 * recopie — s'affiche plus PETITE que le paragraphe qui l'explique.
 */
p.adresse-espace {
  font-size: clamp(1.125rem, 3vw, 1.5rem);
  font-weight: 600;
  overflow-wrap: anywhere;
}

.adresse-espace a {
  color: var(--accent-fort);
}

/*
 * LES DEUX ACCÈS de la page de bienvenue : deux blocs titrés, l'adresse en
 * gras dedans. Une liste de définitions, parce que c'est ce que c'est — un
 * accès, sa clef — et parce qu'un lecteur d'écran l'annonce comme telle.
 */
.acces-liste {
  display: grid;
  gap: 0.75rem;
  margin: 0.75rem 0;
}

.acces {
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--bord);
  border-radius: var(--rayon);
  background: var(--fond);
}

.acces dt {
  font-weight: 700;
  color: var(--texte);
  margin-bottom: 0.25rem;
}

.acces dd {
  margin: 0;
  font-size: 0.9375rem;
  color: var(--texte-doux);
  overflow-wrap: anywhere;
}

.acces dd a {
  font-weight: 600;
  color: var(--accent-fort);
}

/* ─────────────────────────── Grille tarifaire ────────────────────────── */

/*
 * L'offre se lit en DEUX GROUPES TITRÉS — à la manifestation, puis les packs —
 * parce que ce sont deux questions différentes : « combien coûte ma fête » et
 * « combien j'économise si j'en prévois plusieurs ». Une seule nappe de huit
 * cartes obligeait le lecteur à faire ce tri lui-même.
 */
.offre {
  margin: 2.5rem 0;
  display: flex;
  flex-direction: column;
  gap: 3.5rem;
}

.offre-titre {
  max-width: 42rem;
}

.offre-titre h2 {
  font-size: clamp(1.375rem, 3vw, 1.75rem);
  margin-bottom: 0.25rem;
}

.offre-titre p {
  margin: 0;
  font-size: 0.9375rem;
}

.tarifs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1.25rem;
  margin: 1.25rem 0 0;
  align-items: stretch;
}

.tarif {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--fond-2);
  border: 1px solid var(--bord);
  border-radius: var(--rayon-lg);
  padding: 1.5rem;
}

/*
 * UN SEUL palier mis en avant, et c'est « Fête ».
 *
 * C'est celui d'une fête de village : le cas le plus fréquent, et surtout
 * celui dont le prix se défend le mieux — CHF 350 sur CHF 20 000 à 40 000 de
 * bar. Mettre en avant le plus cher ferait fuir une petite société ; mettre en
 * avant le moins cher ancrerait tout le monde à CHF 50.
 */
.tarif.avant {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}

.tarif .palier {
  font-family: var(--police-titre);
  text-transform: uppercase;
  font-size: 1.25rem;
  margin-bottom: 0.25rem;
}

.tarif .prix {
  font-size: 2.25rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  margin: 0.5rem 0;
}

.tarif .prix small {
  font-size: 0.875rem;
  font-weight: 400;
  color: var(--texte-doux);
  display: block;
}

.tarif .repere {
  color: var(--texte-doux);
  font-size: 0.9375rem;
  flex: 1;
}

/*
 * L'ÉTIQUETTE du palier mis en avant. Une seule sur toute la grille (voir
 * `.tarif.avant`) : deux étiquettes n'en seraient plus, et « fête de village »
 * dit POURQUOI ce palier est montré du doigt — le cas le plus fréquent — là où
 * « populaire » ne dirait que notre envie de le vendre.
 */
.etiquette {
  position: absolute;
  top: -0.7rem;
  right: 1.25rem;
  background: var(--degrade-bouton);
  color: #fff;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 0.25rem 0.75rem;
  border-radius: 999px;
}

/*
 * LES CLAUSES : une ligne par chose vendue, coche ou tiret devant. C'est ce
 * qui rend les paliers comparables d'un coup d'œil — l'œil descend la même
 * liste sur chaque carte. La ligne absente (« sans statistiques ») reste
 * affichée, atténuée : c'est elle qui explique le « + » d'à côté.
 */
.clauses {
  list-style: none;
  margin: 0.25rem 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  flex: 1;
  font-size: 0.9375rem;
  color: var(--texte-doux);
}

.clauses li {
  position: relative;
  padding-left: 1.5rem;
}

.clauses li::before {
  content: '✓';
  position: absolute;
  left: 0;
  top: 0;
  color: var(--accent);
  font-weight: 700;
}

.clauses .clause-non {
  opacity: 0.6;
}

/* `li.clause-non` et non `.clause-non` seul : il doit battre `.clauses li`. */
.clauses li.clause-non::before {
  content: '—';
  color: var(--texte-doux);
  font-weight: 400;
}

/*
 * La ligne d'aide qui SUIT une liste de clauses. Sans cette marge, elle vient
 * se coller au dernier item et se lit comme une clause de plus à qui la coche
 * manquerait — la liste n'a pas de marge basse, et `.aide` pas de marge haute.
 */
.clauses + .aide {
  margin-top: 1rem;
}

/*
 * Le rabais d'un pack, dans un cartouche : c'est l'argument de la carte, pas
 * une note de bas de page. Le montant est recalculé par tarifs.js depuis les
 * prix à l'unité — voir data-rabais-reference.
 */
.rabais {
  margin: 1rem 0 0;
  padding: 0.5rem 0.75rem;
  border-radius: var(--rayon-sm);
  background: var(--accent-doux);
  font-size: 0.875rem;
  color: var(--texte-doux);
}

.rabais strong {
  color: var(--accent-fort);
}

/*
 * FESTIVAL EN BANDEAU, pleine largeur sous les quatre paliers : il n'a ni
 * prix ni clauses à comparer, l'aligner sur les cartes laissait une colonne
 * de vide qui ressemblait à un oubli.
 */
.tarif-large {
  grid-column: 1 / -1;
  flex-direction: row;
  align-items: center;
  gap: 2rem;
  flex-wrap: wrap;
}

.tarif-large-tete {
  min-width: 11rem;
}

.tarif-large .prix {
  margin: 0.25rem 0 0;
}

.tarif-large .repere {
  flex: 1 1 18rem;
  margin: 0;
}

.tarif .reglement {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--bord);
  font-size: 0.875rem;
  color: var(--texte-doux);
}

.tarif .reglement strong {
  color: var(--ambre);
  font-weight: 600;
}

/* Après la règle générique, pour la battre à spécificité égale. */
.tarif-large .reglement {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* Le cartouche de rabais colle au règlement : pas de double trait entre eux. */
.rabais + .reglement {
  margin-top: 0.75rem;
  padding-top: 0;
  border-top: 0;
}

/*
 * Le bouton de chaque carte tarifaire, collé en bas.
 *
 * `margin-top: auto` et non une marge fixe : les cartes d'une même rangée n'ont
 * pas le même nombre de clauses, et sans cela les boutons se retrouveraient à
 * trois hauteurs différentes. Un œil qui balaie une grille compare les prix en
 * haut et cherche les boutons en bas ; les décaler oblige à les chercher un par
 * un.
 */
.tarif .choisir {
  margin: 1.25rem 0 0;
}

.tarif .choisir .bouton {
  display: block;
  text-align: center;
}

/* En bandeau, le bouton reprend sa largeur naturelle : la carte est déjà large. */
.tarif-large .choisir {
  margin: 0;
}

.tarif-large .choisir .bouton {
  display: inline-block;
}

/*
 * Le rappel de fin de page : le même appel que les cartes, remis à portée là où
 * la décision se prend. Teinté, pour qu'on le trouve en descendant sans le
 * confondre avec une section de texte de plus.
 */
.section-appel {
  background: var(--fond-2);
  border: 1px solid var(--bord);
  border-radius: var(--rayon-lg);
  padding: 2.5rem;
  margin: 3rem 0;
}

.section-appel h2 {
  margin-bottom: 0.5rem;
}

/* ───────────────────────────── Formulaires ───────────────────────────── */

/*
 * L'INSCRIPTION EST LA SEULE PAGE DU SITE QUI DEMANDE À ÉCRIRE.
 *
 * Tout y est pensé pour qu'on la finisse : des blocs titrés qui découpent un
 * formulaire long en quatre décisions, une aide sous chaque champ plutôt qu'un
 * astérisque renvoyant plus bas, et des cibles tactiles franches — un comité la
 * remplit souvent sur un téléphone, dans une salle, entre deux discussions.
 *
 * AUCUNE VALIDATION EN ROUGE PENDANT LA FRAPPE. Le navigateur souligne déjà ce
 * qu'il refuse ; ajouter nos propres marques à chaque caractère tapé donnerait
 * un formulaire qui gronde avant qu'on ait fini d'écrire son adresse.
 */
.formulaire {
  max-width: 44rem;
  margin: 0 0 3rem;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.bloc {
  border: 1px solid var(--bord);
  border-radius: var(--rayon-lg);
  background: var(--fond-2);
  padding: 1.75rem 1.5rem 1.5rem;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

/*
 * La légende est posée DANS le cadre et non à cheval sur son bord : le rendu à
 * cheval dépend du navigateur, et il casse dès que le bloc a un fond différent
 * du sien — ce qui est exactement notre cas.
 */
.bloc legend {
  float: left;
  width: 100%;
  padding: 0;
  margin: 0 0 0.25rem;
  font-family: var(--police-titre);
  text-transform: uppercase;
  font-size: 1.125rem;
  letter-spacing: 0.01em;
}

.bloc legend + * {
  clear: both;
}

.champ {
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}

.champ label {
  font-weight: 600;
  font-size: 0.9375rem;
}

.champ .option {
  font-weight: 400;
  font-size: 0.8125rem;
  color: var(--texte-doux);
}

.champ input,
.champ select {
  font-family: inherit;
  font-size: 1rem;
  color: var(--texte);
  background: var(--fond);
  border: 1px solid var(--bord);
  border-radius: var(--rayon-sm);
  /* 44 px de haut au minimum : la cible tactile de l'application, ici aussi. */
  min-height: 2.75rem;
  padding: 0.5rem 0.75rem;
  width: 100%;
}

.champ input:focus-visible,
.champ select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.aide {
  margin: 0;
  font-size: 0.875rem;
  color: var(--texte-doux);
}

/*
 * Le sous-domaine et son suffixe sur la même ligne : c'est UNE adresse, et la
 * couper en deux champs ferait taper le domaine à qui ne l'a pas compris.
 */
.champ-suffixe {
  display: flex;
  align-items: stretch;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.champ-suffixe input {
  flex: 1 1 12rem;
}

.suffixe {
  display: flex;
  align-items: center;
  color: var(--texte-doux);
  font-size: 0.9375rem;
  white-space: nowrap;
}

/*
 * L'état du sous-domaine : le MOT, jamais la seule couleur. Un daltonien lit
 * « est libre » ou « déjà pris » aussi bien que n'importe qui ; deux teintes de
 * vert et de rouge ne lui diraient rien.
 */
.etat {
  margin: 0;
  font-size: 0.875rem;
  min-height: 1.25rem;
  color: var(--texte-doux);
}

/*
 * « fanfare.comptoirplus.ch est libre » se lit en VERT, jamais dans le rouge de
 * la marque : rouge, c'est la couleur du refus juste en dessous (un
 * sous-domaine pris), et le même ton pour « libre » et « pris » obligeait à
 * lire la phrase pour savoir de quel côté on tombait.
 */
.etat-libre {
  color: var(--succes);
  font-weight: 600;
}

.etat-pris {
  color: var(--ambre);
  font-weight: 600;
}

/*
 * LES CRITÈRES DU MOT DE PASSE, cochés pendant la frappe. Gris tant que rien
 * n'est tapé ; vert, avec la coche, dès qu'un critère est tenu. La coche est
 * dessinée en CSS — pas de « ✓ », qui sort en carré vide sur les vieilles
 * tablettes.
 */
.criteres {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.35rem;
  font-size: 0.875rem;
  color: var(--texte-doux);
}

.criteres li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  transition: color 0.2s var(--mouvement);
}

.critere-coche {
  flex: none;
  width: 1rem;
  height: 1rem;
  border-radius: 999px;
  border: 1px solid var(--bord);
  position: relative;
  transition: border-color 0.2s var(--mouvement), background-color 0.2s var(--mouvement);
}

.criteres li.acquis {
  color: var(--succes);
}

.criteres li.acquis .critere-coche {
  border-color: var(--succes);
  background: var(--succes);
}

.criteres li.acquis .critere-coche::after {
  content: '';
  position: absolute;
  left: 0.3rem;
  top: 0.12rem;
  width: 0.3rem;
  height: 0.5rem;
  border: solid var(--fond);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

/* Le mot pour les lecteurs d'écran : « acquis » ou « à faire », jamais la seule couleur. */
.criteres li[data-acquis='oui']::after {
  content: ' — acquis';
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/*
 * LE CHAMP AVEC SON BOUTON : le mot de passe, et « Afficher ».
 *
 * Le bouton est DANS le cadre du champ et non à côté : sur un téléphone, un
 * bouton posé à droite pousse le champ à la ligne suivante, et l'on se retrouve
 * avec un mot de passe large de six centimètres sous un bouton large de trois.
 */
.champ-avec-bouton {
  display: flex;
  align-items: stretch;
  gap: 0;
  border: 1px solid var(--bord);
  border-radius: var(--rayon);
  background: var(--fond-2);
  overflow: hidden;
}

.champ-avec-bouton:focus-within {
  border-color: var(--accent);
}

.champ-avec-bouton input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: transparent;
  border-radius: 0;
}

.champ-avec-bouton input:focus {
  outline: none;
  box-shadow: none;
}

.bouton-revele {
  flex: none;
  border: 0;
  border-left: 1px solid var(--bord);
  background: transparent;
  color: var(--texte-doux);
  font: inherit;
  font-size: 0.875rem;
  padding: 0 0.9rem;
  cursor: pointer;
  transition: color 0.2s var(--mouvement), background-color 0.2s var(--mouvement);
}

.bouton-revele:hover {
  background: var(--fond-3);
  color: var(--texte);
}

.bouton-revele[aria-pressed='true'] {
  color: var(--accent);
}

/*
 * LES TROIS ÉTATS D'UN CRITÈRE, et c'est le cœur du sujet.
 *
 * Il n'y en avait que deux : gris (rien à dire) et vert (acquis). Un mot de
 * passe qui NE TIENT PAS un critère était donc affiché exactement comme un champ
 * vide — même gris, même cercle creux. On ne savait pas si l'on n'avait pas
 * encore assez tapé ou si ce qu'on avait tapé était refusé, et l'on ne
 * l'apprenait qu'à l'envoi.
 *
 * Trois états, donc : NEUTRE tant que le champ est vide — on n'accuse pas un
 * formulaire que personne n'a touché —, ACQUIS en vert avec la coche, et
 * MANQUANT en ambre avec une barre. L'ambre et non le rouge : ce n'est pas une
 * faute, c'est un travail en cours.
 */
.criteres li[data-etat='manquant'] {
  color: var(--ambre);
}

.criteres li[data-etat='manquant'] .critere-coche {
  border-color: var(--ambre);
}

.criteres li[data-etat='manquant'] .critere-coche::after {
  content: '';
  position: absolute;
  left: 0.2rem;
  top: 0.42rem;
  width: 0.5rem;
  height: 2px;
  background: var(--ambre);
}

/* Le mot pour les lecteurs d'écran, comme pour « acquis » : jamais la seule couleur. */
.criteres li[data-etat='manquant']::after {
  content: ' — à faire';
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/*
 * L'ERREUR SOUS LE CHAMP, à l'endroit où on la corrige.
 *
 * La boîte rouge en pied de formulaire dit CE qui ne va pas et laisse chercher
 *  ; celle-ci dit où. Les deux coexistent : la boîte reste, pour le refus que
 * seul le serveur peut prononcer.
 */
.champ-erreur {
  margin: 0.35rem 0 0;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ambre);
}

.champ input[aria-invalid='true'],
.champ-avec-bouton:has(input[aria-invalid='true']) {
  border-color: var(--ambre);
}

.groupe-champs {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.champ-large {
  flex: 3 1 12rem;
}

.champ-etroit {
  flex: 1 1 6rem;
}

/*
 * LE RÉCAPITULATIF DU PALIER, sous le choix : ce qu'on prend et ce que ça
 * coûte, relu depuis la même source que celle qui facture. Il est là pour la
 * personne qui a comparé quatre cartes il y a deux minutes et ne sait plus
 * laquelle elle avait retenue.
 */
.recap {
  border: 1px solid var(--bord);
  border-radius: var(--rayon);
  background: var(--fond-3);
  padding: 1rem 1.25rem;
}

.recap-prix {
  margin: 0 0 0.5rem;
  font-size: 1.75rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--texte);
}

.recap-clauses {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  font-size: 0.9375rem;
  color: var(--texte-doux);
}

.recap-clauses li {
  position: relative;
  padding-left: 1.5rem;
}

.recap-clauses li::before {
  content: '✓';
  position: absolute;
  left: 0;
  top: 0;
  color: var(--accent);
  font-weight: 700;
}

.recap-clauses li.clause-non {
  opacity: 0.6;
}

.recap-clauses li.clause-non::before {
  content: '—';
  color: var(--texte-doux);
  font-weight: 400;
}

/* ──────────────────────── Choix du règlement ──────────────────────── */

.choix {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/*
 * L'ÉTIQUETTE ENTIÈRE EST CLIQUABLE, pas seulement le petit rond. C'est la
 * différence entre un choix qu'on fait du pouce sur un téléphone et un choix
 * qu'on rate deux fois.
 */
.option-reglement {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.25rem 0.75rem;
  align-items: start;
  border: 1px solid var(--bord);
  border-radius: var(--rayon);
  padding: 1rem;
  cursor: pointer;
}

.option-reglement:has(input:checked) {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
  background: var(--accent-doux);
}

.option-reglement input {
  grid-row: 1 / span 3;
  width: 1.25rem;
  height: 1.25rem;
  margin: 0.125rem 0 0;
  accent-color: var(--accent);
}

.option-titre {
  font-weight: 600;
}

.option-detail,
.option-refus {
  font-size: 0.875rem;
  color: var(--texte-doux);
  grid-column: 2;
}

.option-refus {
  color: var(--ambre);
}

/*
 * Un moyen éteint reste LISIBLE et reste AFFICHÉ, avec sa raison juste en
 * dessous. Le faire disparaître laisserait croire que la facture n'existe pas ;
 * le griser sans rien dire ferait chercher pourquoi. « À partir de la formule
 * Fête » répond à la question avant qu'on la pose, et vend le palier du dessus.
 */
.option-eteinte {
  opacity: 0.65;
  cursor: default;
}

.case {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.75rem;
  align-items: start;
  font-size: 0.9375rem;
  cursor: pointer;
}

.case input {
  width: 1.25rem;
  height: 1.25rem;
  margin: 0.125rem 0 0;
  accent-color: var(--accent);
}

/*
 * L'AVIS et L'ERREUR : deux cartouches, deux rôles. L'avis explique une
 * situation normale (« cette offre se règle sur devis ») ; l'erreur signale ce
 * qu'il faut corriger, et elle porte `role="alert"` dans le HTML pour être lue
 * à voix haute au moment où elle apparaît.
 */
.avis,
.erreur {
  margin: 0;
  padding: 0.875rem 1rem;
  border-radius: var(--rayon);
  border: 1px solid var(--bord);
  background: var(--fond-3);
  font-size: 0.9375rem;
  color: var(--texte-doux);
}

.avis strong {
  color: var(--texte);
}

.avis-alerte,
.erreur {
  border-color: var(--ambre);
  background: var(--accent-doux);
  color: var(--texte);
}

.actions-formulaire {
  align-items: center;
}

/* ─────────────────────────────── Sections ────────────────────────────── */

.section {
  padding: 3rem 0;
  border-top: 1px solid var(--bord);
}

.etapes {
  list-style: none;
  counter-reset: etape;
  padding: 0;
  margin: 2rem 0 0;
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
}

.etapes li {
  counter-increment: etape;
  position: relative;
  padding-left: 3rem;
}

.etapes li::before {
  content: counter(etape);
  position: absolute;
  left: 0;
  top: 0;
  width: 2.25rem;
  height: 2.25rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--accent-doux);
  color: var(--accent-fort);
  font-family: var(--police-titre);
  font-size: 1.125rem;
}

.etapes strong {
  display: block;
  color: var(--texte);
  margin-bottom: 0.25rem;
}

/* ──────────────────────────────── Pied ───────────────────────────────── */

.pied {
  border-top: 1px solid var(--bord);
  padding: 2rem 0 3rem;
  color: var(--texte-doux);
  font-size: 0.875rem;
}

.pied p {
  font-size: inherit;
}

/*
 * Le mouvement est retiré d'un bloc pour qui l'a demandé. Rien ici n'anime une
 * information : les transitions ne sont que du confort.
 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ═══════════════════════════════ Accueil ═══════════════════════════════ */

/*
 * LA PAGE D'ACCUEIL EST UNE PAGE DE VENTE, et tout ce qui suit sert une seule
 * chose : qu'on comprenne le produit en cinq secondes et qu'on aille voir le
 * prix. Peu de texte, une idée par bloc, un seul appel répété — « Voir les
 * tarifs » —, et une démonstration dessinée en HTML plutôt qu'une capture
 * d'écran, parce qu'une capture vieillit et qu'un dessin se repeint.
 */

html {
  scroll-padding-top: 5.5rem;
}

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

::selection {
  background: var(--accent);
  color: #fff;
}

body.accueil {
  overflow-x: clip;
}

/* Le lien d'évasion : invisible jusqu'au premier Tab, et alors impossible à rater. */
.evasion {
  position: absolute;
  left: 1rem;
  top: -4rem;
  z-index: 100;
  padding: 0.75rem 1.25rem;
  border-radius: var(--rayon);
  background: var(--texte);
  color: var(--fond);
  text-decoration: none;
  font-weight: 600;
  transition: top 0.32s var(--mouvement);
}

.evasion:focus-visible {
  top: 1rem;
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* ─────────────────────────── En-tête fixé ─────────────────────────── */

.entete-fixe {
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in srgb, var(--fond) 78%, transparent);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  backdrop-filter: blur(18px) saturate(1.4);
  border-bottom: 1px solid var(--bord);
}

.entete-accueil {
  max-width: 68rem;
  margin: 0 auto;
  padding: 0.75rem 1.5rem;
  flex-wrap: nowrap;
}

.entete-accueil .navigation {
  gap: 1.75rem;
  flex-wrap: nowrap;
}

.entete-accueil .navigation .bouton {
  padding: 0.625rem 1.125rem;
  font-size: 0.9375rem;
}

/*
 * Sur un téléphone il reste le logo et l'appel. Les trois ancres partent :
 * la page se lit de haut en bas, et le bouton dit déjà où elle mène.
 */
.entete-accueil .navigation a {
  white-space: nowrap;
}

@media (max-width: 1080px) {
  .entete-accueil .navigation {
    gap: 1.125rem;
  }
}

/* En dessous de 920 px, les ancres ne tiennent plus sur une ligne avec le logo, la bascule et l'appel. */
@media (max-width: 920px) {
  .entete-accueil .navigation a:not(.bouton) {
    display: none;
  }
}

/* ───────────────────────────── Héros ───────────────────────────── */

.heros-accueil {
  padding: clamp(3rem, 8vw, 6rem) 0 clamp(2.5rem, 6vw, 4.5rem);
}

.heros-accueil-grille {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}

.surtitre {
  margin: 0 0 1rem;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-fort);
}

.heros-texte h1 {
  font-size: clamp(3rem, 8.5vw, 5.75rem);
  margin-bottom: 1.25rem;
  letter-spacing: 0.005em;
}

/*
 * Le seul mot en dégradé de toute la page : celui qu'on vend. Partout
 * ailleurs le dégradé est réservé aux boutons, pour qu'il continue de dire
 * « cliquez ici ».
 */
.heros-texte h1 em {
  font-style: normal;
  background: var(--degrade);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.heros-texte .accroche {
  max-width: 31rem;
  margin-bottom: 2rem;
}

.preuves {
  list-style: none;
  margin: 1.75rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.75rem;
  font-size: 0.9375rem;
  color: var(--texte-doux);
}

.preuves li {
  position: relative;
  padding-left: 1.125rem;
}

.preuves li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--degrade);
}

.preuves strong {
  color: var(--texte);
  font-weight: 700;
}

/* ──────────────────────── La démonstration ──────────────────────── */

.demo {
  position: relative;
  display: flex;
  justify-content: flex-end;
  padding: 1rem 0 1.5rem;
}

/*
 * Le téléphone porte SA charte, toujours de nuit : c'est ce que voient les
 * bénévoles à 23 h, et c'est aussi ce qui le détache du papier de la page. Ses
 * couleurs sont celles de l'ancienne caisse, à l'identique — ce n'est pas un
 * décor, c'est le produit.
 */
.tel {
  --t-fond: #070608;
  --t-surface: rgb(34 28 38 / 0.92);
  --t-surface-2: rgb(46 38 52 / 0.75);
  --t-bord: rgb(255 255 255 / 0.09);
  --t-texte: #f5f1ec;
  --t-doux: #b5aca6;
  --t-rouge: #e63946;
  --t-rose: #f72585;
  --t-ambre: #fbbf24;
  --t-vert: #4ade80;

  position: relative;
  z-index: 1;
  width: min(19.5rem, 100%);
  aspect-ratio: 9 / 18.6;
  border: 0.5rem solid #15111a;
  border-radius: 2.75rem;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 1rem 0.875rem 0.875rem;
  color: var(--t-texte);
  font-size: 0.8125rem;
  line-height: 1.35;
  background-color: var(--t-fond);
  background-image:
    radial-gradient(18rem 10rem at 15% -10%, color-mix(in srgb, #e63946 16%, transparent), transparent 60%),
    radial-gradient(16rem 9rem at 100% 0%, color-mix(in srgb, #a855f7 14%, transparent), transparent 55%);
  box-shadow:
    0 50px 90px -35px rgb(0 0 0 / 0.6),
    0 0 0 1px rgb(255 255 255 / 0.06);
}

.tel-barre {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.25rem 0.125rem 0;
}

.tel-titre {
  font-family: var(--police-titre);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: 0.875rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tel-etat {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.25rem 0.5rem;
  border-radius: 999px;
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  color: var(--t-ambre);
  background: color-mix(in srgb, var(--t-ambre) 14%, transparent);
}

.tel-etat i {
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 50%;
  background: var(--t-ambre);
  animation: pouls 2.4s var(--mouvement) infinite;
}

@keyframes pouls {
  0% {
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--t-ambre) 50%, transparent);
  }
  70% {
    box-shadow: 0 0 0 0.375rem color-mix(in srgb, var(--t-ambre) 0%, transparent);
  }
  100% {
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--t-ambre) 0%, transparent);
  }
}

.tel-tuiles {
  flex: 1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-auto-rows: 1fr;
  gap: 0.5rem;
  min-height: 0;
}

.tuile {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 0.25rem;
  padding: 0.625rem 0.75rem;
  border-radius: 0.875rem;
  background: var(--t-surface);
  border: 1px solid var(--t-bord);
  transform-origin: center;
}

.tuile span {
  font-weight: 600;
}

.tuile b {
  font-family: var(--police-titre);
  font-weight: 400;
  font-size: 1.25rem;
  line-height: 1;
  letter-spacing: 0.02em;
}

.tuile small {
  font-size: 0.625rem;
  color: var(--t-ambre);
}

/*
 * Une tuile se fait TAPER toutes les cinq secondes : elle s'enfonce, rougit,
 * revient. C'est le seul geste de la caisse, et il suffit à faire comprendre
 * la caisse.
 */
.tuile-tape {
  animation: tape 5s var(--mouvement) 1.5s infinite;
}

@keyframes tape {
  0%,
  100% {
    transform: scale(1);
    background: var(--t-surface);
    box-shadow: 0 0 0 0 transparent;
  }
  6%,
  12% {
    transform: scale(0.94);
    background: color-mix(in srgb, var(--t-rouge) 38%, var(--t-surface));
    box-shadow: 0 0 0 2px var(--t-rouge);
  }
  22% {
    transform: scale(1);
    background: var(--t-surface);
    box-shadow: 0 0 0 0 transparent;
  }
}

.tel-panier {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: 0.75rem 0.875rem 0.875rem;
  border-radius: 1.125rem;
  background: var(--t-surface);
  border: 1px solid var(--t-bord);
}

.tel-ligne {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  color: var(--t-doux);
  font-variant-numeric: tabular-nums;
}

.tel-consigne {
  color: var(--t-ambre);
}

.tel-total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-top: 0.375rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--t-bord);
  font-family: var(--police-titre);
  text-transform: uppercase;
  font-size: 1.25rem;
  letter-spacing: 0.02em;
}

.tel-payer {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.5rem;
  margin-top: 0.625rem;
}

.tel-payer span {
  display: grid;
  place-items: center;
  min-height: 2.5rem;
  border-radius: 0.75rem;
  font-weight: 700;
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
}

.tel-especes {
  background: linear-gradient(135deg, var(--t-rouge), var(--t-rose));
  color: #fff;
}

.tel-twint {
  background: var(--t-texte);
  color: var(--t-fond);
}

/*
 * LE TICKET DU LENDEMAIN, posé de travers sur le flanc du téléphone : c'est
 * le second argument de vente, celui du caissier. Il reste en papier même de
 * nuit — un ticket de caisse est blanc, et c'est ce qui le fait reconnaître.
 *
 * Il recouvre les TUILES et non le panier : les tuiles se répètent, le panier
 * et ses deux boutons de règlement ne se lisent qu'une fois.
 */
.ticket {
  position: absolute;
  left: -2rem;
  bottom: 11rem;
  z-index: 2;
  width: min(18.5rem, 85%);
  padding: 0.875rem 1rem 1rem;
  border-radius: 0.75rem;
  background: #fffdfa;
  color: #1a1518;
  font-size: 0.8125rem;
  line-height: 1.4;
  transform: rotate(-3deg);
  box-shadow:
    0 1px 2px rgb(26 21 24 / 0.08),
    0 28px 50px -22px rgb(26 21 24 / 0.45);
}

.ticket-titre {
  margin: 0 0 0.5rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px dashed rgb(26 21 24 / 0.25);
  font-family: var(--police-titre);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.875rem;
  color: #1a1518;
}

/* Trois colonnes : le produit, la quantité et son prix unitaire, le montant. */
.ticket-ligne {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 0.6rem;
  padding: 0.15rem 0;
  color: #453d39;
  font-variant-numeric: tabular-nums;
}

.ticket-ligne > :first-child {
  white-space: nowrap;
}

.ticket-ligne > :last-child {
  text-align: right;
  min-width: 4rem;
}

.ticket-qte {
  color: #8a807b;
  font-size: 0.75rem;
}

/* La consigne : ambre quand elle entre, verte quand elle ressort — la charte de la caisse. */
.ticket-consigne {
  color: #a04a08;
}

.ticket-rendu {
  color: #15803d;
}

.ticket-somme {
  margin-top: 0.4rem;
  padding-top: 0.5rem;
  border-top: 1px dashed rgb(26 21 24 / 0.25);
  color: #1a1518;
  font-weight: 700;
  font-size: 0.9375rem;
}

@media (max-width: 860px) {
  .heros-accueil-grille {
    grid-template-columns: 1fr;
  }

  .heros-texte {
    text-align: center;
  }

  .heros-texte .accroche,
  .heros-texte .actions,
  .preuves {
    margin-left: auto;
    margin-right: auto;
    justify-content: center;
  }

  /* Sur une colonne, le ticket passe SOUS le téléphone : plus rien à recouvrir. */
  .demo {
    flex-direction: column;
    align-items: center;
    padding: 1rem 0 1rem;
  }

  .ticket {
    position: static;
    width: min(18rem, 92%);
    margin-top: -1.75rem;
    transform: rotate(-1.5deg);
  }
}

/* ───────────────────────── Les quatre « sans » ───────────────────────── */

.bande {
  border-top: 1px solid var(--bord);
  border-bottom: 1px solid var(--bord);
  background: color-mix(in srgb, var(--fond-2) 55%, transparent);
}

.bande-liste {
  list-style: none;
  margin: 0 auto;
  padding: 1.125rem 1.5rem;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 2.75rem;
  font-size: 0.9375rem;
  color: var(--texte-doux);
}

.bande-liste strong {
  margin-right: 0.3rem;
  font-family: var(--police-titre);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent-fort);
}

/* ───────────────────────────── Sections ───────────────────────────── */

.section-accueil {
  padding: clamp(3.5rem, 8vw, 6.5rem) 0;
}

.section-atouts {
  background: color-mix(in srgb, var(--fond-3) 50%, transparent);
  border-top: 1px solid var(--bord);
  border-bottom: 1px solid var(--bord);
}

.titre-section {
  max-width: 40rem;
  margin-bottom: clamp(2rem, 4vw, 3.25rem);
}

.titre-section h2 {
  font-size: clamp(2rem, 4.5vw, 3.125rem);
  margin-bottom: 0;
}

.titre-section-suite {
  margin: 0.75rem 0 0;
  font-size: 1.125rem;
}

.enveloppe-etroite {
  max-width: 46rem;
}

/* Une carte, la même partout : papier, trait fin, arrondi large, ombre discrète. */
.parcours li,
.atout,
.apercu-carte {
  background: var(--fond-2);
  border: 1px solid var(--bord);
  border-radius: var(--rayon-xl);
  box-shadow: var(--ombre-carte);
}

/* ────────────────────────────── Parcours ────────────────────────────── */

.parcours {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1.25rem;
}

.parcours li {
  display: flex;
  flex-direction: column;
  padding: 1rem 1.75rem 1.875rem;
}

/* Un bouton en bas d'une carte illustrée se cale au pied, comme sur la grille des tarifs. */
.parcours .choisir {
  margin: auto 0 0;
  padding-top: 1.25rem;
}

/*
 * L'ILLUSTRATION DE L'ÉTAPE, en tête de carte : une scène de huit rem, sur un
 * fond un ton en dessous du papier, qui montre ce que la ligne d'en dessous
 * dit. Le numéro s'est fait petit pour lui laisser la place.
 */
.parcours-illu {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  height: 8.5rem;
  margin: 0 -0.75rem 1.25rem;
  padding: 1rem;
  border-radius: 1.125rem;
  background: color-mix(in srgb, var(--fond-3) 70%, transparent);
  overflow: hidden;
}

.parcours-num {
  display: block;
  margin-bottom: 0.5rem;
  font-family: var(--police-titre);
  font-size: 1.5rem;
  line-height: 1;
  letter-spacing: 0.02em;
  background: var(--degrade);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* 01 — trois formules, une cochée. */
.mini-formule {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  padding: 0.5rem 0.625rem;
  border-radius: 0.75rem;
  background: var(--fond-2);
  border: 1px solid var(--bord);
  font-size: 0.6875rem;
  color: var(--texte-doux);
  min-width: 4.25rem;
}

.mini-formule b {
  font-family: var(--police-titre);
  font-weight: 400;
  text-transform: uppercase;
  font-size: 0.8125rem;
  color: var(--texte);
}

.mini-formule i {
  font-style: normal;
  font-weight: 600;
  color: var(--texte);
}

.mini-formule.choisie {
  position: relative;
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
  transform: translateY(-0.25rem);
}

.mini-formule.choisie::after {
  content: '✓';
  position: absolute;
  top: -0.5rem;
  right: -0.5rem;
  width: 1.125rem;
  height: 1.125rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--degrade-bouton);
  color: #fff;
  font-size: 0.6875rem;
  font-weight: 700;
}

/* 02 — la carte, en papier, et son affiche PDF. */
.mini-carte {
  width: 12rem;
  padding: 0.625rem 0.75rem 0.75rem;
  border-radius: 0.5rem;
  background: #fffdfa;
  color: #1a1518;
  font-size: 0.6875rem;
  box-shadow:
    0 1px 2px rgb(26 21 24 / 0.08),
    0 14px 28px -16px rgb(26 21 24 / 0.4);
  transform: rotate(-2deg);
}

.mini-carte-titre {
  margin: 0 0 0.375rem;
  padding-bottom: 0.25rem;
  border-bottom: 1px dashed rgb(26 21 24 / 0.25);
  font-family: var(--police-titre);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.75rem;
  color: #1a1518;
}

.mini-ligne {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  padding: 0.1rem 0;
  color: #453d39;
}

.mini-ligne span {
  font-weight: 600;
  color: #1a1518;
}

.mini-ligne em {
  font-style: normal;
  font-size: 0.5625rem;
  color: #a04a08;
}

.mini-ligne b {
  margin-left: auto;
  font-family: var(--police-titre);
  font-weight: 400;
  font-size: 0.8125rem;
  color: #1a1518;
}

.mini-pdf {
  position: absolute;
  right: 1rem;
  bottom: 0.875rem;
  padding: 0.3rem 0.625rem;
  border-radius: 999px;
  background: var(--degrade-bouton);
  color: #fff;
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  box-shadow: var(--ombre-bouton);
}

/* 03 — six chiffres et la caisse s'ouvre. */
.parcours-illu:has(.mini-code) {
  flex-direction: column;
  gap: 0.75rem;
}

.mini-code {
  display: flex;
  gap: 0.3rem;
}

.mini-code span {
  width: 1.75rem;
  height: 2.25rem;
  display: grid;
  place-items: center;
  border-radius: 0.5rem;
  background: var(--fond-2);
  border: 1px solid var(--bord);
  font-family: var(--police-titre);
  font-size: 1.125rem;
  color: var(--texte);
}

.mini-code span:last-child {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}

.mini-ouvrir {
  padding: 0.375rem 0.875rem;
  border-radius: 0.625rem;
  background: var(--degrade-bouton);
  color: #fff;
  font-size: 0.75rem;
  font-weight: 700;
  box-shadow: var(--ombre-bouton);
}

.parcours h3 {
  font-size: 1.25rem;
  margin-bottom: 0.5rem;
}

.parcours p {
  margin: 0;
  font-size: 0.9375rem;
}

/* ─────────────────────────────── Atouts ─────────────────────────────── */

.atouts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.25rem;
}

.atout {
  padding: 1.625rem 1.625rem 1.75rem;
}

.atout-large {
  grid-column: span 2;
}

@media (max-width: 860px) {
  .atouts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 560px) {
  .atouts {
    grid-template-columns: 1fr;
  }

  .atout-large {
    grid-column: auto;
  }
}

.atout-icone {
  width: 2.75rem;
  height: 2.75rem;
  padding: 0.625rem;
  margin-bottom: 1.125rem;
  border-radius: 0.875rem;
  background: var(--accent-doux);
  color: var(--accent-fort);
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.atout h3 {
  font-size: 1.125rem;
  margin-bottom: 0.5rem;
}

.atout p {
  margin: 0;
  font-size: 0.9375rem;
}

.atout-large p {
  max-width: 34rem;
}

/* Hors ligne → synchronisé : la file d'attente qui avance toute seule. */
.atout-illustration {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1.5rem;
  max-width: 24rem;
}

.pastille {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.375rem 0.75rem;
  border-radius: 999px;
  font-size: 0.8125rem;
  font-weight: 600;
  white-space: nowrap;
}

.pastille::before {
  content: '';
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: currentColor;
}

.pastille-hors {
  color: var(--ambre);
  background: color-mix(in srgb, var(--ambre) 12%, transparent);
}

.pastille-ok {
  color: var(--succes);
  background: color-mix(in srgb, var(--succes) 12%, transparent);
}

.fleche {
  flex: 1;
  height: 2px;
  background: repeating-linear-gradient(90deg, var(--texte-doux) 0 6px, transparent 6px 14px);
  opacity: 0.55;
  animation: file 1.2s linear infinite;
}

@keyframes file {
  to {
    background-position: 14px 0;
  }
}

/* ───────────────────────── Aperçu des tarifs ───────────────────────── */

.apercu {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 1.25rem;
  align-items: stretch;
}

/*
 * La carte entière est le lien : on ne cherche pas un bouton dans un prix. Elle
 * se soulève au survol — le seul mouvement de la section, réservé à ce qui se
 * clique.
 */
.apercu-carte {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  padding: 1.75rem;
  color: var(--texte);
  text-decoration: none;
  transition:
    transform 0.32s var(--mouvement),
    box-shadow 0.32s var(--mouvement),
    border-color 0.32s var(--mouvement);
}

.apercu-carte:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--accent) 45%, var(--bord));
}

.apercu-carte:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.apercu-carte.avant {
  border-color: var(--accent);
  box-shadow:
    0 0 0 1px var(--accent),
    var(--ombre-carte);
}

.apercu-carte .palier {
  font-family: var(--police-titre);
  text-transform: uppercase;
  font-size: 1.125rem;
  letter-spacing: 0.02em;
  color: var(--texte-doux);
}

.apercu-carte .prix {
  display: block;
  font-size: 2.5rem;
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

.apercu-carte .prix small {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.875rem;
  font-weight: 400;
  color: var(--texte-doux);
}

.apercu-repere {
  margin-top: 0.5rem;
  font-size: 0.9375rem;
  color: var(--texte-doux);
}

.apercu-suite {
  margin: 2.25rem 0 0;
  text-align: center;
}

/* ────────────────────────────── Questions ────────────────────────────── */

.faq {
  border-top: 1px solid var(--bord);
}

.faq details {
  border-bottom: 1px solid var(--bord);
}

.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.125rem 0;
  cursor: pointer;
  list-style: none;
  font-weight: 600;
  font-size: 1.0625rem;
  color: var(--texte);
  transition: color 0.32s var(--mouvement);
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary:hover {
  color: var(--accent-fort);
}

.faq summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 0.375rem;
}

/* Un « + » qui devient « × » : le signe de la marque, et le geste d'ouvrir. */
.faq summary::after {
  content: '+';
  flex: none;
  width: 1.75rem;
  height: 1.75rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--accent-doux);
  color: var(--accent-fort);
  font-size: 1.25rem;
  font-weight: 500;
  line-height: 1;
  transition: transform 0.32s var(--mouvement);
}

.faq details[open] summary::after {
  transform: rotate(45deg);
}

.faq details p {
  margin: 0 0 1.25rem;
  padding-right: 3.25rem;
  font-size: 0.9875rem;
}

/* ───────────────────────────── Appel final ───────────────────────────── */

.appel {
  padding: clamp(4rem, 10vw, 7rem) 0;
  text-align: center;
  border-top: 1px solid var(--bord);
}

.appel-contenu {
  max-width: 42rem;
}

/*
 * Même mécanique que `.marque-logo` : un masque, peint dans l'encre du texte.
 * Le logo de fête a deux encres à l'origine — orange et noir — et le noir
 * disparaît sur un fond sombre ; en silhouette, il n'a plus qu'une encre et
 * suit la nuit tout seul.
 */
.appel-logo {
  display: block;
  width: min(17rem, 60%);
  aspect-ratio: 749 / 462;
  margin: 0 auto 1.5rem;
  background: var(--texte);
  -webkit-mask: url('/marque/logo-fete.png') center / contain no-repeat;
  mask: url('/marque/logo-fete.png') center / contain no-repeat;
}

.appel h2 {
  font-size: clamp(2rem, 5vw, 3.25rem);
  margin-bottom: 0.75rem;
}

.appel p {
  font-size: 1.125rem;
  margin-bottom: 2rem;
}

.actions-centrees {
  justify-content: center;
}

.pied-accueil {
  padding: 0;
}

.pied-grille {
  padding-top: 2rem;
  padding-bottom: 3rem;
}

.pied-grille p:last-child {
  margin-bottom: 0;
}

/* ──────────────────────── Apparition au défilement ──────────────────────── */

/*
 * Rien n'est caché sans JavaScript (voir accueil.js) : la classe `js` sur
 * <html> est la condition. Le mouvement est court et bas — dix-huit pixels,
 * sept dixièmes de seconde — pour accompagner la lecture, pas la retenir.
 */
html.js [data-revele] {
  opacity: 0;
  translate: 0 18px;
  transition:
    opacity 0.72s var(--mouvement),
    translate 0.72s var(--mouvement);
}

html.js [data-revele].revele {
  opacity: 1;
  translate: 0 0;
}

html.js .parcours li:nth-child(2),
html.js .atout:nth-child(2),
html.js .atout:nth-child(5) {
  transition-delay: 0.08s;
}

html.js .parcours li:nth-child(3),
html.js .atout:nth-child(3),
html.js .atout:nth-child(6) {
  transition-delay: 0.16s;
}

/* ═══════════════════════════════ Tarifs ═══════════════════════════════ */

/*
 * La page des tarifs emprunte tout à l'accueil — en-tête fixé, héros, cartes
 * illustrées — et n'ajoute que ses propres scènes : une quittance, une
 * facture QR, une caisse qui reste ouverte, des appareils, des jours, une
 * jauge, et les trois façons d'encaisser. Toutes dessinées avec les mêmes
 * briques que le téléphone du héros.
 */

.heros-tarifs {
  padding-bottom: 0;
}

.heros-tarifs .heros-texte {
  max-width: 44rem;
}

.section-grille {
  padding-top: clamp(2rem, 5vw, 3.5rem);
}

.section-grille .offre {
  margin: 0 auto;
}

/* Une pastille d'étiquette sur une scène : verte pour ce qui est ouvert. */
.mini-badge {
  padding: 0.3rem 0.625rem;
  border-radius: 999px;
  background: var(--fond-2);
  border: 1px solid var(--bord);
  color: var(--texte);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.mini-badge-ok {
  position: absolute;
  right: 0.875rem;
  top: 0.875rem;
  border-color: transparent;
  background: var(--succes);
  color: #fff;
  box-shadow: 0 8px 18px -8px color-mix(in srgb, var(--succes) 60%, transparent);
}

/* Une facture avec son QR : le carré, en damier de dégradés. */
.mini-facture {
  width: 12.5rem;
}

.mini-facture-corps {
  display: flex;
  align-items: center;
  gap: 0.625rem;
}

.mini-qr {
  display: block;
  flex: none;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 0.25rem;
  background-color: #fffdfa;
  background-image:
    linear-gradient(#1a1518, #1a1518),
    linear-gradient(#1a1518, #1a1518),
    linear-gradient(#1a1518, #1a1518),
    repeating-linear-gradient(90deg, #1a1518 0 3px, transparent 3px 6px),
    repeating-linear-gradient(0deg, #1a1518 0 3px, transparent 3px 7px);
  background-size:
    30% 30%,
    30% 30%,
    30% 30%,
    60% 40%,
    40% 60%;
  background-position:
    0 0,
    100% 0,
    0 100%,
    100% 100%,
    40% 100%;
  background-repeat: no-repeat;
  outline: 2px solid #fffdfa;
  outline-offset: -4px;
}

.mini-qr-grand {
  width: 4rem;
  height: 4rem;
  border-radius: 0.375rem;
}

/* Une scène de nuit, dans la charte de la caisse. */
.mini-nuit {
  --t-fond: #070608;
  --t-surface: rgb(34 28 38 / 0.92);
  --t-bord: rgb(255 255 255 / 0.09);
  --t-texte: #f5f1ec;
  --t-doux: #b5aca6;
  --t-vert: #4ade80;
  --t-ambre: #fbbf24;

  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.25rem;
  width: 13rem;
  padding: 0.875rem 1rem;
  border-radius: 1rem;
  border: 1px solid var(--t-bord);
  color: var(--t-texte);
  font-size: 0.75rem;
  background-color: var(--t-fond);
  background-image:
    radial-gradient(10rem 6rem at 10% -10%, color-mix(in srgb, #e63946 18%, transparent), transparent 60%),
    radial-gradient(9rem 5rem at 100% 0%, color-mix(in srgb, #a855f7 14%, transparent), transparent 55%);
  box-shadow: 0 24px 40px -22px rgb(0 0 0 / 0.6);
}

.mini-nuit b {
  font-family: var(--police-titre);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  font-size: 0.9375rem;
  line-height: 1.15;
}

.mini-nuit small {
  font-size: 0.6875rem;
  color: var(--t-doux);
}

.mini-nuit-etat {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  margin-bottom: 0.25rem;
  padding: 0.2rem 0.5rem;
  border-radius: 999px;
  font-size: 0.625rem;
  font-weight: 600;
  color: var(--t-vert);
  background: color-mix(in srgb, var(--t-vert) 14%, transparent);
}

.mini-nuit-etat i {
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 50%;
  background: var(--t-vert);
}

.mini-nuit-ligne {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  width: 100%;
  color: var(--t-doux);
}

.mini-nuit-ligne b {
  font-size: 1.125rem;
  color: var(--t-texte);
}

.mini-nuit-rendu,
.mini-nuit-rendu b {
  color: var(--t-vert);
}

/* La pièce est posée sur le coin : les montants s'arrêtent avant. */
.mini-monnaie {
  position: relative;
  gap: 0.375rem;
  padding-right: 3rem;
}

/* La pièce ambrée de l'écran de rendu, posée sur le coin. */
.mini-piece {
  position: absolute;
  right: -0.75rem;
  bottom: -0.75rem;
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  background: var(--t-ambre);
  color: #2a1607;
  font-size: 0.625rem;
  font-weight: 700;
  border: 2px solid #fffdfa;
  box-shadow: 0 8px 16px -8px rgb(0 0 0 / 0.5);
}

.mini-twint {
  align-items: center;
  width: auto;
  gap: 0.5rem;
  padding: 0.75rem 1.5rem;
}

.mini-twint b {
  font-size: 1.125rem;
}

/* Six appareils : des téléphones en silhouette, tous allumés. */
.mini-appareils {
  display: grid;
  grid-template-columns: repeat(6, 1.25rem);
  gap: 0.375rem;
}

.mini-appareils span {
  height: 2.25rem;
  border-radius: 0.375rem;
  border: 2px solid var(--texte-doux);
  background: var(--fond-2);
  opacity: 0.4;
  position: relative;
}

.mini-appareils span.allume {
  opacity: 1;
  border-color: var(--accent);
  background: var(--accent-doux);
}

.mini-appareils span::after {
  content: '';
  position: absolute;
  left: 50%;
  bottom: 0.2rem;
  width: 0.5rem;
  height: 2px;
  border-radius: 1px;
  background: currentColor;
  transform: translateX(-50%);
  opacity: 0.5;
}

/* Trois jours et la fin qui déborde sur le lundi. */
.mini-jours {
  display: flex;
  align-items: center;
  gap: 0.375rem;
}

.mini-jours span {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 0.625rem;
  background: var(--accent-doux);
  color: var(--accent-fort);
  font-family: var(--police-titre);
  font-size: 0.875rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.mini-jours .mini-jours-fin {
  width: auto;
  padding: 0 0.625rem;
  background: var(--fond-2);
  border: 1px solid var(--bord);
  color: var(--texte);
  font-family: var(--police-texte);
  font-weight: 600;
  font-size: 0.75rem;
  text-transform: none;
  letter-spacing: 0;
  white-space: nowrap;
}

/* La jauge des commandes : presque pleine, et la phrase qui rassure. */
.mini-jauge {
  width: 13rem;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
  font-size: 0.75rem;
  color: var(--texte-doux);
}

.mini-jauge-tete {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
}

.mini-jauge-tete b {
  color: var(--texte);
  font-variant-numeric: tabular-nums;
}

.mini-jauge-barre {
  height: 0.625rem;
  border-radius: 999px;
  background: var(--fond-2);
  border: 1px solid var(--bord);
  overflow: hidden;
}

.mini-jauge-barre i {
  display: block;
  width: 96%;
  height: 100%;
  border-radius: 999px;
  background: var(--degrade);
}

.mini-jauge small {
  font-size: 0.6875rem;
  color: var(--succes);
  font-weight: 600;
}

/* Le terminal de carte : l'appareil qu'on a déjà, à côté de la caisse. */
.parcours-illu:has(.mini-terminal) {
  flex-direction: column;
  gap: 0.625rem;
}

.mini-terminal {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.375rem;
  width: 4.75rem;
  padding: 0.5rem 0.5rem 0.625rem;
  border-radius: 0.75rem 0.75rem 0.5rem 0.5rem;
  background: #2a2530;
  box-shadow: 0 14px 24px -14px rgb(0 0 0 / 0.6);
}

.mini-terminal-ecran {
  display: grid;
  place-items: center;
  width: 100%;
  height: 1.5rem;
  border-radius: 0.25rem;
  background: #d6e8d0;
  color: #1a1518;
  font-family: var(--police-titre);
  font-size: 0.8125rem;
  letter-spacing: 0.03em;
}

.mini-terminal-touches {
  display: grid;
  grid-template-columns: repeat(3, 0.875rem);
  gap: 0.25rem;
}

.mini-terminal-touches i {
  height: 0.6rem;
  border-radius: 0.15rem;
  background: rgb(255 255 255 / 0.18);
}

/* Sur la page des tarifs, la ligne sous les trois cartes est une phrase, pas un bouton. */
.section-atouts .apercu-suite {
  max-width: 40rem;
  margin-left: auto;
  margin-right: auto;
  font-size: 0.9375rem;
}

/* ═══════════════════════ Bascule clair / sombre ═══════════════════════ */

/*
 * Un bouton rond dans l'en-tête, une lune de jour et un soleil de nuit : le
 * pictogramme dit ce que l'appui FERA, pas ce qu'on voit. Les deux icônes
 * sont superposées et s'échangent en tournant ; laquelle est visible dépend
 * du thème effectif — le système, ou le choix posé sur <html> par theme.js.
 */
.bascule-theme {
  display: grid;
  place-items: center;
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--bord);
  background: var(--fond-2);
  color: var(--texte);
  cursor: pointer;
  transition:
    border-color 0.32s var(--mouvement),
    transform 0.32s var(--mouvement);
}

.bascule-theme:hover {
  border-color: var(--texte-doux);
  transform: translateY(-1px);
}

.bascule-theme:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.bascule-theme svg {
  grid-area: 1 / 1;
  width: 1.125rem;
  height: 1.125rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition:
    opacity 0.32s var(--mouvement),
    transform 0.5s var(--mouvement);
}

.bascule-theme .icone-soleil {
  opacity: 0;
  transform: rotate(60deg) scale(0.6);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='clair']) .bascule-theme .icone-lune {
    opacity: 0;
    transform: rotate(-60deg) scale(0.6);
  }

  :root:not([data-theme='clair']) .bascule-theme .icone-soleil {
    opacity: 1;
    transform: none;
  }
}

:root[data-theme='sombre'] .bascule-theme .icone-lune {
  opacity: 0;
  transform: rotate(-60deg) scale(0.6);
}

:root[data-theme='sombre'] .bascule-theme .icone-soleil {
  opacity: 1;
  transform: none;
}

/* ═══════════════════════════ Tarifs, suite ═══════════════════════════ */

/*
 * LE HÉROS DES TARIFS EST CENTRÉ : il n'a pas de téléphone à sa droite, et
 * un titre calé à gauche sur un écran de vingt-quatre pouces laissait les
 * deux tiers de la ligne vides. Centré, il tient au-dessus de la grille
 * comme un titre d'affiche au-dessus de ses prix.
 */
.heros-tarifs .heros-texte {
  max-width: 44rem;
  margin: 0 auto;
  text-align: center;
}

.heros-tarifs h1 {
  font-size: clamp(2.75rem, 6.5vw, 4.75rem);
}

.heros-tarifs .accroche,
.heros-tarifs .preuves {
  margin-left: auto;
  margin-right: auto;
  justify-content: center;
}

.heros-tarifs .accroche {
  max-width: 36rem;
}

/* La grille : les cartes prennent l'ombre et l'arrondi du reste du site. */
.tarif {
  border-radius: var(--rayon-xl);
  box-shadow: var(--ombre-carte);
}

.offre-titre {
  margin: 0 auto 0.5rem;
  max-width: none;
  text-align: center;
}

.offre-titre h2 {
  font-size: clamp(1.5rem, 3.5vw, 2.125rem);
}

/*
 * LES PACKS. Deux cartes de front, plus larges que celles de l'unité, et
 * l'argument — le rabais — en pastille verte au sommet, là où l'unité met son
 * étiquette. Sous le prix, ce que coûte une fête dans le pack : c'est le
 * chiffre qu'un comité compare à la carte « Fête » deux lignes plus haut.
 */
.tarifs-packs {
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  max-width: 48rem;
  margin-left: auto;
  margin-right: auto;
}

.tarif-pack .rabais {
  order: -1;
  align-self: flex-start;
  margin: 0 0 1rem;
  padding: 0.3rem 0.75rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--succes) 12%, transparent);
  color: var(--succes);
  font-size: 0.8125rem;
  font-weight: 600;
}

.tarif-pack .rabais strong {
  color: inherit;
  font-weight: 700;
}

.par-fete {
  margin: -0.25rem 0 0.75rem;
  font-size: 0.9375rem;
  color: var(--texte-doux);
}

.tarif-pack .reglement {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--bord);
}

/*
 * SUR MESURE n'est pas une carte de plus : pas de prix à comparer, pas de
 * clauses. Un cadre en pointillé, sans fond ni ombre, dit « ici on parle » là
 * où les autres disent « ici on choisit ».
 */
.tarif-large {
  grid-column: 1 / -1;
  border-style: dashed;
  border-color: var(--bord);
  background: transparent;
  box-shadow: none;
  gap: 1.5rem 2.5rem;
}

.tarif-large .repere {
  font-size: 0.9375rem;
}

/* ═══════════════════════════ Inscription ═══════════════════════════ */

/*
 * LE FORMULAIRE À GAUCHE, CE QU'ON OBTIENT À DROITE. La colonne de droite
 * reste sous les yeux en défilant : elle rappelle pourquoi on remplit
 * quinze champs — une adresse d'espace, un code pour les bénévoles, une
 * quittance —, ce qu'un formulaire seul ne dit jamais.
 */
.inscription-grille {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2.5rem;
  align-items: start;
  padding-bottom: clamp(3rem, 6vw, 5rem);
}

@media (min-width: 960px) {
  .inscription-grille {
    grid-template-columns: minmax(0, 1fr) 19rem;
    gap: 3.5rem;
  }

  .inscription-cote {
    position: sticky;
    top: 5.5rem;
  }
}

.inscription-grille .formulaire {
  margin-bottom: 0;
}

/* Les trois temps du formulaire, en une ligne au-dessus : on sait où l'on va. */
.etapes-fil {
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  font-size: 0.9375rem;
  color: var(--texte-doux);
}

.etapes-fil li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.etapes-fil b {
  display: grid;
  place-items: center;
  width: 1.625rem;
  height: 1.625rem;
  border-radius: 50%;
  background: var(--accent-doux);
  color: var(--accent-fort);
  font-family: var(--police-titre);
  font-weight: 400;
  font-size: 0.875rem;
}

.inscription-cote {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.inscription-cote h2 {
  font-size: 1.25rem;
  margin-bottom: 0.25rem;
}

.obtenu {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.25rem 1rem;
  align-items: center;
  padding: 1rem 1.125rem;
  border-radius: 1.125rem;
  background: var(--fond-2);
  border: 1px solid var(--bord);
  box-shadow: var(--ombre-carte);
}

.obtenu h3 {
  font-size: 1rem;
  margin: 0;
}

.obtenu p {
  grid-column: 2;
  margin: 0;
  font-size: 0.875rem;
}

.obtenu-illu {
  grid-row: 1 / span 2;
  display: grid;
  place-items: center;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 0.875rem;
  background: color-mix(in srgb, var(--fond-3) 70%, transparent);
  font-family: var(--police-titre);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--texte);
}

.obtenu-illu .mini-code {
  gap: 0.15rem;
}

.obtenu-illu .mini-code span {
  width: 0.75rem;
  height: 1.125rem;
  font-size: 0.625rem;
  border-radius: 0.2rem;
}

.obtenu-illu .mini-qr {
  width: 1.75rem;
  height: 1.75rem;
}

/*
 * L'ADRESSE NE TIENT PAS DANS UN DISQUE : deux lignes de dix caractères
 * débordaient sur le texte d'à côté. Pour cette carte-là, la vignette devient
 * une pastille aussi large que son contenu, sans jamais couper le nom de
 * domaine — une adresse scindée se recopie de travers.
 */
.obtenu-adresse {
  width: auto;
  min-width: 3.25rem;
  padding: 0 0.75rem;
  color: var(--accent-fort);
  font-size: 0.625rem;
  line-height: 1.3;
  text-align: center;
  text-transform: lowercase;
  white-space: nowrap;
}

/* Les blocs du formulaire prennent l'ombre des cartes du site. */
.bloc {
  border-radius: var(--rayon-xl);
  box-shadow: var(--ombre-carte);
}

/* ═════════════════════════════ Support ═════════════════════════════ */

/* L'adresse, seule sur sa ligne, en grand, jamais coupée. */
.adresse-grande {
  display: inline-block;
  margin: 0.25rem 0 0;
  font-size: clamp(1.25rem, 3.5vw, 1.75rem);
  font-weight: 700;
  color: var(--accent-fort);
  text-decoration: none;
  overflow-wrap: anywhere;
}

.adresse-grande:hover {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* Le message tout prêt : une enveloppe avec ses quatre lignes à remplir. */
.mini-message {
  width: 13rem;
  font-size: 0.6875rem;
}

.mini-message .mini-ligne {
  gap: 0.5rem;
}

.mini-message .mini-ligne i {
  flex: 1;
  height: 1px;
  border-bottom: 1px dashed rgb(26 21 24 / 0.35);
}

/* Trois boutons de courriel tout prêts, alignés sous les cartes. */
.actions-support {
  justify-content: center;
  margin-top: 2rem;
}

/* ═════════════════════════ Bienvenue et données ═════════════════════════ */

/* Les deux grandes cartes de la page d'après : l'espace et la facture. */
.obtenus {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: 1.25rem;
}

.obtenu-grand {
  position: relative;
  margin: 0;
  padding: 1.75rem;
  border-radius: var(--rayon-xl);
  box-shadow: var(--ombre-carte);
}

.obtenu-grand .obtenu-illu {
  margin-bottom: 1rem;
}

.obtenu-grand h2 {
  font-size: 1.375rem;
}

.obtenu-grand p.adresse-espace {
  margin-bottom: 0.75rem;
}

/* Sans rien à afficher, la section ne laisse pas un trou. */
.section-obtenu:not(:has([id]:not([hidden]))) {
  display: none;
}

.avis-page {
  max-width: 46rem;
  margin: 0 auto 2.5rem;
}

.atouts-donnees .atout p + p {
  margin-top: 0.75rem;
}

/* ══════════════════════════ Le code d'inscription ══════════════════════════ */

/* Le bloc du code se distingue des autres : c'est une étape, pas un champ de plus. */
.bloc-code {
  border-color: var(--accent);
  box-shadow:
    0 0 0 1px var(--accent),
    var(--ombre-carte);
}

.champ-code input {
  max-width: 12rem;
  font-family: var(--police-titre);
  font-size: 1.75rem;
  letter-spacing: 0.35em;
  text-align: center;
}

.champ-code input::placeholder {
  letter-spacing: 0.35em;
  opacity: 0.35;
}
