/* Harmonia — page d'accueil marketing.
   Dépend de style.css pour les tokens de couleur et les polices. */

body.home { padding: 0; max-width: none; --nav-h: 4.5rem; }

/* ── En-tête ─────────────────────────────────────────────────────────────── */
/* La barre flotte au-dessus du hero, pas avant lui : sans le retrait négatif
   appliqué plus bas, son texte blanc se posait sur le fond crème et devenait
   illisible tant qu'on n'avait pas défilé. */
.nav {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  min-height: var(--nav-h);
  padding: .75rem clamp(1.25rem, 5vw, 3rem);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background .3s ease, border-color .3s ease;
}
/* Au repos la barre flotte sur le dégradé du hero, en blanc. Dès qu'on défile,
   elle reprend le fond crème et l'encre de la page. */
.nav .mark {
  font-family: 'Quicksand', sans-serif; font-weight: 700;
  font-size: 1.35rem; color: #fff; text-decoration: none;
  transition: color .3s ease;
}
.nav .cta {
  font-family: 'Quicksand', sans-serif; font-weight: 600; font-size: .92rem;
  padding: .5rem 1rem; border-radius: 999px;
  background: rgba(255, 255, 255, .18); color: #fff; text-decoration: none;
  border: 1px solid rgba(255, 255, 255, .55);
  transition: transform .18s ease, background .18s ease, color .18s ease, border-color .18s ease;
}
.nav .cta:hover { background: rgba(255, 255, 255, .3); transform: translateY(-1px); color: #fff; }

.nav.scrolled {
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(140%) blur(14px);
  border-bottom-color: var(--line);
}
.nav.scrolled .mark { color: var(--ink); }
.nav.scrolled .cta {
  background: var(--brand); border-color: transparent; color: #fff;
}
.nav.scrolled .cta:hover { background: var(--brand-deep); }

/* ── Section générique ───────────────────────────────────────────────────── */
html { scroll-snap-type: y proximity; }
@media (prefers-reduced-motion: reduce) { html { scroll-snap-type: none; } }

.section {
  min-height: 100svh;
  display: flex; align-items: center;
  padding: clamp(2.75rem, 8vw, 7.5rem) clamp(1.25rem, 5vw, 3rem);
  scroll-snap-align: start;
}
.inner { max-width: 68rem; margin: 0 auto; width: 100%; }

/* Sous la largeur tablette, `.split` empile texte et capture verticalement :
   le total dépasse souvent un plein écran. Forcer le snap dessus faisait
   résister le défilement pile au moment où il fallait voir la suite, et
   rendait pénible le retour en arrière pour relire le texte coupé. Les
   questions (.q-panel) tiennent toujours sur un seul écran, quel que soit
   l'appareil — elles gardent le comportement, seules les réponses le perdent. */
@media (max-width: 47.99rem) {
  .section { scroll-snap-align: none; }
}

/* Plein écran et rien d'autre : on ne doit pas apercevoir la réponse avant
   d'avoir lu la question. */
.q-panel {
  min-height: 100svh;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(2rem, 8vw, 5rem) clamp(1.5rem, 6vw, 3rem);
  scroll-snap-align: center;
  scroll-snap-stop: always;
}

.eyebrow {
  font-family: 'Quicksand', sans-serif; font-weight: 600;
  font-size: .85rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--brand-deep); margin: 0 0 .3rem;
}
/* Le surtitre et son titre forment une seule unité : la marge haute générique
   des h2 les séparait d'un vide de 2,5 rem. */
.eyebrow + h2 { margin-top: 0; }

.section h2, .plus h2 {
  font-size: clamp(1.6rem, 5.5vw, 2.15rem);
  font-weight: 700; line-height: 1.15;
  margin-bottom: .75rem;
}
.lead { font-size: clamp(1.05rem, 2.2vw, 1.2rem); color: var(--ink-2); max-width: 34rem; }

