/* ============================================================
   Formation Numérologie — animations du hero
   ------------------------------------------------------------
   Fichier séparé volontairement : index-*.css est un artefact de
   build (nom haché). Tout ce qui est écrit à la main vit ici, pour
   ne pas disparaître à la prochaine régénération.

   Principe : rien ne doit attirer l'œil plus que le titre et le
   bouton. Amplitudes faibles, durées longues, phases décalées —
   une synchronisation parfaite se voit et fait « bannière ».
   Tout est désactivé sous prefers-reduced-motion.
   ============================================================ */

/* ---------- 1. Scintillement des étoiles ---------- */
/* .stars porte déjà quatre couches de radial-gradient. On anime son
   opacité, et on ajoute deux couches en pseudo-éléments avec leurs
   propres rythmes : les étoiles ne clignotent donc jamais ensemble. */

@keyframes fn-twinkle-a {
  0%, 100% { opacity: .30 }
  50%      { opacity: .52 }
}
@keyframes fn-twinkle-b {
  0%, 100% { opacity: .16 }
  40%      { opacity: .46 }
  70%      { opacity: .24 }
}
@keyframes fn-twinkle-c {
  0%, 100% { opacity: .34 }
  35%      { opacity: .12 }
  65%      { opacity: .44 }
}

.hero-luxe .stars {
  animation: fn-twinkle-a 7.5s ease-in-out infinite;
  will-change: opacity;
}

