/* ============================================================
   « Cahier Vivant » — motion design de IA Aïcha (v11)
   Le cahier prend vie : les lettres du sujet s'envolent pour s'écrire,
   le stylo écrit au rythme réel de la génération, les mises en page se distribuent comme des cartes.
   Uniquement transform / opacity / stroke-dashoffset : fluide même sur téléphone d'entrée de gamme.
   ============================================================ */

/* ---------- 1. Chargement : la scène du stylo ---------- */
#loading.mv-on .stack{display:none}
#loading.mv-on .loading-wrap{max-width:460px;padding-top:0}

.mv-sheet{
  position:relative;width:min(100%,420px);height:330px;margin:0 0 18px;
  background-color:#fff;
  background-image:
    linear-gradient(90deg,transparent 29px,rgba(226,72,61,.55) 29px 31px,transparent 31px),
    repeating-linear-gradient(0deg,transparent 0 25px,#C9D6F3 25px 26px);
  background-position:0 0,0 -1px;
  border:1px solid var(--rule);border-radius:2px 2px 12px 12px;
  box-shadow:0 22px 40px -24px rgba(20,33,61,.5), 0 2px 0 #fff inset;
  transform-origin:50% 100%;
  animation:mvSheetIn .7s cubic-bezier(.2,.9,.25,1.1) backwards;
  overflow:hidden;
}
/* reliure à spirale */
.mv-sheet::before{
  content:"";position:absolute;left:0;top:0;right:0;height:12px;
  background:radial-gradient(circle at 12px 6px,#14213D 0 3px,transparent 3.5px) 0 0/24px 12px repeat-x;
  opacity:.85;
}
@keyframes mvSheetIn{from{opacity:0;transform:translateY(24px) rotate(-3deg) scale(.94)}to{opacity:1;transform:none}}

.mv-title{
  position:absolute;left:44px;right:18px;top:30px;
  font:700 22px/1.25 "Bricolage Grotesque","Atkinson Hyperlegible",sans-serif;letter-spacing:-.015em;color:#14213D;
  word-break:break-word;min-height:55px;
}
.mv-ch{display:inline-block;opacity:0;white-space:pre}
.mv-ch.in{opacity:1}
.mv-ch.in.pop{animation:mvPop .35s cubic-bezier(.3,1.6,.5,1)}
@keyframes mvPop{0%{transform:translateY(-4px) scale(1.25)}100%{transform:none}}
.mv-fly{
  position:fixed;left:0;top:0;z-index:90;pointer-events:none;will-change:transform;
  font:700 22px/1.25 "Bricolage Grotesque","Atkinson Hyperlegible",sans-serif;color:#E2483D;white-space:pre;
}
.mv-ink{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}
.mv-ink path{fill:none;stroke-linecap:round;stroke-linejoin:round}
.mv-ink .u{stroke:#E2483D;stroke-width:3}
.mv-ink .n{stroke:#1F3FA8;stroke-width:1.7;opacity:.92}
.mv-ink .d{stroke:#14213D;stroke-width:1.9}
.mv-ink .sun{stroke:#E2483D;stroke-width:2.2}
.mv-nib{filter:drop-shadow(2px 5px 3px rgba(20,33,61,.28));transition:opacity .4s}
.mv-nib.off{opacity:0}

/* ---------- 2. Cartes de mise en page : distribuées, inclinables, avec reflet ---------- */
body .page-card,
body .page-card:nth-child(odd),
body .page-card:nth-child(even),
body .page-card:hover,
body .page-card.selected{
  transform:perspective(800px)
    rotate(var(--r,0deg))
    rotateX(calc(var(--rx,0deg) + var(--dev-rx,0deg)))
    rotateY(calc(var(--ry,0deg) + var(--dev-ry,0deg)))
    translateY(var(--ty,0px));
  transform-style:preserve-3d;
  transition:transform .22s cubic-bezier(.2,.8,.2,1),box-shadow .22s ease;
}
body .page-card:nth-child(odd){--r:-1.1deg}
body .page-card:nth-child(even){--r:1.1deg}
body .page-card:hover{--r:0deg;--ty:-5px}
body .page-card.selected{--r:0deg;--ty:-7px}
body .page-card.tilting{transition:transform .06s linear,box-shadow .22s ease}
.page-card::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;opacity:0;
  background:radial-gradient(circle at var(--gx,50%) var(--gy,50%),rgba(255,255,255,.55),rgba(255,255,255,0) 55%);
  mix-blend-mode:soft-light;transition:opacity .25s;
}
.page-card:hover::after,.page-card.tilting::after{opacity:1}
.page-card.selected::before{
  content:"";position:absolute;right:12px;top:-9px;width:26px;height:26px;border-radius:50%;
  background:#E2483D;box-shadow:0 3px 0 #9E2A22;
  animation:mvStamp .5s cubic-bezier(.3,1.7,.5,1);
}
.page-card.selected::before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 26 26'%3E%3Cpath d='M7 13.5l4 4 8-9' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}
@keyframes mvStamp{from{transform:scale(2.4) rotate(-30deg);opacity:0}to{transform:none;opacity:1}}

/* ---------- 3. La leçon apparaît comme une page qu'on dépose ---------- */
#courseView.mv-reveal{transform-origin:50% 0;animation:mvPage .95s cubic-bezier(.2,.8,.2,1) backwards}
@keyframes mvPage{
  from{clip-path:inset(0 0 100% 0 round 4px);transform:perspective(1100px) rotateX(-7deg) translateY(36px)}
  to{clip-path:inset(0 0 0 0 round 4px);transform:none}
}
#courseView.mv-reveal>*{animation:mvRise .75s cubic-bezier(.2,.8,.2,1) backwards;animation-delay:calc(var(--k,0)*75ms + 280ms)}
@keyframes mvRise{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}

/* ---------- 4. État vide : la page d'exemple s'écrit toute seule ---------- */
#emptyState .mock-page{
  position:relative;overflow:hidden;
  transform:perspective(900px) rotateX(var(--ex,0deg)) rotateY(var(--ey,0deg));
  transition:transform .25s cubic-bezier(.2,.8,.2,1);
}
#emptyState .mock-page.tilting{transition:transform .06s linear}
#emptyState .mock-page>div:nth-child(1){--i:0}#emptyState .mock-page>div:nth-child(2){--i:1}
#emptyState .mock-page>div:nth-child(3){--i:2}#emptyState .mock-page>div:nth-child(4){--i:3}
#emptyState .mock-page>div:nth-child(5){--i:4}#emptyState .mock-page>div:nth-child(6){--i:5}
#emptyState .mock-page>div:nth-child(7){--i:6}
#emptyState .mock-title,#emptyState .mock-line{
  transform-origin:left center;
  animation:mvWrite 9s cubic-bezier(.4,0,.2,1) infinite;
  animation-delay:calc(var(--i)*.55s);
}
@keyframes mvWrite{
  0%{transform:scaleX(0);background:#2F52C9;opacity:1}
  9%{transform:scaleX(1);background:#2F52C9}
  26%{background:var(--rule-soft)}
  88%{transform:scaleX(1);opacity:1}
  96%{transform:scaleX(1);opacity:0}
  100%{transform:scaleX(0);opacity:0}
}
#emptyState .mock-image{animation:mvDevelop 9s ease-in-out infinite;animation-delay:2.4s}
@keyframes mvDevelop{
  0%{filter:blur(10px) saturate(0);opacity:.35}
  22%{filter:blur(0) saturate(1);opacity:1}
  90%{filter:blur(0);opacity:1}
  100%{filter:blur(10px);opacity:.35}
}
#emptyState .mock-page::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 40%,rgba(255,255,255,.75) 50%,transparent 60%);
  transform:translateX(-120%);animation:mvSheen 6.5s ease-in-out 1.2s infinite;
}
@keyframes mvSheen{0%,55%{transform:translateX(-120%)}100%{transform:translateX(120%)}}

/* ---------- 5. Bouton « Générer » : éclaboussure d'encre ---------- */
.btn-generate{position:relative;overflow:hidden}
.mv-splat{
  position:absolute;border-radius:50%;pointer-events:none;background:#14213D;opacity:.55;
  width:20px;height:20px;margin:-10px 0 0 -10px;
  animation:mvSplat .7s cubic-bezier(.2,.8,.3,1) forwards;
}
@keyframes mvSplat{to{transform:scale(18);opacity:0}}

/* ---------- accessibilité & impression ---------- */
@media(prefers-reduced-motion:reduce){
  .mv-sheet,#courseView.mv-reveal,#courseView.mv-reveal>*,
  #emptyState .mock-title,#emptyState .mock-line,#emptyState .mock-image,#emptyState .mock-page::after,
  .page-card.selected::before,.mv-ch.in.pop{animation:none!important}
  body .page-card{transition:none}
}
@media print{
  .mv-sheet,.mv-fly,.mv-splat{display:none!important}
  #courseView.mv-reveal,#courseView.mv-reveal>*{animation:none!important}
}

/* correctif : la colonne principale ne doit pas élargir la page (défilement horizontal à ~1100 px) */
.canvas{min-width:0}

/* ============================================================
   « Cahier Vivant » v12 — couche 2 : ouverture du cahier, sélecteur à ressort,
   stylo du professeur, tampon de fin, copeaux de crayon, grille vivante
   ============================================================ */

/* ---------- A. Ouverture du cahier (une fois par session) ---------- */
html.mv-splash-pending body{visibility:hidden;animation:mvFailsafe 0s 3s forwards}
@keyframes mvFailsafe{to{visibility:visible}}
.mv-splash{
  position:fixed;inset:0;z-index:300;visibility:visible;display:grid;place-items:center;cursor:pointer;
  background:radial-gradient(circle at 50% 38%,#26407f 0,#14213D 55%,#0C1428 100%);
  perspective:1300px;overflow:hidden;
}
.mv-splash.out{animation:mvSplashOut .7s cubic-bezier(.6,0,.3,1) forwards;pointer-events:none}
@keyframes mvSplashOut{to{opacity:0;transform:scale(1.35);filter:blur(6px)}}
.mv-splash::before{ /* quadrillage qui défile doucement */
  content:"";position:absolute;inset:-40px;opacity:.12;
  background:repeating-linear-gradient(0deg,transparent 0 31px,#fff 31px 32px),repeating-linear-gradient(90deg,transparent 0 31px,#fff 31px 32px);
  animation:mvGridDrift 6s linear infinite;
}
@keyframes mvGridDrift{to{transform:translate(32px,32px)}}
.mv-book{
  position:relative;width:210px;height:280px;transform-style:preserve-3d;
  animation:mvBookIn 2.1s cubic-bezier(.3,.7,.2,1) forwards;
  filter:drop-shadow(0 40px 38px rgba(0,0,0,.55));
}
@keyframes mvBookIn{
  0%{opacity:0;transform:translateY(60px) rotateY(-32deg) rotateX(14deg) scale(.7)}
  26%{opacity:1;transform:translate(0,0) rotateY(-26deg) rotateX(9deg) scale(1)}
  55%{transform:translate(calc(var(--open-x)*.35),0) rotateY(-8deg) rotateX(2deg) scale(calc(var(--open-s)*.95))}
  82%,100%{opacity:1;transform:translate(var(--open-x),0) rotateY(0deg) rotateX(0deg) scale(var(--open-s))}
}
.mv-book{--open-x:117px;--open-s:1.12}
@media(max-width:520px){.mv-book{--open-x:84px;--open-s:.8}}
.mv-inside{
  position:absolute;inset:0;background:#fff;border-radius:2px 8px 8px 2px;padding:46px 20px 0 38px;
  background-image:linear-gradient(90deg,transparent 29px,rgba(226,72,61,.6) 29px 31px,transparent 31px),repeating-linear-gradient(0deg,transparent 0 25px,#C9D6F3 25px 26px);
  background-position:0 0,0 6px;
}
.mv-inside b{
  display:inline-block;font:700 23px/1.2 "Bricolage Grotesque",sans-serif;color:#E2483D;transform:rotate(-3deg);
  clip-path:inset(0 100% 0 0);animation:mvWriteOn .9s 2.55s cubic-bezier(.5,0,.2,1) forwards;
}
@keyframes mvWriteOn{to{clip-path:inset(0 0 0 0)}}
.mv-cover{
  position:absolute;inset:0;transform-origin:left center;transform-style:preserve-3d;
  animation:mvOpen 1.15s .55s cubic-bezier(.65,0,.25,1) forwards;
}
@keyframes mvOpen{from{transform:rotateY(0)}to{transform:rotateY(-172deg)}}
.mv-cover>div{position:absolute;inset:0;backface-visibility:hidden;border-radius:2px 8px 8px 2px}
.mv-front{
  background:linear-gradient(135deg,#2A4DC4,#1F3FA8 55%,#172F80);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;color:#fff;text-align:center;
  box-shadow:inset 6px 0 0 rgba(0,0,0,.25),inset 0 0 0 2px rgba(255,255,255,.12);
}
.mv-front img{width:76px;height:76px;border-radius:6px;background:#fff;padding:3px;box-shadow:0 0 0 3px #E2483D}
.mv-front strong{font:700 19px/1.1 "Bricolage Grotesque",sans-serif;padding:0 16px}
.mv-front small{font-size:12px;opacity:.8}
.mv-front::after{content:"";position:absolute;right:26px;top:0;bottom:0;width:9px;background:#E2483D;box-shadow:0 0 6px rgba(0,0,0,.35)}
.mv-back{background:#EEF2FB;transform:rotateY(180deg);box-shadow:inset -6px 0 0 rgba(0,0,0,.08)}
.mv-skip{position:absolute;bottom:22px;left:0;right:0;text-align:center;color:#fff;opacity:.4;font-size:12px;letter-spacing:.06em}
/* bouton Commencer : arrive après l'ouverture du livre, puis attend le toucher */
.mv-splash{flex-direction:column}
.mv-go{
  position:absolute;left:50%;bottom:clamp(54px,11vh,96px);transform:translateX(-50%);
  display:inline-flex;align-items:center;gap:12px;border:0;cursor:pointer;
  background:#E2483D;color:#fff;font:700 19px/1 "Bricolage Grotesque","Atkinson Hyperlegible",sans-serif;letter-spacing:.01em;
  padding:17px 30px 18px;border-radius:6px;box-shadow:0 5px 0 #9E2A22,0 18px 34px -10px rgba(226,72,61,.65);
  opacity:0;animation:mvGoIn .7s 3.1s cubic-bezier(.2,.9,.3,1.25) forwards;
}
.mv-go i{font-style:normal;display:inline-block;animation:mvGoArrow 1.1s 3.8s ease-in-out infinite}
.mv-go::before{ /* onde qui pulse pour attirer le pouce */
  content:"";position:absolute;inset:0;border-radius:inherit;border:3px solid #E2483D;opacity:0;
  animation:mvGoPulse 1.8s 3.9s ease-out infinite;
}
.mv-go:active{transform:translateX(-50%) translateY(4px);box-shadow:0 1px 0 #9E2A22}
.mv-go:focus-visible{outline:3px solid #fff;outline-offset:4px}
@keyframes mvGoIn{from{opacity:0;transform:translateX(-50%) translateY(24px) scale(.85)}to{opacity:1;transform:translateX(-50%)}}
@keyframes mvGoArrow{0%,100%{transform:translateX(0)}50%{transform:translateX(6px)}}
@keyframes mvGoPulse{0%{opacity:.8;transform:scale(1)}100%{opacity:0;transform:scale(1.35,1.9)}}

/* ---------- B. Sélecteur de mode : pastille à ressort + titre qui s'écrit ---------- */
.mode-switch{position:relative}
.mode-switch button{position:relative;z-index:1;transition:color .25s}
.mode-switch button.active{background:transparent}
.mv-pill{
  position:absolute;top:4px;bottom:4px;left:0;width:0;z-index:0;border-radius:8px;
  background:var(--ochre-bright);box-shadow:0 3px 0 #9E2A22;
  transition:transform .55s cubic-bezier(.3,1.55,.5,1),width .55s cubic-bezier(.3,1.55,.5,1);
}
.mv-pill.nt{transition:none}
.mv-writeon{animation:mvTitleOn .7s cubic-bezier(.5,0,.2,1) backwards}
@keyframes mvTitleOn{from{clip-path:inset(0 100% 0 0);transform:translateX(-4px)}to{clip-path:inset(0 0 0 0);transform:none}}

/* ---------- C. Le stylo du professeur souligne les titres quand on arrive dessus ---------- */
.mv-ul{position:relative;width:fit-content;max-width:100%}
.mv-ul::after{
  content:"";position:absolute;left:0;right:0;bottom:-5px;height:7px;pointer-events:none;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='7' viewBox='0 0 14 7'%3E%3Cpath d='M0 4Q3.5 0 7 4T14 4' fill='none' stroke='%23E2483D' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E") repeat-x 0 0/14px 7px;
  clip-path:inset(0 100% 0 0);transition:clip-path .9s cubic-bezier(.5,0,.2,1) .1s;
}
.mv-ul.on::after{clip-path:inset(0 0 0 0)}
.mv-ul.inst::after{transition:none}
/* les images « se développent » comme une photo */
.mv-dev{filter:blur(12px) grayscale(1) contrast(1.2);opacity:.35;transform:scale(1.04);transition:filter 1.3s ease,opacity 1s ease,transform 1.3s cubic-bezier(.2,.8,.2,1)}
.mv-dev.on{filter:none;opacity:1;transform:none}
.mv-dev.inst{transition:none}

/* ---------- D. Tampon de fin + copeaux de crayon ---------- */
.mv-stamp{
  position:fixed;right:clamp(14px,6vw,90px);top:178px;z-index:70;pointer-events:none;
  font:700 26px/1 "Bricolage Grotesque",sans-serif;color:#E2483D;letter-spacing:.02em;
  border:4px double #E2483D;border-radius:10px;padding:10px 18px 11px;background:rgba(255,255,255,.88);
  transform:rotate(-9deg);animation:mvStampIn 2.9s cubic-bezier(.2,.9,.3,1) forwards;
  text-shadow:0 0 1px rgba(226,72,61,.5);
}
.mv-stamp small{display:block;font:600 11px/1.4 "Atkinson Hyperlegible",sans-serif;letter-spacing:.14em;text-transform:uppercase;margin-top:4px;opacity:.85}
@keyframes mvStampIn{
  0%{opacity:0;transform:rotate(-24deg) scale(3.2)}
  12%{opacity:1;transform:rotate(-9deg) scale(.94)}
  18%{transform:rotate(-9deg) scale(1.03)}
  24%{transform:rotate(-9deg) scale(1)}
  82%{opacity:1;transform:rotate(-9deg) scale(1)}
  100%{opacity:0;transform:rotate(-9deg) translateY(-14px) scale(1)}
}
.mv-shave{position:fixed;z-index:69;pointer-events:none;width:14px;height:5px;border-radius:5px 1px 5px 1px;will-change:transform}

/* ---------- E. Changement de couverture : l'encre se répand ---------- */
/* (animation WAAPI dans motion2.js) */

/* ---------- F. Grille vivante + bouton son ---------- */
.canvas{
  background-position:var(--bx1,0px) 0, 0 var(--by,0px), var(--bx,0px) 0;
  transition:background-position .25s ease-out;
}
#soundBtn{margin-left:8px;cursor:pointer}
#soundBtn[aria-pressed="true"]{background:var(--paper-soft);border-color:var(--ochre)}
@media(max-width:520px){#soundBtn{margin-left:0}}

@media(prefers-reduced-motion:reduce){
  .mv-pill{transition:none}
  .mv-writeon,.mv-stamp{animation:none}
  .mv-go,.mv-go i,.mv-go::before{animation:none}
  .mv-go{opacity:1}
  .mv-ul::after,.mv-dev{transition:none}
  .mv-dev{filter:none;opacity:1;transform:none}
}
@media print{
  .mv-splash,.mv-stamp,.mv-shave{display:none!important}
  .mv-ul::after{display:none}
  .mv-dev{filter:none!important;opacity:1!important;transform:none!important}
}


/* ============ v14 : le livre devient un vrai objet ============ */
.mv-book{filter:drop-shadow(0 34px 30px rgba(0,0,0,.5)) drop-shadow(0 6px 8px rgba(0,0,0,.35))}
/* épaisseur : tranche de feuilles visible sous la page de droite */
.mv-inside{
  box-shadow:1px 1px 0 #fff,2px 2px 0 #D5DEF2,3px 3px 0 #fff,4px 4px 0 #C8D4EE,5px 5px 0 #F4F7FD,6px 6px 0 #B9C8E8,7px 7px 0 #E7EDFA,8px 8px 0 #AFC0E4;
  border-radius:2px 7px 7px 2px;
}
.mv-inside::after{ /* pli central, ombre portée de la reliure */
  content:"";position:absolute;left:0;top:0;bottom:0;width:26px;pointer-events:none;
  background:linear-gradient(90deg,rgba(20,33,61,.22),rgba(20,33,61,.06) 60%,transparent);
}
.mv-inside b{font-size:21px;line-height:1.15;padding-top:2px}
.mv-inside b .g2{display:block;margin:0;font-size:19px;color:#1F3FA8;transform:rotate(1.5deg)}
.mv-inside b .g2:empty{display:none}
.mv-inside b{white-space:normal;max-width:150px}
/* couverture : papier grainé, étiquette, reflet */
.mv-front{
  gap:0;justify-content:space-between;padding:26px 0 26px;
  background:
    linear-gradient(115deg,rgba(255,255,255,.16) 0,rgba(255,255,255,0) 38%,rgba(0,0,0,.1) 100%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 .55 0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E"),
    linear-gradient(135deg,#2A4DC4,#1F3FA8 55%,#172F80);
  background-blend-mode:normal,soft-light,normal;
}
.mv-front::after{right:22px;width:7px}
.mv-kick{font:700 10.5px/1 "Atkinson Hyperlegible",sans-serif;letter-spacing:.28em;opacity:.85;padding-left:.28em}
.mv-label{
  background:#fff;color:#14213D;width:150px;padding:14px 8px 12px;border-radius:3px;display:flex;flex-direction:column;align-items:center;gap:6px;
  box-shadow:0 0 0 3px #fff,0 0 0 4.5px #E2483D,0 8px 14px -6px rgba(0,0,0,.5);transform:rotate(-1deg);
}
.mv-label img{width:46px;height:46px;border-radius:5px;background:none;padding:0;box-shadow:none}
.mv-label strong{font:700 15px/1.1 "Bricolage Grotesque",sans-serif;padding:0}
.mv-label small{font-size:10.5px;opacity:.7;color:#14213D}
.mv-rule{width:90px;height:3px;background:rgba(255,255,255,.55);border-radius:2px;margin:0 auto}
/* intérieur de la couverture : page de garde « Ce cahier appartient à » */
.mv-back{
  background:repeating-linear-gradient(135deg,#E8EEFB 0 10px,#EEF2FB 10px 20px);
  display:flex;align-items:center;justify-content:center;
  box-shadow:inset -8px 0 14px -8px rgba(20,33,61,.25);
}
.mv-own{
  background:#fff;width:150px;padding:14px 10px 12px;text-align:center;border-radius:3px;
  box-shadow:0 0 0 2px #1F3FA8,0 8px 14px -8px rgba(20,33,61,.5);
}
.mv-own small{display:block;font:700 9.5px/1.2 "Atkinson Hyperlegible",sans-serif;letter-spacing:.14em;text-transform:uppercase;color:#6A7799}
.mv-own em{
  display:block;margin-top:9px;font:600 italic 20px/1.1 "Bricolage Grotesque",sans-serif;color:#1F3FA8;transform:rotate(-2deg);
  word-break:break-word;clip-path:inset(0 100% 0 0);animation:mvWriteOn .8s 2.7s cubic-bezier(.5,0,.2,1) forwards;
}
.mv-own i{display:block;height:1.5px;margin-top:6px;background:#9FB0DA}
@media(prefers-reduced-motion:reduce){.mv-own em{animation:none;clip-path:none}}

/* nom calligraphique lisible : couverture + page « Bienvenue » */
.mv-label strong.calli{font:700 34px/1 "Dancing Script",cursive;letter-spacing:0;padding:2px 0;white-space:nowrap;color:#1F3FA8}
.mv-inside b .g1{font-size:21px}
.mv-inside b .g2{font-family:"Dancing Script","Bricolage Grotesque",cursive;font-weight:700;font-size:35px;line-height:1.1;white-space:nowrap;color:#1F3FA8;margin-top:2px}
.mv-own .o3{display:block;margin-top:10px;font:700 10px/1.3 "Atkinson Hyperlegible",sans-serif;letter-spacing:.06em;color:#E2483D}

/* illustration d'accueil : élèves avec cahiers et figures géométriques */
.mv-hero{
  position:absolute;left:50%;top:clamp(10px,2.5vh,28px);bottom:calc(50% + 134px);transform:translateX(-50%);
  max-width:min(92vw,400px);width:auto;height:auto;max-height:calc(50% - 134px);object-fit:contain;pointer-events:none;
  filter:drop-shadow(0 10px 18px rgba(0,0,0,.35));animation:mvHeroIn .9s .25s cubic-bezier(.2,.8,.3,1) both;
}
@media(min-width:521px){.mv-hero{bottom:calc(50% + 172px);max-height:calc(50% - 172px)}}
@keyframes mvHeroIn{from{opacity:0;transform:translate(-50%,-18px) scale(.94)}to{opacity:1;transform:translate(-50%,0) scale(1)}}
.mv-inside b{max-width:152px}
.mv-inside b .g1{font-size:20px;white-space:nowrap}

/* ---------- pages qui se feuillettent ---------- */
.mv-inside{transform:translateZ(-8px)}
.mv-leaf{
  position:absolute;inset:0;transform-origin:left center;transform-style:preserve-3d;
  --z0:calc(-1px - var(--i)*.6px);--z1:calc(3px + var(--i)*.6px);
  transform:translateZ(var(--z0)) rotateY(0deg);
  animation:mvFlip .72s calc(1.35s + var(--i)*.17s) cubic-bezier(.5,.05,.3,1) both;
}
@keyframes mvFlip{
  0%{transform:translateZ(var(--z0)) rotateY(0deg);opacity:1}
  35%{transform:translateZ(var(--z0)) rotateY(-62deg) skewY(-2.5deg)}
  70%{opacity:1}
  100%{transform:translateZ(var(--z1)) rotateY(-172deg);opacity:0}
}
.mv-leaf>div{
  position:absolute;inset:0;backface-visibility:hidden;border-radius:2px 7px 7px 2px;background-color:#fff;
  background-image:linear-gradient(90deg,transparent 29px,rgba(226,72,61,.6) 29px 31px,transparent 31px),repeating-linear-gradient(0deg,transparent 0 25px,#C9D6F3 25px 26px);
  background-position:0 0,0 6px;
}
.mv-leaf>.lb{transform:rotateY(180deg)}
.mv-leaf>div::after{ /* ombre qui passe sur la page pendant qu'elle tourne */
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:linear-gradient(90deg,rgba(20,33,61,.38),rgba(20,33,61,0) 70%);opacity:0;
  animation:mvShade .72s calc(1.35s + var(--i)*.17s) both;
}
@keyframes mvShade{0%,100%{opacity:0}40%{opacity:1}}

/* ================= « 4D » : vraie profondeur 3D + inclinaison + poussière ================= */
/* Le filtre d'ombre aplatissait la 3D du livre : il passe sur une scène englobante,
   ce qui rend les pages et la couverture réellement en volume. */
.mv-stage{
  display:grid;place-items:center;perspective:1300px;
  filter:drop-shadow(0 34px 30px rgba(0,0,0,.5)) drop-shadow(0 6px 8px rgba(0,0,0,.35));
  rotate:var(--ax,0) var(--ay,1) 0 var(--ang,0deg);
  translate:calc(var(--px,0)*7px) calc(var(--py,0)*5px);
}
.mv-book{filter:none}
.mv-hero{
  translate:calc(var(--px,0)*-12px) calc(var(--py,0)*-7px);
  filter:drop-shadow(calc(var(--px,0)*-7px) 12px 18px rgba(0,0,0,.38));
}
.mv-splash::before{background-position:calc(var(--px,0)*-14px) calc(var(--py,0)*-14px)}
.mv-shine{
  position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:radial-gradient(circle at calc(50% + var(--px,0)*46%) calc(34% + var(--py,0)*36%),rgba(255,255,255,.34),rgba(255,255,255,0) 58%);
}
.mv-dust{
  position:absolute;left:var(--x);top:var(--y);width:var(--sz);height:var(--sz);pointer-events:none;opacity:0;
  background:var(--c);filter:blur(calc(var(--d)*.35px));
  translate:calc(var(--px,0)*var(--d)*-26px) calc(var(--py,0)*var(--d)*-18px);
  animation:mvDust var(--dur) var(--dl) linear infinite;
}
.mv-dust.s0{border-radius:50%}
.mv-dust.s1{border-radius:2px}
.mv-dust.s2{clip-path:polygon(50% 0,100% 100%,0 100%)}
.mv-dust.s3{border-radius:50%;box-shadow:0 0 8px var(--c)}
@keyframes mvDust{
  0%{opacity:0;transform:translateY(24px) rotate(0)}
  18%{opacity:.75}
  82%{opacity:.75}
  100%{opacity:0;transform:translateY(-130px) rotate(220deg)}
}

/* ============================================================
   « Cahier Vivant » v14 — chorégraphie professionnelle
   Principes : un seul langage de mouvement (jetons ci-dessous), de la continuité
   entre les écrans (un élément devient le suivant), des sorties aussi soignées
   que les entrées, du retour tactile sur chaque contrôle, et de la retenue.
   ============================================================ */
:root{
  --ease-out:cubic-bezier(.16,1,.3,1);          /* arrivées : rapide puis se pose */
  --ease-in-out:cubic-bezier(.65,0,.35,1);      /* déplacements d'un point à un autre */
  --ease-spring:cubic-bezier(.34,1.56,.64,1);   /* petit rebond (sélecteurs, tampons) */
  --d1:120ms; --d2:200ms; --d3:320ms; --d4:480ms; --d5:720ms;
}

/* ---------- Retour tactile cohérent sur tous les contrôles ---------- */
.btn-pdf,.btn-ghost,.btn-save,.xb,.etool button{
  transition:transform var(--d2) var(--ease-out),background-color var(--d2),border-color var(--d2),box-shadow var(--d2),color var(--d2);
}
@media(hover:hover){
  .btn-pdf:hover,.btn-ghost:hover{transform:translateY(-1px)}
  .btn-pdf:hover{box-shadow:0 8px 16px -10px rgba(20,33,61,.6)}
}
.btn-pdf:active,.btn-ghost:active,.btn-save:active,.xb:active,.etool button:active{transform:scale(.97);transition-duration:var(--d1)}
.field input,.field textarea,.field select{transition:border-color var(--d2),box-shadow var(--d3) var(--ease-out),background-color var(--d2)}
.field label{transition:color var(--d2)}
.field:focus-within>label{color:#fff}
.switch input{transition:transform var(--d2) var(--ease-spring)}
.switch input:active{transform:scale(.85)}
.upload-zone{transition:border-color var(--d2),background-color var(--d2),transform var(--d2) var(--ease-out)}
.upload-zone:active{transform:scale(.985)}

/* ---------- Barre de progression : vivante, jamais figée ---------- */
.progress-fill{position:relative;overflow:hidden;transition:width .9s var(--ease-out)}
.progress-fill::after{
  content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.5),transparent);
  animation:mvShim 1.5s var(--ease-in-out) infinite;
}
@keyframes mvShim{to{transform:translateX(100%)}}

/* ---------- Fenêtres : elles entrent avec élégance ---------- */
.hist:not(.hidden){animation:mvFade var(--d3) var(--ease-out)}
.hist:not(.hidden) .hist-card{animation:mvSheetUp var(--d5) var(--ease-out)}
@keyframes mvFade{from{opacity:0}to{opacity:1}}
@keyframes mvSheetUp{from{transform:translateY(40px) scale(.985);opacity:.6}to{transform:none;opacity:1}}
.pr:not(.hidden){animation:mvPr var(--d4) var(--ease-out)}
@keyframes mvPr{from{opacity:0;transform:scale(1.02)}to{opacity:1;transform:none}}
.pr-slide{animation-duration:var(--d3);animation-timing-function:var(--ease-out)}

/* ---------- Entrée en cascade des résultats ---------- */
#results:not(.hidden) .results-head{animation:mvRise var(--d5) var(--ease-out) .08s backwards}
#results:not(.hidden) .notice-bar:not(.hidden){animation:mvRise var(--d5) var(--ease-out) .5s backwards}

/* ---------- Barre d'outils : ombre quand elle se colle + progression de lecture ---------- */
.lesson-toolbar{transition:box-shadow var(--d3) var(--ease-out)}
.lesson-toolbar.mv-stuck{box-shadow:0 10px 18px -14px rgba(20,33,61,.55)}
.mv-read{
  position:fixed;left:0;top:0;right:0;height:3px;z-index:60;pointer-events:none;
  background:#E2483D;transform:scaleX(0);transform-origin:left;opacity:0;
  transition:opacity var(--d3);
}
.mv-read.on{opacity:1}

@media(prefers-reduced-motion:reduce){
  .progress-fill::after,.hist:not(.hidden),.hist:not(.hidden) .hist-card,.pr:not(.hidden),
  #results:not(.hidden) .results-head,#results:not(.hidden) .notice-bar{animation:none}
  .btn-pdf,.btn-ghost,.btn-save{transition:none}
}
@media print{.mv-read{display:none}}

/* ---------- photo d'accueil en 3D (remplace l'illustration des deux élèves) ----------
   Elle suit le même mouvement (--px / --py) que le livre : inclinaison en perspective, ombre qui bouge, léger décalage. */
.mv-hero{
  box-sizing:border-box;border-radius:18px;border:3px solid rgba(255,255,255,.92);background:#fff;
  transform:perspective(900px) translateX(-50%) rotateY(calc(var(--px,0)*-9deg)) rotateX(calc(var(--py,0)*6deg));
  filter:none;
  box-shadow:calc(var(--px,0)*-12px) 18px 38px rgba(0,0,0,.5),0 0 0 1px rgba(0,0,0,.18);
  animation:mvHeroIn3d .9s .25s cubic-bezier(.2,.8,.3,1) both;
}
@keyframes mvHeroIn3d{from{opacity:0;scale:.9}to{opacity:1;scale:1}}