/* ── Héros ───────────────────────────────────────────────────────────────── */
/* Le dégradé est celui de la célébration Crescendo dans l'app
   (AppGradients.crescendoCelebration : primary400 → primary500 → primary600).
   C'est la signature visuelle la plus reconnaissable d'Harmonia — un aplat
   crème aurait été fidèle aux tokens, mais infidèle à ce que l'utilisateur voit. */
.hero-home {
  /* Le hero remonte sous la barre : le dégradé passe derrière elle, et le
     wordmark blanc de la barre redevient lisible dès le premier pixel. */
  margin-top: calc(-1 * var(--nav-h));
  /* 92svh plutôt que 100 : la marge qui reste garantit que la vague en bas
     (position absolute, calée sur le bord du bloc) reste dans le premier
     écran sur toute la gamme d'appareils, sans dépendre du calcul exact du
     viewport. */
  min-height: 92svh;
  position: relative;
  /* Sans ceci, `flex-direction:column` applique `align-items:stretch` par
     défaut : le bouton (devenu item flex) s'étirait sur toute la largeur du
     hero au lieu de rester à la taille de son contenu. */
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  scroll-snap-align: start;
  padding: calc(var(--nav-h) + clamp(1.5rem, 5vw, 3rem))
           clamp(1.25rem, 5vw, 3rem)
           clamp(2.5rem, 6vw, 4.5rem);
  text-align: center;
  background: linear-gradient(180deg, #E89050 0%, #E07A2F 52%, #D06820 100%);
  color: #fff;
  overflow: hidden;
}
/* La vague qui sépare l'orange du crème est celle de l'écran de personnalisation
   dans l'app (cf. onboarding.webp) : on la reprend ici comme transition entre
   le hero et la première section, plutôt que de couper au cordeau. */
.hero-wave {
  position: absolute; left: 0; right: 0; bottom: -1px;
  width: 100%; height: clamp(36px, 7vw, 64px);
  display: block;
}
.hero-wave path { fill: var(--bg); }
.hero-home .wordmark { font-size: clamp(3rem, 11vw, 5.5rem); margin: 0 0 .35rem; color: #fff; line-height: 1.05; }
/* La baseline est une ligne d'affichage, pas du corps de texte : en pile
   système juste sous un wordmark arrondi, la rupture se voyait. */
.hero-home .baseline {
  font-family: 'Quicksand', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-weight: 500;
  font-size: clamp(1.15rem, 3.6vw, 1.5rem);
  line-height: 1.4;
  max-width: 30rem; margin: 0 auto 1.5rem;
  color: rgba(255, 255, 255, .92);
}

/* Sur un viewport court (mobile en paysage, petit écran), le contenu dépassait
   de quelques pixels le premier écran — assez pour repousser la vague hors
   champ. On resserre encore la colonne quand la hauteur manque, plutôt que de
   deviner une marge universelle qui serait soit trop large, soit encore trop
   juste. */
@media (max-height: 480px) {
  /* padding-bottom doit rester supérieur à la hauteur de la vague (rétrécie
     ci-dessous à 28px) : sinon son pic remonte par-dessus le texte, en étant
     positionnée en absolute elle passe visuellement au-dessus. */
  .hero-home { padding-top: calc(var(--nav-h) + .75rem); padding-bottom: 2.75rem; min-height: auto; }
  .hero-home .wordmark { font-size: clamp(2.2rem, 9vw, 3.5rem); margin-bottom: .2rem; }
  .hero-home .baseline { margin-bottom: .9rem; }
  .meta-release { margin-top: .6rem; }
  .hero-wave { height: 28px; }
}

/* La date de sortie est une promesse, pas une mention légale — elle mérite
   plus de poids que du texte de bas de page. Plus de puce devant : sur un
   fond déjà orange, un point doré de plus n'ajoutait rien, juste du bruit. */
.meta-release {
  margin: 1.1rem 0 0;
  font-family: 'Quicksand', sans-serif; font-weight: 600;
  font-size: clamp(.95rem, 2.4vw, 1.05rem);
  color: #fff;
}
/* ── Appel à l'action ────────────────────────────────────────────────────── */
/* Le bouton mailto ne capturait rien tant que l'utilisateur n'envoyait pas
   lui-même le message. Le formulaire fait la même chose — pas de backend,
   donc pas de vraie liste d'attente serveur — mais pré-remplit l'adresse
   saisie dans le corps du mail, ce qui capture l'intention même si l'envoi
   échoue. Le jour où un vrai backend existe (Mailchimp, Formspree…), seul le
   handler JS `submit` est à remplacer, pas le balisage. */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: 'Quicksand', sans-serif; font-weight: 700; font-size: 1.02rem;
  padding: .9rem 1.7rem; border-radius: 999px; text-decoration: none;
  transition: transform .18s ease, background .18s ease, color .18s ease;
}
.btn:hover { transform: translateY(-1px); }

.btn-light { background: #fff; color: #B85E18; box-shadow: 0 14px 30px -14px rgba(90, 45, 10, .65); }
.btn-light:hover { background: #fff; color: #904810; }

.btn-brand { background: var(--brand); color: #fff; box-shadow: 0 14px 30px -16px rgba(90, 45, 10, .7); }
.btn-brand:hover { background: var(--brand-deep); color: #fff; }

.release-note { margin: 1rem 0 0; font-size: .92rem; color: rgba(255, 255, 255, .82); }

.closing { text-align: center; margin-top: 2.5rem; }
.closing .release-note { color: var(--ink-2); }

/* La pastille « bientôt disponible » a disparu : elle formait un cinquième
   élément centré de plus, et sa date rivalisait avec le bouton. L'information
   vit maintenant dans `.meta-release`, sous l'action. */

/* ── Liste d'attente ─────────────────────────────────────────────────────── */
/* Seul le formulaire de la section offres capture une adresse — le hero se
   contente d'un bouton qui y renvoie (#prevenir). Une seule variante de champ
   suffit donc : sur le fond crème des offres. */
.waitlist {
  display: flex; flex-wrap: wrap; gap: .6rem; justify-content: center;
  width: 100%; max-width: 26rem; margin: 0 auto;
}
.waitlist input[type="email"] {
  flex: 1 1 12rem; min-width: 0;
  font: inherit; font-size: 1rem;
  padding: .85rem 1.15rem; border-radius: 999px; border: 1px solid var(--line);
  background: #fff; color: var(--ink);
}
.waitlist input[type="email"]:focus-visible {
  outline: 2px solid var(--brand); outline-offset: 2px;
}
.waitlist button {
  flex: none;
  font-family: 'Quicksand', sans-serif; font-weight: 700; font-size: 1rem;
  padding: .85rem 1.6rem; border-radius: 999px; border: 0; cursor: pointer;
  background: var(--brand); color: #fff;
  box-shadow: 0 14px 30px -16px rgba(90, 45, 10, .7);
  transition: transform .18s ease, background .18s ease;
}
.waitlist button:hover { background: var(--brand-deep); transform: translateY(-1px); }

/* ── Cadre téléphone ─────────────────────────────────────────────────────── */
.phone {
  position: relative;
  width: min(280px, 72vw);
  border-radius: 38px;
  padding: 9px;
  /* Bezel proche du noir plutôt que bronze : le ton chaud précédent lisait
     comme une carte, pas comme un appareil. Le noir tranche mieux sur le
     crème, à la manière des posts de com. */
  background: linear-gradient(160deg, #2E2419, #120D08);
  box-shadow: 0 28px 60px -22px rgba(20, 14, 8, .55),
              0 2px 6px rgba(20, 14, 8, .3),
              inset 0 0 0 1px rgba(255, 255, 255, .1);
  flex: none;
}
/* L'écran adopte exactement le rapport des captures recadrées (640 × 1345).
   Avec un cadre en 9:19,5, `cover` rognait les bords gauche et droit de chaque
   capture pour combler la différence de hauteur. */
.phone .screen {
  position: relative;
  width: 100%; aspect-ratio: 640 / 1345;
  border-radius: 30px; overflow: hidden;
  background: var(--surface);
}
/* La capture se superpose au cartouche. Si le fichier manque, le `onerror`
   retire l'image et le cartouche réapparaît — déposer les PNG dans screens/
   suffit donc à basculer le site, sans toucher au code. */
/* Les captures sont recadrées à la source (barre d'état et barre de geste
   Android retirées), donc un simple `cover` centré suffit. */
.phone .screen img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 50%;
  display: block;
}
.phone .placeholder {
  position: absolute; inset: 0;
  display: grid; place-items: center; padding: 1.5rem; text-align: center;
  font-family: 'Quicksand', sans-serif; color: var(--ink-2); font-size: .9rem;
  background: linear-gradient(170deg,
              color-mix(in srgb, var(--brand) 14%, var(--surface)), var(--surface));
}
.phone .placeholder small { display: block; margin-top: .4rem; opacity: .7; }

/* ── Alternance texte / visuel ───────────────────────────────────────────── */
.split {
  display: flex; align-items: center; gap: clamp(2.75rem, 6vw, 5rem);
  flex-wrap: wrap; justify-content: center;
}
.split .copy { flex: 1 1 20rem; max-width: 30rem; }
.split.reverse { flex-direction: row-reverse; }

.section.alt { background: var(--surface); }

/* La promesse « comprendre plutôt que mémoriser » ne vit plus dans un bloc
   dédié : elle affleure une fois par section, dans la dernière phrase de chaque
   paragraphe. Un manifeste se lit et s'oublie ; une idée répétée s'installe. */

/* ── Offres ──────────────────────────────────────────────────────────────── */
/* Deux cartes plutôt qu'un pavé à puces : la frontière gratuit/payant est une
   information que le visiteur cherche, autant la montrer plutôt que la décrire. */
.offers { display: grid; gap: 1rem; margin-top: 2rem; }
@media (min-width: 46rem) {
  .offers { grid-template-columns: 1fr 1.1fr; align-items: stretch; }
}

.offer {
  border-radius: 26px;
  padding: clamp(1.6rem, 4vw, 2.4rem);
  display: flex; flex-direction: column;
}
.offer h3 {
  font-family: 'Quicksand', sans-serif; font-weight: 700;
  font-size: 1.35rem; margin: 0 0 .2rem;
}
.offer .tag {
  font-family: 'Quicksand', sans-serif; font-weight: 600;
  font-size: .78rem; letter-spacing: .07em; text-transform: uppercase;
  margin: 0 0 .9rem;
}
.offer ul { list-style: none; padding: 0; margin: .4rem 0 0; display: grid; gap: .8rem; }
.offer li { display: flex; gap: .7rem; align-items: flex-start; line-height: 1.5; }
.offer li::before {
  content: "✓"; flex: none; font-weight: 700; line-height: 1.5;
}

.offer.free {
  background: var(--bg);
  border: 1px solid var(--line);
  color: var(--ink);
}
.offer.free .tag { color: var(--ink-2); }
.offer.free li::before { color: var(--green); }

/* Ambre profond de AppGradients.masteryHero (primary600 → primary800) : la même
   carte que celle qui clôt une session de maîtrise dans l'app. */
.offer.pro {
  position: relative;
  /* Dégage la place du médaillon "pas encore disponible" au-dessus du titre :
     sans ce surcroît, il chevauchait "Harmonia Plus" sur les cartes étroites. */
  padding-top: clamp(2.9rem, 7vw, 3.6rem);
  background: linear-gradient(150deg, #D06820, #904810);
  color: #fff;
  box-shadow: 0 18px 40px -18px rgba(90, 45, 10, .55);
}
.offer.pro .tag { color: #FCD24A; }
.offer.pro li { color: rgba(255, 255, 255, .94); }
.offer.pro li::before { color: #FCD24A; }

/* Deux des trois lignes de la carte sont encore en chantier (chips
   individuelles) — ce médaillon dit la même chose au niveau de l'offre
   entière, sur un ton d'annonce plutôt que de restriction : l'abonnement
   arrive après l'app gratuite, pas avec elle. */
.offer.pro .not-yet {
  position: absolute; top: 1.1rem; right: 1.1rem;
  display: inline-flex; align-items: center; gap: .4rem;
  background: rgba(20, 12, 4, .28);
  border: 1px solid rgba(255, 255, 255, .3);
  border-radius: 999px;
  padding: .35rem .75rem .35rem .6rem;
  font-family: 'Quicksand', sans-serif; font-weight: 600;
  font-size: .68rem; letter-spacing: .04em; text-transform: uppercase;
  color: #FFEFB6;
}
.offer.pro .not-yet svg { width: 13px; height: 13px; flex: none; }

/* Puce de statut — sur une puce gratuite déjà solide, une feature encore en
   chantier doit se voir sans casser la promesse du reste de la liste. Deux
   variantes : sur le fond crème des sections, et sur le fond sombre de la
   carte Plus. */
.li-body { display: flex; flex-direction: column; align-items: flex-start; gap: .4rem; }

.chip {
  display: inline-flex; align-items: center; gap: .4rem;
  font-family: 'Quicksand', sans-serif; font-weight: 600;
  font-size: .68rem; letter-spacing: .05em; text-transform: uppercase;
  padding: .25rem .65rem; border-radius: 999px; white-space: nowrap;
}
.chip::before {
  content: ""; width: 6px; height: 6px; border-radius: 999px;
  background: currentColor; opacity: .7; flex: none;
}
.chip-soft { background: var(--surface); border: 1px solid var(--line); color: var(--ink-2); }
.chip-on-dark { background: rgba(255, 255, 255, .16); border: 1px solid rgba(255, 255, 255, .3); color: #fff; }

/* Chip autonome à la suite d'un .lead (hors liste à puces) : le flux inline
   le collait directement sous la dernière ligne de texte. */
.lead + .chip { margin-top: .9rem; }

/* ── Citation d'ouverture ────────────────────────────────────────────────── */
/* Elle coiffe la section entière, au-dessus de la rangée texte + écran : on
   pose d'abord la question — « tiens, c'est moi » — et la réponse arrive
   ensuite d'un bloc. Placée dans la colonne de texte, elle n'était plus qu'un
   surtitre parmi d'autres. */
.quote-hook {
  position: relative;
  max-width: 34rem;
  margin: 0 auto;
  padding-top: clamp(2rem, 5vw, 2.75rem);
  text-align: center;
  font-family: 'Quicksand', sans-serif; font-weight: 500;
  font-size: clamp(1.55rem, 6vw, 2.5rem); line-height: 1.3;
  color: var(--ink);
}
/* Un filet à gauche est un dispositif d'alignement à gauche : centré, il ne
   voulait plus rien dire. Ce trait court sert de point d'appui au centrage et
   marque l'ouverture de la section. */
.quote-hook::before {
  content: ""; position: absolute; top: 0; left: 50%;
  transform: translateX(-50%);
  width: 34px; height: 2px; border-radius: 2px;
  background: var(--brand);
}

/* Le titre ouvre désormais sa colonne : la marge haute générique des h2 y
   creusait un vide. */
.copy > h2:first-child { margin-top: 0; }

/* ── Révélation au défilement ────────────────────────────────────────────── */
.offer { transition: transform .2s ease, box-shadow .2s ease; }
.offer:hover { transform: translateY(-3px); }

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

.reveal { opacity: 0; transform: translateY(18px); transition: opacity .7s ease, transform .7s ease; }
.reveal.in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

footer.site {
  padding: 2.5rem clamp(1.25rem, 5vw, 3rem) 4rem;
  border-top: 1px solid var(--line);
  margin-top: 0;
}