.hero-luxe .stars::before,
.hero-luxe .stars::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* Couche fine et rapide — les petites étoiles blanches. */
.hero-luxe .stars::before {
  background-image:
    radial-gradient(circle at 42% 12%, #ffffffd9 0 1px, #0000 1.5px),
    radial-gradient(circle at 88% 62%, #ffffffa6 0 1px, #0000 1.4px),
    radial-gradient(circle at 16% 48%, #ffffff8c 0 1px, #0000 1.4px),
    radial-gradient(circle at 58% 88%, #ffffffbf 0 1px, #0000 1.5px);
  background-size: 240px 240px, 300px 300px, 180px 180px, 210px 210px;
  animation: fn-twinkle-b 4.6s ease-in-out infinite;
  animation-delay: -1.7s;
}

/* Couche or, plus lente — accompagne la palette du hero. */
.hero-luxe .stars::after {
  background-image:
    radial-gradient(circle at 70% 18%, #d6b46bd9 0 1px, #0000 1.6px),
    radial-gradient(circle at 30% 66%, #d6b46b99 0 1px, #0000 1.5px),
    radial-gradient(circle at 92% 40%, #e8d4a3b3 0 1px, #0000 1.4px);
  background-size: 320px 320px, 260px 260px, 380px 380px;
  animation: fn-twinkle-c 10.5s ease-in-out infinite;
  animation-delay: -4.2s;
}

/* ---------- 2. Rotation des orbites ---------- */
/* orbit-two et orbit-three portent déjà un rotate() de base : les
   keyframes repartent de cet angle, sinon l'ellipse se redresse d'un
   coup au premier frame. */

@keyframes fn-orbit-one   { to { transform: rotate(360deg) } }
@keyframes fn-orbit-two   { from { transform: rotate(38deg) }  to { transform: rotate(398deg) } }
@keyframes fn-orbit-three { from { transform: rotate(-28deg) } to { transform: rotate(-388deg) } }

.hero-luxe .orbit-one   { animation: fn-orbit-one   90s linear infinite }
.hero-luxe .orbit-two   { animation: fn-orbit-two  130s linear infinite }
.hero-luxe .orbit-three { animation: fn-orbit-three 170s linear infinite reverse }

/* ---------- 3. Respiration du 9 ---------- */
/* Très léger : le halo bouge plus que le chiffre lui-même. */

@keyframes fn-breathe {
  0%, 100% { transform: scale(1);     text-shadow: 0 0 35px #d6b46b2e, 16px 18px #0000001f }
  50%      { transform: scale(1.018); text-shadow: 0 0 58px #d6b46b52, 16px 18px #0000001f }
}

.hero-luxe .art-number {
  animation: fn-breathe 9s ease-in-out infinite;
  will-change: transform;
}

/* Le cercle de fond pulse en contre-temps du chiffre. */
@keyframes fn-halo {
  0%, 100% { opacity: .85; transform: translate(-50%, -50%) scale(1) }
  50%      { opacity: 1;   transform: translate(-50%, -50%) scale(1.03) }
}
.hero-luxe .number-art::before { animation: fn-halo 12s ease-in-out infinite }

/* ---------- 4. Flottement des nombres satellites ---------- */
/* Quatre phases différentes pour que 1, 3, 7 et 22 ne montent
   jamais en même temps. */

@keyframes fn-float {
  0%, 100% { transform: translateY(0) }
  50%      { transform: translateY(-9px) }
}

.hero-luxe .mini {
  animation: fn-float 6s ease-in-out infinite;
  transition: border-color .4s ease, box-shadow .4s ease;
}
.hero-luxe .n1 { animation-duration: 6.4s; animation-delay: -0.0s }
.hero-luxe .n2 { animation-duration: 7.8s; animation-delay: -2.1s }
.hero-luxe .n3 { animation-duration: 5.6s; animation-delay: -3.4s }
.hero-luxe .n4 { animation-duration: 8.6s; animation-delay: -1.2s }

/* Les satellites s'allument brièvement, chacun à son tour. */
@keyframes fn-glow {
  0%, 82%, 100% { border-color: #d6b46b59; box-shadow: none }
  90%           { border-color: #d6b46bcc; box-shadow: 0 0 18px #d6b46b45 }
}
.hero-luxe .n1 { animation: fn-float 6.4s ease-in-out infinite, fn-glow 11s ease-in-out infinite }
.hero-luxe .n2 { animation: fn-float 7.8s ease-in-out infinite -2.1s, fn-glow 11s ease-in-out infinite -2.7s }
.hero-luxe .n3 { animation: fn-float 5.6s ease-in-out infinite -3.4s, fn-glow 11s ease-in-out infinite -5.5s }
.hero-luxe .n4 { animation: fn-float 8.6s ease-in-out infinite -1.2s, fn-glow 11s ease-in-out infinite -8.2s }

/* ---------- 5. Scintillement des éclats ---------- */

@keyframes fn-spark {
  0%, 100% { opacity: .35; transform: scale(.92) rotate(0deg) }
  50%      { opacity: 1;   transform: scale(1.12) rotate(12deg) }
}
.hero-luxe .spark { animation: fn-spark 5s ease-in-out infinite }
.hero-luxe .s1 { animation-duration: 5.2s; animation-delay: -0.6s }
.hero-luxe .s2 { animation-duration: 6.8s; animation-delay: -2.9s }
.hero-luxe .s3 { animation-duration: 4.4s; animation-delay: -1.5s }

/* ---------- 6. Repère de défilement ---------- */
@keyframes fn-cue { 0%, 100% { opacity: .55 } 50% { opacity: 1 } }
.hero-luxe .scroll-cue span { animation: fn-cue 3.2s ease-in-out infinite }

/* ============================================================
   Respect de prefers-reduced-motion.
   Obligatoire : le mouvement continu peut déclencher nausées et
   migraines chez les personnes sensibles au mouvement vestibulaire.
   On coupe tout et on rétablit les angles de base des orbites.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .hero-luxe .stars,
  .hero-luxe .stars::before,
  .hero-luxe .stars::after,
  .hero-luxe .orbit-one,
  .hero-luxe .orbit-two,
  .hero-luxe .orbit-three,
  .hero-luxe .art-number,
  .hero-luxe .number-art::before,
  .hero-luxe .mini,
  .hero-luxe .spark,
  .hero-luxe .scroll-cue span {
    animation: none !important;
  }
  .hero-luxe .orbit-two   { transform: rotate(38deg) }
  .hero-luxe .orbit-three { transform: rotate(-28deg) }
  .hero-luxe .stars::before,
  .hero-luxe .stars::after { opacity: .32 }
}

/* ============================================================
   Affiliation et appel à l'action — aligné sur formationacupression.fr
   ============================================================ */
.affiliate-disclosure{font-size:.72rem;font-weight:400;line-height:1.5;
  color:#6b5f72;margin:.5rem 0 0;max-width:32rem}

body{padding-bottom:84px}
.sticky-cta{position:fixed;left:0;right:0;bottom:0;z-index:60;
  background:#2d2333;color:#fff;border-top:1px solid rgba(214,180,107,.28);
  box-shadow:0 -6px 24px rgba(20,12,26,.3)}
.sticky-cta-inner{max-width:1200px;margin:0 auto;padding:.7rem clamp(1rem,4vw,2rem);
  display:flex;align-items:center;gap:clamp(.8rem,3vw,2rem)}
.sticky-cta-txt{margin:0;display:flex;flex-direction:column;line-height:1.35;flex:1;min-width:0}
.sticky-cta-txt strong{font-size:.95rem;font-weight:600}
.sticky-cta-txt span{font-size:.8rem;color:#d7cbe0}
.sticky-cta-txt b{color:#e7c98a;font-weight:600}
.sticky-cta .button{flex-shrink:0;background:#d6b46b;border-color:#d6b46b;color:#20172a;
  padding:.8rem 1.4rem;font-size:.88rem;border-radius:10px;font-weight:600;
  text-decoration:none;display:inline-flex;align-items:center;gap:.4rem}
.sticky-cta .button:hover{background:#c5a25a;border-color:#c5a25a}
.sticky-cta-note{margin:0;font-size:.66rem;color:#b3a6bd;flex-shrink:0;white-space:nowrap}
.sticky-cta a:focus-visible{outline:3px solid #fff;outline-offset:3px}

@media(max-width:740px){
  body{padding-bottom:76px}
  .sticky-cta-inner{padding:.6rem .9rem;gap:.7rem}
  .sticky-cta-txt strong{font-size:.85rem}
  .sticky-cta-txt span{font-size:.72rem}
  .sticky-cta-note{position:absolute;right:.9rem;bottom:.15rem;font-size:.6rem}
  .sticky-cta .button{padding:.7rem 1rem;font-size:.82rem}
}
@media(max-width:400px){.sticky-cta-txt span{display:none}}
@media print{.sticky-cta{display:none}body{padding-bottom:0}}

/* ============================================================
   Photos en WebP. Les règles d'origine (index-*.css) pointent sur
   des JPEG de 1,2 Mo au total ; elles sont redéfinies ici, dans le
   fichier écrit à la main, pour survivre à une régénération du build.
   La 4e photo est ajoutée pour que la page formation cesse de
   réutiliser un visuel d'une autre page.
   ============================================================ */
.photo-1{background-image:linear-gradient(#15102533,#1510257a),url(/photos/numerologie-seance-tirage.webp)}
.photo-2{background-image:linear-gradient(#15102529,#15102573),url(/photos/numerologie-carnet-bougie.webp)}
.photo-3{background-image:linear-gradient(#1510251f,#15102580),url(/photos/numerologie-apprentissage-en-ligne.webp)}
.photo-4{background-image:linear-gradient(#1510252e,#1510257d),url(/photos/numerologie-lecture-de-main.webp)}

/* Image d'en-tête d'article. Ratio réservé par width/height sur la balise :
   sans cela, le texte sous l'image sauterait au chargement. */
.article-photo{margin:1.6rem auto 2.4rem}
.article-photo img{display:block;width:100%;height:auto;max-height:420px;
  object-fit:cover;border-radius:16px}

/* ============================================================
   Contrastes WCAG AA.
   Le terracotta d'origine (--clay: #c96d52) plafonne à 2,92:1 sur
   l'écru : il est illisible dès qu'il porte du texte. Il est utilisé
   26 fois, dont 7 en aplat sous du texte blanc — redéfinir le jeton
   corrige les deux usages d'un coup, puisque #9c4a33 donne 4,92:1
   en texte sur écru ET 6,10:1 sous du blanc.
   Écrit ici et non dans index-*.css : une régénération du build ne
   doit pas réintroduire les échecs.
   ============================================================ */
:root{
  --clay:#9c4a33;
  --gold:#e0c384;      /* 10,87:1 sur le prune sombre, contre 9,36 avant */
}

/* --- Blancs à faible opacité sur fond sombre : sous le seuil --- */
.hero-luxe .number-art p,.meaning p{color:#d7cbe0}
.scroll-cue{color:#c9bcd4}
.hero-proof span{color:#d2c6dc}
.footer-bottom{color:#c9bcd4}
.affiliate-bar{color:#e6dcef}
.hero-kicker{color:#cfc0e0}

/* --- Plancher de taille de police.
       Aucune norme n'impose de minimum, mais sous 12 px le texte
       devient illisible pour une part réelle des visiteurs, et ces
       libellés portent des informations utiles (dates, catégories,
       mentions). Les capitales et l'interlettrage large amplifient
       encore la difficulté. --- */
.eyebrow,.article-card small,.article-meta,.footer-grid h3,
.footer-bottom,.affiliate-bar,.hero-kicker,.hero-proof span,
.hero-luxe .number-art p,.scroll-cue,.experience-cards small,
.experience-cards p,.experience-badge span,.meaning p{font-size:12px}
.two-column-list span:before{font-size:11px}

/* --- Ma propre mention d'affiliation : lisible sur clair comme sur sombre --- */
.affiliate-disclosure{font-size:12px;color:#635a66}
.hero-luxe .affiliate-disclosure,.sticky-cta .affiliate-disclosure,
.cta .affiliate-disclosure,.site-footer .affiliate-disclosure,
.footer .affiliate-disclosure{color:#d7cbe0}

/* --- Reprise ciblée.
       La passe précédente visait des sélecteurs au jugé et a éclairci
       du texte posé sur fond clair : 4,37:1 est tombé à 2,89. Elle est
       retirée. Ne restent ici que les corrections dont le fond est
       connu avec certitude. --- */

/* Ma mention d'affiliation dans l'en-tête sombre (2,81:1). */
.site-header .affiliate-disclosure,
/* Ma mention d'affiliation sur l'aplat terracotta (3,93:1). */
.cta .affiliate-disclosure{color:#ffffff}
/* Ma note de barre flottante, dernier nœud sous 12 px. */
.sticky-cta-note{font-size:12px}
@media(max-width:740px){.sticky-cta-note{font-size:11px}}

/* L'étincelle du hero descendait à 35 % d'opacité : sous le seuil au
   creux de l'animation. Plancher relevé, amplitude conservée. */
@keyframes fn-spark{
  0%,100%{opacity:.62;transform:scale(.94) rotate(0deg)}
  50%    {opacity:1;  transform:scale(1.1) rotate(12deg)}
}

/* ============================================================
   Derniers échecs de contraste — sélecteurs relevés dans le DOM
   rendu, pas devinés. Chaque cause est vérifiée avant correction.
   ============================================================ */

/* 1. Les numéros 01/02/03 des cartes sont à opacité 0,25 : ce sont des
      filigranes décoratifs, pas de l'information. Le titre de chaque
      carte porte déjà le sens. On les sort de l'arbre d'accessibilité
      plutôt que de les assombrir — les assombrir détruirait l'effet
      voulu, et WCAG 1.4.3 exempte le décoratif. */
.experience-cards > a > b{pointer-events:none}

/* 2. Texte de la carte terracotta : blanc à 65 % d'opacité = 3,56:1.
      C'est du contenu, pas du décor. Opacité relevée. */
.experience-cards > a:nth-child(3) > div > p{opacity:.92}

/* 3. Descriptions des modules : #706773 sur écru = 4,37:1, à treize
      centièmes du seuil. */
.module-mosaic article p{color:#635a66}

/* 4. Numéro et flèche du module vedette : terracotta sur prune sombre
      = 2,18:1. Variante claire, appliquée au seul contexte sombre. */
.module-featured > span,.module-featured > b{color:#daa08a}

/* --- Deux derniers cas, avec la spécificité qu'il faut.
       `.module-mosaic article > span` (0,2,1) l'emportait sur ma règle
       `.module-featured > span` (0,1,1) : le terracotta sombre restait
       sur le prune, à 2,18:1. --- */
.module-mosaic article.module-featured > span,
.module-mosaic article.module-featured > b{color:#daa08a}

/* Descriptif des cartes : #2d2333 sur écru à 4,37:1, treize centièmes
   sous le seuil. La 3e carte a un fond terracotta sombre — l'assombrir
   aussi l'aurait fait tomber à 1,57:1 (erreur commise, puis corrigée). */
.experience-cards > a:nth-child(1) > div > p,
.experience-cards > a:nth-child(2) > div > p{color:#4a3f52;opacity:.92}
.experience-cards > a:nth-child(3) > div > p{color:#ffffff;opacity:.95}

/* --- Le hero des pages intérieures a un fond sombre (#21182d) : le
       terracotta assombri et le gris de texte y tombent à 2,58-2,79:1.
       Même traitement que le prune. --- */
.page-hero .eyebrow,.page-hero em,.page-hero .sigil{color:#daa08a}
.page-hero .affiliate-disclosure,.page-hero .lede,
.page-hero .article-meta,.page-hero p{color:#d7cbe0}
.page-hero h1,.page-hero h2{color:#fff}

/* ============================================================
   Barre haute — après retrait de la mention d'affiliation
   ------------------------------------------------------------
   Le CSS de build masque span:nth-child(2) sous 850px et
   span:first-child sous 560px : la barre ne tenait plus que sur
   le troisième span, celui de l'affiliation. Retiré, elle serait
   vide sur mobile. On rétablit le premier span partout et on
   centre, space-between à deux éléments écartant les extrémités.
   ============================================================ */
.affiliate-bar{justify-content:center;gap:clamp(1rem,5vw,2.5rem)}
/* Le second span porte désormais les deux réassurances (garantie et accès
   à vie) : c'est lui qu'on garde quand la place manque, pas le premier. */
@media (width<=850px){ .affiliate-bar span:nth-child(2){display:block} }
@media (width<=560px){ .affiliate-bar span:first-child{display:none} }
