/* ============================================================================
   motion-lectendo.css — Lorenzo, motion design (2026-09-17)
   Couche additive, indépendante de tout autre fichier. Utilise les tokens
   --dur-fast/--dur-base/--dur-slow/--ease s'ils existent déjà sur la page
   (lectendo-v2.css), sinon retombe sur les mêmes valeurs par défaut.
   Respect strict de prefers-reduced-motion. Aucun sélecteur ne dépend d'une
   classe propre à index-lectendo.html : ce fichier "sert" les accroches
   (.reveal, #heroDemo, .lang-ticker, .count, .btn/.card/.nav-link/details).
   ============================================================================ */

/* ---------------------------------------------------------------------------
   0. Fallback tokens (utilisés seulement si non déjà définis par la page)
   ------------------------------------------------------------------------- */
:where(html){
  --lct-dur-fast: var(--dur-fast, 140ms);
  --lct-dur-base: var(--dur-base, 220ms);
  --lct-dur-slow: var(--dur-slow, 420ms);
  --lct-ease: var(--ease, cubic-bezier(.22,.8,.28,1));
}

/* ---------------------------------------------------------------------------
   1. .reveal — apparition au scroll
   Par défaut (pas de JS, JS pas encore prêt, ou reduced-motion) : visible.
   JS ajoute la classe "lct-anim" sur <html> uniquement quand il tourne et que
   le mouvement est autorisé, PUIS observe chaque .reveal pour poser
   .is-visible une seule fois. Voir motion-lectendo.js.
   ------------------------------------------------------------------------- */
.reveal{opacity:1;transform:none}
html.lct-anim .reveal{
  opacity:0;
  transform:translateY(12px);
  transition:opacity var(--lct-dur-slow) var(--lct-ease),
             transform var(--lct-dur-slow) var(--lct-ease);
}
html.lct-anim .reveal.is-visible{opacity:1;transform:none}

/* ---------------------------------------------------------------------------
   2. Démo signature #heroDemo (écoute -> texte source -> document)
   Hauteurs réservées pour zéro layout shift, quel que soit l'état.
   ------------------------------------------------------------------------- */
#heroDemo{position:relative}

/* Onde audio "qui écoute" — reste au repos tant que .is-listening est absent */
#demoWave{display:flex;align-items:center;justify-content:center;gap:4px;height:40px}
#demoWave .lct-bar{
  width:3px;border-radius:2px;background:currentColor;opacity:.5;
  transform:scaleY(.4);transform-origin:50% 50%;
  animation:lctWave 1s var(--lct-ease) infinite;animation-play-state:paused;
}
#demoWave.is-listening .lct-bar{animation-play-state:running;opacity:1}
#demoWave .lct-bar:nth-child(1){height:10px;animation-delay:0ms}
#demoWave .lct-bar:nth-child(2){height:18px;animation-delay:90ms}
#demoWave .lct-bar:nth-child(3){height:26px;animation-delay:180ms}
#demoWave .lct-bar:nth-child(4){height:18px;animation-delay:270ms}
#demoWave .lct-bar:nth-child(5){height:10px;animation-delay:360ms}
@keyframes lctWave{0%,100%{transform:scaleY(.4)}50%{transform:scaleY(1)}}

/* Texte source (darija) qui s'écrit — dir=rtl porté par le balisage hôte */
#demoIn{min-height:5.5em;line-height:1.7;white-space:pre-wrap}
#demoIn[dir="rtl"],#demoIn:lang(ar),#demoIn:lang(ary){direction:rtl;text-align:right}

/* Document généré — lignes révélées une à une + curseur discret */
#demoOut{min-height:9em;line-height:1.7;white-space:pre-wrap}
#demoOut[dir="rtl"],#demoOut:lang(ar),#demoOut:lang(ary){direction:rtl;text-align:right}
#demoOut .lct-line{display:block;min-height:1.7em}
.lct-cursor{
  display:inline-block;width:2px;height:1em;margin-inline-start:2px;vertical-align:-.15em;
  background:currentColor;animation:lctBlink 1.1s var(--lct-ease) infinite;
}
@keyframes lctBlink{0%,100%{opacity:1}50%{opacity:.15}}

/* ---------------------------------------------------------------------------
   3. .lang-ticker — bande de langues en défilement continu
   Structure attendue : .lang-ticker > .lang-ticker-track > (items...)
   Le JS duplique le contenu du track pour boucler ; le doublon est aria-hidden.
   ------------------------------------------------------------------------- */
.lang-ticker{
  overflow:hidden;position:relative;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
}
.lang-ticker-track{display:flex;gap:32px;width:max-content;will-change:transform;
  animation:lctTicker 28s linear infinite}
.lang-ticker:hover .lang-ticker-track,
.lang-ticker:focus-within .lang-ticker-track{animation-play-state:paused}
[dir="rtl"] .lang-ticker-track{animation-name:lctTickerRtl}
@keyframes lctTicker{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@keyframes lctTickerRtl{from{transform:translateX(0)}to{transform:translateX(50%)}}

/* ---------------------------------------------------------------------------
   4. .count[data-to] — compteur qui monte quand visible
   ------------------------------------------------------------------------- */
.count{font-variant-numeric:tabular-nums;display:inline-block}

/* ---------------------------------------------------------------------------
   5. Micro-interactions génériques (opt-in, n'écrasent rien d'existant)
   ------------------------------------------------------------------------- */
.btn{transition:transform var(--lct-dur-fast) var(--lct-ease),
                box-shadow var(--lct-dur-fast) var(--lct-ease),
                filter var(--lct-dur-fast) var(--lct-ease)}
.btn:hover{transform:translateY(-1px)}
.btn:active{transform:translateY(0)}

.card{transition:transform var(--lct-dur-base) var(--lct-ease),
                 box-shadow var(--lct-dur-base) var(--lct-ease),
                 border-color var(--lct-dur-base) var(--lct-ease)}
.card:hover{transform:translateY(-2px);box-shadow:var(--shadow-card,0 18px 40px -28px rgba(20,21,42,.28))}

/* lien de nav : soulignement animé via background-size (pas de layout shift) */
.nav-link{
  position:relative;background-repeat:no-repeat;background-position:0 100%;
  background-size:0% 1px;background-image:linear-gradient(currentColor,currentColor);
  transition:background-size var(--lct-dur-base) var(--lct-ease);
}
.nav-link:hover,.nav-link:focus-visible{background-size:100% 1px}
[dir="rtl"] .nav-link{background-position:100% 100%}

/* FAQ <details> — ouverture douce (grid-template-rows 0fr -> 1fr), posée par JS */
.lct-details-panel{
  display:grid;grid-template-rows:0fr;
  transition:grid-template-rows var(--lct-dur-base) var(--lct-ease);
}
.lct-details-panel > div{overflow:hidden;min-height:0}
details[open] > .lct-details-panel{grid-template-rows:1fr}
details.lct-closing > .lct-details-panel{grid-template-rows:0fr}

/* ---------------------------------------------------------------------------
   6. prefers-reduced-motion — tout devient instantané, rien ne manque
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce){
  *{animation-duration:1ms !important;animation-iteration-count:1 !important;
    transition-duration:1ms !important;scroll-behavior:auto !important}
  html.lct-anim .reveal{opacity:1;transform:none}
  #demoWave .lct-bar{opacity:.85;transform:scaleY(.6)}
  .lct-cursor{opacity:1}
  .lang-ticker-track{animation:none}
  .lang-ticker{overflow-x:auto}
}
