:root{
  --ground:#EFECE6; --surface:#F9F7F3; --sunk:#E6E2DA; --line:rgba(23,20,28,.14); --line-soft:rgba(23,20,28,.075);
  --ink:#17141C; --ink-2:#4C4657; --ink-3:#7E7788;
  --acc:#4B2E86; --acc-deep:#3A2168; --acc-2:#6A46BE; --acc-soft:rgba(75,46,134,.10); --acc-glow:rgba(75,46,134,.28);
  --on-acc:#FCFBF9;
  --ok:#4B2E86; --bad:#9C3D24; --bad-soft:#F3E3DD;
  --warn-ink:#7E5410; --warn-bg:rgba(150,104,18,.10); --warn-line:rgba(150,104,18,.28);
  --key-w:#FCFBF9; --key-w-edge:rgba(23,20,28,.22); --key-b:#1D1926;
  --shadow-s:0 1px 2px rgba(23,20,28,.05),0 8px 22px -14px rgba(23,20,28,.35);
  --shadow-btn:0 1px 2px rgba(23,20,28,.12),0 10px 20px -12px rgba(75,46,134,.65);
  --r:14px;
}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --ground:#131017; --surface:#1B1723; --sunk:#0F0D14; --line:rgba(241,238,246,.16); --line-soft:rgba(241,238,246,.08);
    --ink:#F1EEF6; --ink-2:#B9B2C6; --ink-3:#8A8399;
    --acc:#A78CF5; --acc-deep:#C3AEFF; --acc-2:#C3AEFF; --acc-soft:rgba(167,140,245,.16); --acc-glow:rgba(167,140,245,.4);
    --on-acc:#120F18;
    --ok:#A78CF5; --bad:#E08A6A; --bad-soft:#33201A;
  --warn-ink:#E0B473; --warn-bg:rgba(224,180,115,.12); --warn-line:rgba(224,180,115,.30);
    --warn-ink:#E0B473; --warn-bg:rgba(224,180,115,.12); --warn-line:rgba(224,180,115,.30);
    --key-w:#DCD7E4; --key-w-edge:rgba(13,11,17,.55); --key-b:#0B0910;
    --shadow-s:0 1px 2px rgba(0,0,0,.45),0 10px 26px -16px rgba(0,0,0,.9);
    --shadow-btn:0 1px 2px rgba(0,0,0,.5),0 12px 24px -14px rgba(167,140,245,.5);
  }
}
:root[data-theme="dark"]{
  --ground:#131017; --surface:#1B1723; --sunk:#0F0D14; --line:rgba(241,238,246,.16); --line-soft:rgba(241,238,246,.08);
  --ink:#F1EEF6; --ink-2:#B9B2C6; --ink-3:#8A8399;
  --acc:#A78CF5; --acc-deep:#C3AEFF; --acc-2:#C3AEFF; --acc-soft:rgba(167,140,245,.16); --acc-glow:rgba(167,140,245,.4);
  --on-acc:#120F18;
  --ok:#A78CF5; --bad:#E08A6A; --bad-soft:#33201A;
  --key-w:#DCD7E4; --key-w-edge:rgba(13,11,17,.55); --key-b:#0B0910;
  --shadow-s:0 1px 2px rgba(0,0,0,.45),0 10px 26px -16px rgba(0,0,0,.9);
  --shadow-btn:0 1px 2px rgba(0,0,0,.5),0 12px 24px -14px rgba(167,140,245,.5);
}
*{box-sizing:border-box}
html,body{margin:0}
body{
  background:var(--ground); color:var(--ink);
  font-family:Archivo,"Helvetica Neue",Arial,sans-serif; font-size:16px; line-height:1.55;
  padding:0 1.15rem 4rem; -webkit-font-smoothing:antialiased;
}
::selection{background:var(--acc-soft)}
.mono{font-family:"IBM Plex Mono",ui-monospace,monospace;font-variant-numeric:tabular-nums}
.sans{font-family:Archivo,"Helvetica Neue",sans-serif}
.lab{font-family:"IBM Plex Mono",monospace;font-size:.63rem;font-weight:500;letter-spacing:.2em;text-transform:uppercase;color:var(--ink-3);margin:0}
.wrap{max-width:1160px;margin:0 auto}
:focus-visible{outline:2px solid var(--acc);outline-offset:3px;border-radius:6px}

/* ---------- header ---------- */
header{display:flex;flex-wrap:wrap;align-items:center;gap:1rem 2.2rem;padding:.75rem 0 1rem;border-bottom:1px solid var(--line-soft)}
.brandline{display:flex;align-items:center;gap:.7rem}
.brand-mark{display:flex;gap:2px;align-items:flex-end;height:26px}
.brand-mark i{display:block;width:4px;height:26px;background:var(--ink);border-radius:0 0 1px 1px}
.brand-mark i:nth-child(2),.brand-mark i:nth-child(4){height:15px;background:var(--acc)}
h1{font-family:"Bodoni Moda",Didot,"Times New Roman",serif;font-size:1.85rem;font-weight:400;letter-spacing:-.015em;margin:0;line-height:1}
h1 span{color:var(--acc);font-style:italic}
.tag{font-size:.78rem;color:var(--ink-3);margin:.28rem 0 0;letter-spacing:.01em}
.meter-box{flex:1 1 340px;min-width:250px;display:flex;flex-direction:column;gap:.42rem}
.meter-top{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;font-size:.76rem}
.meter-top b{font-family:"IBM Plex Mono",monospace;font-size:.95rem;font-weight:500;color:var(--acc);font-variant-numeric:tabular-nums}
.meter{position:relative;height:10px;background:var(--sunk);border-radius:100px;overflow:hidden;border:1px solid var(--line-soft)}
.meter .ceil{position:absolute;inset:0 auto 0 0;background:var(--acc-soft)}
.meter .tgt{position:absolute;inset:0 auto 0 0;background:linear-gradient(90deg,var(--acc),var(--acc-2));border-radius:100px;transition:width .5s cubic-bezier(.2,.7,.3,1)}
.meter .mark{position:absolute;top:-3px;bottom:-3px;width:2px;background:var(--ink);opacity:.5;transition:left .5s cubic-bezier(.2,.7,.3,1)}
.meter-sub{display:flex;justify-content:space-between;font-size:.7rem;color:var(--ink-3)}

/* ---------- layout ---------- */
main{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:1.4rem;padding-top:1.15rem;align-items:start}
main>*{min-width:0}
@media (max-width:900px){main{grid-template-columns:minmax(0,1fr)}}
.card{background:var(--surface);border:1px solid var(--line-soft);border-radius:var(--r);padding:1.25rem 1.35rem;box-shadow:var(--shadow-s)}
.stack{display:flex;flex-direction:column;gap:1.1rem}

/* ---------- stage ---------- */
.card.stage{background-image:radial-gradient(120% 62% at 50% -28%,var(--acc-soft),transparent 60%)}
.now{display:flex;flex-wrap:wrap;gap:.15rem .8rem;align-items:baseline;padding-bottom:.85rem;margin-bottom:.95rem;border-bottom:1px solid var(--line-soft)}
.now-title{font-family:"Bodoni Moda",Didot,serif;font-weight:400;font-size:1.5rem;letter-spacing:-.01em;line-height:1.15;text-wrap:balance}
.now-src{font-size:.75rem;color:var(--ink-3);font-family:"IBM Plex Mono",monospace}
.stage-head{display:flex;flex-wrap:wrap;gap:.5rem 1.9rem;align-items:baseline;margin-bottom:1rem}
.stage-head .k{font-family:"IBM Plex Mono",monospace;font-size:.62rem;color:var(--ink-3);text-transform:uppercase;letter-spacing:.18em}
.stage-head .v{font-family:"IBM Plex Mono",monospace;font-size:1.05rem;font-weight:500;font-variant-numeric:tabular-nums;margin-top:.15rem}
/* ---------- le record ----------
   Une pastille discrète tant que la phrase en cours ne vaut pas plus que le
   record, qui s'allume dès qu'elle le vaut : c'est ce moment-là qui donne envie
   d'aller la chercher proprement. */
/* petit tableau de score : ton record d'un cote, ce que vaut la phrase posee
   devant toi de l'autre. Meme typographie que la ligne de stats juste a gauche,
   pour que ce soit lu comme la suite naturelle et non comme un ornement. */
.rec{position:relative;margin-left:auto;align-self:center;display:flex;align-items:center;gap:.85rem;
  padding:.42rem .9rem;border-radius:var(--r);border:1px solid var(--line);
  background:var(--sunk);font-family:"IBM Plex Mono",monospace;line-height:1;
  transition:background .3s ease,border-color .3s ease,box-shadow .3s ease,transform .2s ease}
.rec[hidden]{display:none}
.rec .rc{display:flex;flex-direction:column;gap:.28rem}
.rec .rk{font-size:.58rem;text-transform:uppercase;letter-spacing:.17em;color:var(--ink-3);
  transition:color .3s ease}
.rec .rv{font-size:1.05rem;font-weight:500;font-variant-numeric:tabular-nums;color:var(--ink-2);
  transition:color .3s ease,font-weight .3s ease}
.rec .rsep{width:1px;align-self:stretch;background:var(--line);transition:background .3s ease}
/* au repos : la phrase en cours est indiquee, sans insister */
.rec .rnow .rv{color:var(--ink-2)}
/* elle vaut plus que le record : c'est la qu'on attire l'oeil */
.rec.hot{background:var(--acc-soft);border-color:var(--acc);
  animation:recpulse 2.6s ease-in-out infinite}
.rec.hot .rsep{background:var(--acc-glow)}
.rec.hot .rnow .rk{color:var(--acc)}
.rec.hot .rnow .rv{color:var(--acc);font-weight:600}
@keyframes recpulse{
  0%,100%{box-shadow:0 0 0 0 var(--acc-soft)}
  50%{box-shadow:0 0 0 7px var(--acc-soft)}}
/* ---------- le record battu ----------
   UN COMPTEUR QUI MONTE. Le record ne saute pas d'une valeur a l'autre : il
   grimpe, vite d'abord puis de plus en plus lentement, et vient mourir sur le
   nouveau chiffre. C'est le ralenti de fin qui fait qu'on le regarde jusqu'au
   bout, et c'est la seule chose que les deux essais precedents n'avaient pas :
   un chiffre qui se deplace, on le voit arriver et c'est fini ; un chiffre qui
   monte, on attend de voir ou il s'arrete.
   Pendant la montee le nombre est gonfle et allume, la boite envoie un anneau
   qui s'ouvre et se dissout, et a l'atterrissage le chiffre depasse sa taille
   une fraction de seconde avant de se ranger. */
.rec.win{border-color:var(--acc);background:var(--acc-soft);
  animation:recring 1.1s cubic-bezier(.2,.8,.3,1)}
.rec.win .rsep{background:var(--acc)}
.rec.win .rbest .rk{color:var(--acc)}
.rec.win .rbest .rv{color:var(--acc);font-weight:600}
.rec .rbest .rv{display:inline-block;transform-origin:center}
@keyframes recring{
  0%  {box-shadow:0 0 0 0 var(--acc-glow)}
  65% {box-shadow:0 0 0 13px transparent}
  100%{box-shadow:0 0 0 0 transparent}}
/* la montee : le chiffre prend de la place et s'allume, sans bouger de sa case */
.rec .rbest .rv.roule{color:var(--acc-2);animation:recroule var(--rd) ease-out both}
@keyframes recroule{
  0%  {transform:scale(1);text-shadow:0 0 0 transparent}
  18% {transform:scale(1.24);text-shadow:0 0 20px var(--acc-glow)}
  100%{transform:scale(1.12);text-shadow:0 0 24px var(--acc-glow)}}
/* l'atterrissage : un depassement franc, puis il se range */
.rec .rbest .rv.pose{animation:recpose .52s cubic-bezier(.18,1.7,.35,1)}
@keyframes recpose{
  0%  {transform:scale(1.12);text-shadow:0 0 24px var(--acc-glow)}
  38% {transform:scale(1.34);text-shadow:0 0 26px var(--acc-glow)}
  100%{transform:scale(1);text-shadow:0 0 0 transparent}}
@media (prefers-reduced-motion:reduce){
  .rec.hot,.rec.win{animation:none}
  .rec .rbest .rv.roule,.rec .rbest .rv.pose{animation:none} }
@media (max-width:560px){ .rec{margin-left:0} }

/* ---------- score ---------- */
.score{overflow-x:auto;margin-top:.35rem;padding:.15rem .3rem;
  background:var(--sunk);border:1px solid var(--line-soft);border-radius:10px}
.score svg{transition:opacity .35s ease}
.score.idle svg{opacity:.42}
.score svg{display:block}
.st-line{stroke:var(--ink-3);stroke-width:1;opacity:.5}
.st-clef{fill:var(--ink-2);font-family:"Bravura","Noto Music","Segoe UI Symbol",serif}
.st-head{fill:var(--acc)}
.st-hollow{fill:none;stroke:var(--acc);stroke-width:1.8}
.st-stem{stroke:var(--acc);stroke-width:1.6}
.st-flag{fill:var(--acc)}
.st-tri{font-family:"Bodoni Moda",serif;font-style:italic;font-size:10px;fill:var(--ink-2);text-anchor:middle}
.st-alt{font-size:15px;fill:var(--acc);text-anchor:middle;font-family:"Noto Music",serif}
.st-name{font-family:"IBM Plex Mono",monospace;font-size:11px;fill:var(--ink-2);text-anchor:middle}
.st-oct{font-family:"IBM Plex Mono",monospace;font-size:9px;fill:var(--ink-3);text-anchor:middle}
.score-idle{display:flex;align-items:center;gap:.5rem;font-family:"IBM Plex Mono",monospace;font-size:.62rem;
  letter-spacing:.18em;text-transform:uppercase;color:var(--ink-3);padding:.1rem .35rem .4rem}
.score-idle::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--acc);opacity:.5}

/* ---------- buttons ---------- */
.controls{display:flex;flex-wrap:wrap;gap:.6rem;margin-top:1.15rem;align-items:center}
button{font-family:Archivo,sans-serif;font-size:.86rem;font-weight:500;letter-spacing:.005em;
  padding:.62rem 1.15rem;border-radius:100px;border:1px solid var(--line);background:var(--surface);
  color:var(--ink);cursor:pointer;
  transition:background .16s ease,border-color .16s ease,color .16s ease,transform .16s ease,box-shadow .16s ease}
button:hover{border-color:var(--acc);color:var(--acc);background:var(--acc-soft);transform:translateY(-1px)}
button:active{transform:translateY(0)}
button:focus-visible{outline:2px solid var(--acc);outline-offset:3px}
button.primary{background:var(--acc);border-color:var(--acc);color:var(--on-acc);
  padding:.72rem 1.5rem;font-size:.92rem;font-weight:600;box-shadow:var(--shadow-btn)}
button.primary:hover{background:var(--acc-2);border-color:var(--acc-2);color:var(--on-acc);transform:translateY(-2px)}
button.primary::before{content:"▶";font-size:.7em;margin-right:.55em;display:inline-block;transform:translateY(-.05em)}
button.primary:disabled{opacity:.45;box-shadow:none;transform:none}
button:disabled{opacity:.4;cursor:default;transform:none}
button:disabled:hover{background:var(--surface);border-color:var(--line);color:var(--ink);transform:none}
button.dev{margin-left:auto;opacity:.5;font-family:"IBM Plex Mono",monospace;font-size:.75rem;letter-spacing:.04em}
button.dev:hover{opacity:1}
#bSkip::before{content:"→";margin-right:.5em;opacity:.7}
#bRef::before,#bReveal::before{content:"";display:inline-block;width:1.05em;height:1.05em;
  margin-right:.55em;vertical-align:-.17em;background-color:currentColor;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;
  -webkit-mask-size:contain;mask-size:contain;opacity:.85;transition:opacity .15s ease}
button:hover::before{opacity:1}
#bRef::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23000'%20stroke-width='2.2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M7%202.5v9.5a5%205%200%200%200%2010%200V2.5'/%3E%3Cpath%20d='M12%2017v4.5'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23000'%20stroke-width='2.2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M7%202.5v9.5a5%205%200%200%200%2010%200V2.5'/%3E%3Cpath%20d='M12%2017v4.5'/%3E%3C/svg%3E");width:1.2em;height:1.2em;vertical-align:-.24em}
#bReveal::before{-webkit-mask-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23000'%20stroke-width='2.1'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M1.8%2012S5.4%205.2%2012%205.2%2022.2%2012%2022.2%2012%2018.6%2018.8%2012%2018.8%201.8%2012%201.8%2012Z'/%3E%3Ccircle%20cx='12'%20cy='12'%20r='3.1'/%3E%3C/svg%3E");mask-image:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23000'%20stroke-width='2.1'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M1.8%2012S5.4%205.2%2012%205.2%2022.2%2012%2022.2%2012%2018.6%2018.8%2012%2018.8%201.8%2012%201.8%2012Z'/%3E%3Ccircle%20cx='12'%20cy='12'%20r='3.1'/%3E%3C/svg%3E")}
.msg{margin:1.05rem 0 .7rem;font-size:.92rem;color:var(--ink-2);min-height:1.5em;line-height:1.5}
.msg .reveal{color:var(--acc);font-weight:600}

/* ---------- keyboard ---------- */
.kb-wrap{overflow-x:auto;padding:.7rem .7rem .5rem;background:var(--sunk);border:1px solid var(--line-soft);border-radius:10px}
.kb{position:relative;height:136px;display:flex;min-width:520px;user-select:none}
.wk{position:relative;flex:1 0 auto;width:38px;background:var(--key-w);border:1px solid var(--key-w-edge);border-top:none;
  border-radius:0 0 6px 6px;margin-right:-1px;cursor:pointer;display:flex;align-items:flex-end;
  justify-content:center;padding-bottom:8px;font-family:"IBM Plex Mono",monospace;font-size:.58rem;color:var(--ink-3);
  transition:background .1s ease,box-shadow .1s ease}
.bk{position:absolute;top:0;width:26px;height:80px;background:var(--key-b);border-radius:0 0 4px 4px;
  cursor:pointer;z-index:2;border:1px solid var(--key-b);box-shadow:0 3px 7px rgba(0,0,0,.4);
  transition:background .1s ease,box-shadow .1s ease}
.wk:hover{background:color-mix(in srgb,var(--acc) 8%,var(--key-w))}
.wk.on{background:color-mix(in srgb,var(--acc) 30%,var(--key-w));box-shadow:0 0 0 1px var(--acc),0 0 20px var(--acc-glow)}
.bk.on{background:var(--acc);box-shadow:0 0 20px var(--acc-glow)}
/* la relecture d'epilogue : on n'accompagne plus, on montre. Les touches
   brulent, parce que c'est la seule chose qui reste a regarder. */
.wk.on.vif{background:color-mix(in srgb,var(--acc) 66%,var(--key-w));
  box-shadow:0 0 0 2px var(--acc),0 0 26px var(--acc-glow),0 0 58px var(--acc-glow);
  transition:background .04s ease,box-shadow .04s ease}
.bk.on.vif{background:color-mix(in srgb,#fff 34%,var(--acc));
  box-shadow:0 0 0 2px var(--acc),0 0 26px var(--acc-glow),0 0 58px var(--acc-glow);
  transition:background .04s ease,box-shadow .04s ease}
/* LA RELECTURE APRES UN ECHEC. On ne dime plus le clavier en bloc : l'opacite
   du conteneur eteignait aussi les touches allumees, et il ne restait qu'un
   piano gris ou clignotait un gris un peu moins gris. Le clavier s'efface
   TOUCHE PAR TOUCHE, les noms de notes avec, et seules celles qui sonnent
   restent a pleine lumiere. C'est la seule chose a regarder, elle doit etre la
   seule chose qu'on voie. */
.kb.gel.relire{opacity:1}
.kb.relire{pointer-events:none}
.kb.relire .wk{background:color-mix(in srgb,var(--sunk) 78%,var(--key-w));
  border-color:var(--line-soft);color:transparent;box-shadow:none;
  transition:background .18s ease,box-shadow .18s ease}
.kb.relire .bk{background:color-mix(in srgb,var(--sunk) 62%,var(--key-b));
  border-color:transparent;box-shadow:none;
  transition:background .18s ease,box-shadow .18s ease}
.kb.relire .wk.on{background:color-mix(in srgb,var(--acc) 74%,var(--key-w));
  box-shadow:0 0 0 2px var(--acc),0 0 30px var(--acc-glow),0 0 70px var(--acc-glow);
  transition:background .04s ease,box-shadow .04s ease}
.kb.relire .bk.on{background:color-mix(in srgb,#fff 42%,var(--acc));
  box-shadow:0 0 0 2px var(--acc),0 0 30px var(--acc-glow),0 0 70px var(--acc-glow);
  transition:background .04s ease,box-shadow .04s ease}
.kb-foot{display:flex;justify-content:space-between;align-items:center;gap:1rem;margin-top:.6rem;font-size:.72rem;color:var(--ink-3)}

/* ---------- side panels ---------- */
.side{gap:.85rem;align-items:flex-end}
.panel{width:300px;background:var(--surface);border:1px solid var(--line-soft);border-radius:var(--r);
  box-shadow:var(--shadow-s);overflow:hidden;transition:width .28s cubic-bezier(.2,.7,.2,1)}
.panel>summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:.6rem;
  padding:.85rem 1.1rem;font-family:"IBM Plex Mono",monospace;font-size:.66rem;font-weight:500;
  letter-spacing:.19em;text-transform:uppercase;color:var(--ink-2);white-space:nowrap;
  transition:color .15s ease,background .15s ease}
.panel>summary::-webkit-details-marker{display:none}
.panel>summary::marker{content:""}
.panel>summary:hover{color:var(--acc);background:var(--acc-soft)}
.panel>summary .dot{width:6px;height:6px;border-radius:50%;background:var(--acc);opacity:.6;flex:none}
.panel>summary .chev{margin-inline-start:auto;flex:none;font-size:1.05rem;line-height:1;
  transition:transform .25s ease;transform:rotate(0deg)}
.panel>summary .chev::before{content:"\203A"}
.panel[open]>summary{border-bottom:1px solid var(--line-soft)}
.panel .body{padding:1rem 1.1rem 1.15rem;width:300px}

/* replié : rail vertical, titre toujours lisible */
.panel:not([open]){width:46px}
.panel:not([open])>summary{writing-mode:vertical-rl;padding:1.05rem .55rem 1.1rem;gap:.75rem;color:var(--ink-3)}
.panel:not([open])>summary .chev{writing-mode:horizontal-tb;transform:rotate(180deg)}
@media (max-width:900px){
  .panel,.panel .body,.panel:not([open]){width:100%}
  .panel:not([open])>summary{writing-mode:horizontal-tb;padding:.85rem 1.1rem}
  .panel:not([open])>summary .chev{transform:rotate(90deg)}
}

.rows{display:flex;flex-direction:column;gap:.5rem;font-size:.82rem}
.row{display:flex;justify-content:space-between;gap:.6rem;align-items:baseline}
.row span{color:var(--ink-3)}
.row b{font-family:"IBM Plex Mono",monospace;font-weight:500;font-size:.9rem;font-variant-numeric:tabular-nums}
.spark{display:flex;align-items:flex-end;gap:2px;height:40px;margin-top:.85rem}
.spark i{flex:1;background:var(--acc);border-radius:2px 2px 0 0;min-height:2px;opacity:.75}
.spark i.low{background:var(--bad)}
select,label.opt{font-family:Archivo,sans-serif;font-size:.8rem}
.langsel{width:auto;min-width:9.5rem;align-self:center;margin-top:0;padding:.5rem .7rem;font-size:.8rem;border-radius:100px}
select{width:100%;padding:.5rem .65rem;border-radius:8px;border:1px solid var(--line);background:var(--surface);color:var(--ink);margin-top:.3rem;cursor:pointer}
select:hover{border-color:var(--acc)}
label.opt{display:flex;align-items:center;gap:.5rem;color:var(--ink-2);margin-top:.7rem;cursor:pointer}
label.opt input{accent-color:var(--acc);width:15px;height:15px}
.status{font-size:.74rem;color:var(--ink-3);margin-top:.6rem;line-height:1.45}
.status.warn{display:flex;gap:.5rem;align-items:flex-start;color:var(--warn-ink);
  background:var(--warn-bg);border:1px solid var(--warn-line);border-radius:9px;
  padding:.5rem .6rem;margin-top:.65rem;line-height:1.4}
.status.warn::before{content:"!";flex:none;width:14px;height:14px;margin-top:.5px;border-radius:50%;
  border:1px solid currentColor;font-family:Archivo,sans-serif;font-size:9.5px;font-weight:700;
  line-height:12px;text-align:center;opacity:.9}
.mini{font-size:.71rem;color:var(--ink-3);line-height:1.45;margin:.6rem 0 0}
kbd{font-family:"IBM Plex Mono",monospace;font-size:.72em;background:var(--sunk);border:1px solid var(--line-soft);border-radius:4px;padding:.1em .35em}
/* les deux boutons du bas du panneau sont une colonne : sans largeur imposee,
   celui du journal se calait a gauche sur sa propre longueur pendant que
   l'autre tenait toute la largeur, et la paire etait de travers */
#bLog,#bReset{display:block;width:100%;font-size:.8rem}
#bLog{margin-top:.9rem}
#bReset{margin-top:.55rem}
#bReset:hover{border-color:var(--bad);color:var(--bad);background:var(--bad-soft)}
.hidden{display:none !important}
@media (prefers-reduced-motion:reduce){*{transition-duration:.001ms !important;animation-duration:.001ms !important}}
/* le clavier est gelé pendant que l'app donne une note : on ne veut pas
   qu'une touche enfoncée en même temps soit comptée */
.kb.gel{opacity:.45;pointer-events:none;transition:opacity .12s ease}


/* ---------- panneau des regles ----------
   Trois etapes illustrees, les trois facons de jouer, et le clavier dessine avec
   ses lettres. Tout en SVG inline : le fichier reste autonome. */
.calib-box.ins{width:min(38rem,100%);max-height:calc(100vh - 2rem);overflow-y:auto;
  padding:1.4rem 1.4rem 1.2rem}
.ins-hi{margin:0 0 1rem;font-size:1.35rem;font-weight:600;letter-spacing:-.01em;color:var(--ink);text-align:center}
.ins-steps{display:grid;grid-template-columns:repeat(3,1fr);gap:.7rem;margin-bottom:1rem}
.ins-step{display:flex;flex-direction:column;align-items:center;gap:.6rem;text-align:center;
  padding:.75rem .5rem;border-radius:var(--r);background:var(--sunk);border:1px solid var(--line-soft)}
.ins-step > span:last-child{font-size:.82rem;line-height:1.4;color:var(--ink-2)}
.ins-ico{position:relative;display:block}
.ins-ico b{position:absolute;right:-4px;bottom:-3px;width:19px;height:19px;border-radius:50%;
  background:var(--acc);color:var(--on-acc);font-family:"IBM Plex Mono",monospace;
  font-size:.66rem;font-weight:600;display:flex;align-items:center;justify-content:center}
.ins-svg{width:52px;height:52px;display:block}
.ins-svg .s1{fill:none;stroke:var(--acc);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round}
.ins-svg .s2{fill:none;stroke:var(--ink-3);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.ins-svg .s3{fill:none;stroke:var(--ink-3);stroke-width:2;stroke-linecap:round;opacity:.45}
.ins-svg .f1{fill:var(--acc)}
.ins-svg .f2{fill:var(--acc-soft);stroke:var(--acc);stroke-width:1.6}
.ins-svg .pw{fill:var(--key-w);stroke:var(--key-w-edge);stroke-width:1.4}
.ins-svg .pe{fill:none;stroke:var(--key-w-edge);stroke-width:1.2}
.ins-svg .pb{fill:var(--key-b)}

.ins-kb{padding:.85rem .9rem .8rem;border-radius:var(--r);border:1px solid var(--line-soft);
  background:var(--sunk);margin-bottom:.9rem}
.ins-lab{margin:0 0 .75rem;font-family:"IBM Plex Mono",monospace;font-size:.6rem;
  text-transform:uppercase;letter-spacing:.18em;color:var(--ink-3);text-align:center}
.ins-ways{display:flex;justify-content:center;flex-wrap:wrap;gap:.5rem 1.3rem;margin-bottom:.95rem}
.ins-way{display:flex;align-items:center;gap:.4rem;font-size:.78rem;color:var(--ink-2)}
.ins-way i{font-style:normal}
.ins-mini{width:30px;height:21px;flex:none}
.ins-mini .s2{fill:none;stroke:var(--ink-3);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.ins-mini .f1{fill:var(--acc)}
.ins-mini .kc{font-family:"IBM Plex Mono",monospace;font-size:8px;text-anchor:middle;fill:var(--ink-3)}

.ins-piano{display:block;width:min(272px,100%);height:auto;margin:0 auto;overflow:visible}
.ins-piano .kw{fill:var(--key-w);stroke:var(--key-w-edge);stroke-width:1}
.ins-piano .kb2{fill:var(--key-b)}
.ins-piano .kl{font-family:"IBM Plex Mono",monospace;font-size:11px;font-weight:600;
  text-anchor:middle;fill:#3A3346}
.ins-piano .kln{fill:#FCFBF9}

/* Les deux dernières lignes forment une paire : même taille, même couleur, même
   gouttière d'icône, pour qu'aucune ne pèse plus que l'autre. Ni fond ni cadre,
   le bouton reste le seul élément rempli du panneau. */
.ins-note{display:flex;align-items:flex-start;gap:.6rem;margin:0 0 .7rem;
  font-size:.83rem;line-height:1.5;color:var(--ink-2)}
.ins-note:last-of-type{margin-bottom:1.1rem}
.ins-pic{flex:none;width:19px;display:flex;justify-content:center;padding-top:.06rem}
.ins-pic svg{width:16px;height:19px;display:block}
.ins-pic .s2{fill:none;stroke:var(--acc);stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.ins-go{display:block;width:100%;padding:.8rem;font:inherit;font-size:.98rem;font-weight:600;
  color:var(--on-acc);background:var(--acc);border:0;border-radius:11px;cursor:pointer;
  box-shadow:var(--shadow-btn);transition:background .16s ease,transform .16s ease}
.ins-go:hover{background:var(--acc-2);transform:translateY(-1px)}
.ins-go:active{transform:translateY(0)}
.ins-go:focus-visible{outline:2px solid var(--acc);outline-offset:3px}
@media (max-width:520px){
  .ins-steps{grid-template-columns:1fr;gap:.6rem}
  .ins-step{flex-direction:row;text-align:left;gap:.85rem}
}

/* ---------- question d'entree ---------- */
.calib{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;
  padding:1.5rem;background:var(--ground);animation:cfade .28s ease}
.calib[hidden]{display:none}
@keyframes cfade{from{opacity:0}to{opacity:1}}
.calib-box{width:min(30rem,100%);background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r);box-shadow:var(--shadow-s);padding:1.6rem 1.5rem 1.3rem;
  background-image:radial-gradient(120% 62% at 50% -28%,var(--acc-soft),transparent 60%)}
.calib-q{font-size:1.06rem;line-height:1.45;margin:0 0 1.15rem;color:var(--ink);font-weight:500}
.calib-opt{display:block;width:100%;text-align:left;margin:0 0 .55rem;padding:.72rem .9rem;
  font:inherit;font-size:.95rem;color:var(--ink);background:var(--sunk);cursor:pointer;
  border:1px solid var(--line);border-radius:10px;
  transition:background .16s ease,border-color .16s ease,transform .16s ease}
.calib-opt:hover{background:var(--acc-soft);border-color:var(--acc-glow);transform:translateY(-1px)}
.calib-opt:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
.calib-note{margin:1rem 0 0;font-size:.78rem;line-height:1.5;color:var(--ink-3)}
.calib-p{margin:0 0 .8rem;font-size:.9rem;line-height:1.55;color:var(--ink-2)}
.calib-p kbd{font-family:"IBM Plex Mono",monospace;font-size:.82em;background:var(--sunk);
  border:1px solid var(--line);border-radius:4px;padding:.05em .35em}
.calib-go{margin-top:1.1rem;text-align:center;font-weight:500}

/* ============================================================================
   NOUVEAU : en-tete de progression, panneau Profil, vies, animations
   ========================================================================= */

/* ---------- en-tete : XP, niveau, serie ---------- */
.prog{flex:1 1 340px;min-width:250px;display:flex;flex-direction:column;gap:.42rem}
.prog-top{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;
  font-family:"IBM Plex Mono",monospace;font-size:.76rem;color:var(--ink-3)}
.prog-lvl{font-size:.63rem;font-weight:500;letter-spacing:.2em;text-transform:uppercase}
.prog-lvl b{font-family:"Bodoni Moda",Didot,serif;font-size:1.35rem;font-weight:400;
  letter-spacing:0;color:var(--acc);margin-left:.4em;vertical-align:-.08em}
.prog-xp{font-variant-numeric:tabular-nums;font-size:.95rem;color:var(--ink-2)}
.prog-xp b{font-weight:500;color:var(--ink)}
.bar{position:relative;height:8px;background:var(--sunk);border-radius:100px;overflow:hidden;
  border:1px solid var(--line-soft)}
.bar i{position:absolute;inset:0 auto 0 0;border-radius:100px;
  background:linear-gradient(90deg,var(--acc),var(--acc-2));
  transition:width .6s cubic-bezier(.2,.7,.3,1)}
.prog-sub{display:flex;justify-content:space-between;font-size:.7rem;color:var(--ink-3)}
.streak{display:inline-flex;align-items:center;gap:.32rem;font-variant-numeric:tabular-nums}
.streak svg{width:11px;height:13px;flex:none}
.streak.on{color:var(--acc)}
.streak.on svg path{fill:var(--acc)}
.streak svg path{fill:var(--ink-3);opacity:.55}

/* le gain d'XP qui monte vers le compteur */
.xpfly{position:fixed;z-index:60;pointer-events:none;font-family:"IBM Plex Mono",monospace;
  font-size:1.15rem;font-weight:600;color:var(--acc);text-shadow:0 1px 10px var(--acc-glow);
  animation:xpfly 1.15s cubic-bezier(.3,.8,.4,1) forwards}
@keyframes xpfly{
  0%{opacity:0;transform:translate(-50%,0) scale(.8)}
  18%{opacity:1;transform:translate(-50%,-14px) scale(1.1)}
  100%{opacity:0;transform:translate(-50%,-96px) scale(.85)}}
.xpdet{font-family:"IBM Plex Mono",monospace;font-size:.72rem;color:var(--ink-3);
  margin-top:.35rem;letter-spacing:.01em;opacity:0;animation:xpdet 3.2s ease forwards}
.xpdet b{color:var(--ink-2);font-weight:500;font-variant-numeric:tabular-nums}
.xpdet em{font-style:normal;color:var(--acc);font-weight:600}
@keyframes xpdet{0%{opacity:0}12%{opacity:1}72%{opacity:1}100%{opacity:0}}

/* ---------- gravure animee de la partition ---------- */
.score .ng{opacity:0;animation:grav .12s ease-out forwards}
@keyframes grav{from{opacity:0;transform:translateY(2px)}to{opacity:1;transform:translateY(0)}}
@media (prefers-reduced-motion:reduce){.score .ng{animation:none;opacity:1}}

/* ---------- ecoute et jeu : deux etats, tres legerement ---------- */
.card.stage{transition:filter .2s ease}
.card.stage.ecoute{filter:saturate(.94)}
.card.stage.ecoute{background-image:radial-gradient(120% 62% at 50% -28%,
  color-mix(in srgb,var(--acc) 13%,transparent),transparent 60%)}

/* ---------- le logo qui respire ---------- */
.brand-mark i{transition:background .09s ease}
.brand-mark i.lit{background:var(--acc)!important}

/* ---------- bandeau de mode ---------- */
.mode{display:inline-flex;align-items:center;gap:.45rem;margin-bottom:.7rem;
  padding:.3rem .75rem;border-radius:100px;border:1px solid var(--acc-glow);
  background:var(--acc-soft);color:var(--acc);
  font-family:"IBM Plex Mono",monospace;font-size:.62rem;font-weight:500;
  letter-spacing:.17em;text-transform:uppercase}
.mode[hidden]{display:none}
.mode::before{content:"";width:5px;height:5px;border-radius:50%;background:currentColor}

/* ---------- panneau Profil : les quatre axes ---------- */
.axes{display:flex;flex-direction:column;gap:.72rem;margin:.2rem 0 .95rem}
.axe{display:grid;grid-template-columns:1fr auto;gap:.15rem .6rem;align-items:baseline}
.axe .an{font-size:.79rem;color:var(--ink-2)}
.axe .av{font-family:"IBM Plex Mono",monospace;font-size:.85rem;font-weight:500;
  font-variant-numeric:tabular-nums;color:var(--ink-2)}
.axe .ab{grid-column:1/-1;height:6px;background:var(--sunk);border-radius:100px;
  overflow:hidden;border:1px solid var(--line-soft)}
.axe .ab i{display:block;height:100%;border-radius:100px;background:var(--acc);opacity:.55;
  transition:width .5s cubic-bezier(.2,.7,.3,1)}
.axe.faible .an{color:var(--acc);font-weight:500}
.axe.faible .av{color:var(--acc);font-weight:600}
.axe.faible .ab i{opacity:1}
.axe .tag{grid-column:1/-1;font-family:"IBM Plex Mono",monospace;font-size:.56rem;
  letter-spacing:.16em;text-transform:uppercase;color:var(--acc);margin-top:.1rem}
.glob{display:flex;justify-content:space-between;align-items:baseline;
  padding-bottom:.7rem;margin-bottom:.2rem;border-bottom:1px solid var(--line-soft)}
.glob span{font-family:"IBM Plex Mono",monospace;font-size:.6rem;letter-spacing:.18em;
  text-transform:uppercase;color:var(--ink-3)}
.glob b{font-family:"Bodoni Moda",Didot,serif;font-size:1.7rem;font-weight:400;color:var(--acc)}

/* sparkline a quatre lignes */
.spark4{position:relative;height:46px;margin-top:.85rem;background:var(--sunk);
  border:1px solid var(--line-soft);border-radius:8px;overflow:hidden}
.spark4 svg{display:block;width:100%;height:100%}
.spark4 path{fill:none;stroke:var(--acc);stroke-width:1.5;stroke-linejoin:round;stroke-linecap:round}
.spark4 path.a0{opacity:.30}
.spark4 path.a1{opacity:1}
.spark4 path.a2{opacity:.62}
.spark4 path.a3{opacity:.44}
.sk-leg{display:flex;flex-wrap:wrap;gap:.15rem .7rem;margin-top:.4rem;
  font-family:"IBM Plex Mono",monospace;font-size:.58rem;color:var(--ink-3)}
.sk-leg i{display:inline-block;width:9px;height:2px;background:var(--acc);margin-right:.3rem;
  vertical-align:.22em}
.spark4[hidden]{display:none}

/* ============================================================================
   VIES, DEGATS, PERTE, REPECHAGE, ENTREE DE MODE
   ========================================================================= */
:root{ --vie:#D8352A; --vie-glow:rgba(216,53,42,.45); --vie-bg:rgba(216,53,42,.12); }
/* le repechage est la seule bonne nouvelle de cette famille d'ecrans : il a sa
   couleur, le vert des seances ciblees, et pas le rouge des vies qui tombent. */
:root{ --rep:#2E7D50; --rep-glow:rgba(46,125,80,.45); --rep-bg:rgba(46,125,80,.14); }
:root:not([data-theme="light"]){ }
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --vie:#F2564A; --vie-glow:rgba(242,86,74,.5); --vie-bg:rgba(242,86,74,.16); }}
:root[data-theme="dark"]{ --vie:#F2564A; --vie-glow:rgba(242,86,74,.5); --vie-bg:rgba(242,86,74,.16); }
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --rep:#5FB183; --rep-glow:rgba(95,177,131,.5); --rep-bg:rgba(95,177,131,.16); }}
:root[data-theme="dark"]{ --rep:#5FB183; --rep-glow:rgba(95,177,131,.5); --rep-bg:rgba(95,177,131,.16); }

.vies{display:flex;align-items:center;gap:.4rem;margin-left:auto;align-self:center}
.vies svg{width:21px;height:20px;display:block;overflow:visible}
.vies .v{transform-origin:50% 60%;display:block}
.vies .vh{fill:var(--vie);stroke:var(--vie);stroke-width:1.4;stroke-linejoin:round;
  filter:drop-shadow(0 1px 4px var(--vie-glow));
  transition:fill .3s ease,opacity .3s ease,filter .3s ease}
.vies .v.off .vh{fill:none;opacity:.32;filter:none}
.vies .v.off .vx{stroke:var(--vie);stroke-width:1.7;stroke-linecap:round;opacity:.32;fill:none}

/* une vie qui tombe : le coeur gonfle, vire, puis se vide */
.vies .v.pop{animation:viepop .52s cubic-bezier(.3,1.5,.4,1)}
@keyframes viepop{
  0%{transform:scale(1) rotate(0)}
  25%{transform:scale(1.45) rotate(-9deg)}
  45%{transform:scale(1.1) rotate(7deg)}
  70%{transform:scale(1.22) rotate(-4deg)}
  100%{transform:scale(1) rotate(0)}}
.vies .v.brise{animation:viebrise .5s ease-out}
@keyframes viebrise{
  0%{transform:translateY(0) rotate(0);opacity:1}
  30%{transform:translateY(-5px) rotate(-12deg)}
  100%{transform:translateY(13px) rotate(22deg);opacity:.15}}

/* la carte encaisse : un flash rouge bref, sans secousse excessive */
.card.stage.degat{animation:degat .5s ease-out}
@keyframes degat{
  0%{box-shadow:var(--shadow-s)}
  12%{box-shadow:0 0 0 3px var(--vie-glow),var(--shadow-s);transform:translateX(-4px)}
  30%{transform:translateX(4px)}
  46%{transform:translateX(-2px)}
  100%{box-shadow:var(--shadow-s);transform:translateX(0)}}

/* la melodie est perdue : plus lourd, plus long, sans etre grotesque */
.card.stage.perdu{animation:perdu 1.05s cubic-bezier(.3,.7,.4,1)}
@keyframes perdu{
  0%{box-shadow:var(--shadow-s)}
  8%{box-shadow:0 0 0 5px var(--vie-glow),var(--shadow-s);transform:translateX(-9px) rotate(-.5deg)}
  20%{transform:translateX(9px) rotate(.5deg)}
  32%{transform:translateX(-6px) rotate(-.3deg)}
  44%{transform:translateX(5px)}
  58%{transform:translateX(-2px)}
  100%{box-shadow:var(--shadow-s);transform:translateX(0) rotate(0)}}
.card.stage.perdu::after{content:"";position:absolute;inset:0;border-radius:var(--r);
  pointer-events:none;background:var(--vie-bg);animation:perduvoile 1.05s ease-out forwards}
@keyframes perduvoile{0%{opacity:0}14%{opacity:1}100%{opacity:0}}
.card.stage{position:relative}
.msg .rouge{color:var(--vie);font-weight:600}

/* repechage : la carte reprend des couleurs */
.card.stage.repeche{animation:repechep 2s ease-out}
@keyframes repechep{
  0%{box-shadow:var(--shadow-s)}
  18%{box-shadow:0 0 0 6px var(--rep-glow),var(--shadow-s)}
  100%{box-shadow:var(--shadow-s)}}
.repeche-flash{position:absolute;inset:0;z-index:5;display:flex;
  align-items:center;justify-content:center;border-radius:var(--r);pointer-events:none;
  background:radial-gradient(70% 70% at 50% 50%,var(--rep-bg),transparent 76%);
  backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);
  animation:repfade 2.6s ease-out forwards}
/* le bandeau se posait a meme la carte et son sous-texte tombait en travers
   des boutons : illisible. Il a maintenant son propre cartouche. */
.rep-box{display:flex;flex-direction:column;align-items:center;gap:.42rem;
  padding:1.15rem 1.9rem;border-radius:var(--r);background:var(--surface);
  border:1px solid var(--rep);box-shadow:0 10px 40px -12px var(--rep-glow),var(--shadow-s);
  max-width:min(26rem,88%);text-align:center}
.repeche-flash span{font-family:"Bodoni Moda",Didot,serif;font-size:2.3rem;line-height:1;
  color:var(--rep);text-shadow:0 2px 22px var(--rep-glow);
  animation:reppop 2.6s cubic-bezier(.2,1.4,.4,1) forwards}
/* le sous-texte dit ce que le repechage rend : sans lui, le bandeau est joli
   mais le joueur ne sait pas ce qui vient de se passer */
.repeche-flash em{font-style:normal;font-family:Archivo,sans-serif;font-size:.95rem;
  font-weight:500;color:var(--ink-2);letter-spacing:.01em;line-height:1.4;
  animation:repsous 2.6s ease-out forwards}
@keyframes repsous{
  0%{opacity:0;transform:translateY(8px)}
  22%{opacity:0;transform:translateY(8px)}
  38%{opacity:1;transform:translateY(0)}
  84%{opacity:1;transform:translateY(0)}
  100%{opacity:0;transform:translateY(-4px)}}
@keyframes repfade{0%{opacity:0}12%{opacity:1}74%{opacity:1}100%{opacity:0}}
@keyframes reppop{
  0%{transform:scale(.5) rotate(-6deg);opacity:0}
  16%{transform:scale(1.15) rotate(2deg);opacity:1}
  30%{transform:scale(1) rotate(0)}
  74%{transform:scale(1);opacity:1}
  100%{transform:scale(1.05);opacity:0}}

/* ---------- sauvetage ----------
   Le sauvetage prend l'ecran. Tout s'efface SAUF le clavier, parce que c'est
   exactement ce qu'on demande au joueur de faire : chercher les notes sous ses
   doigts. Le voile ne dime donc pas la page entiere par-dessus, il eteint les
   elements un par un et laisse le piano intact — pas de superposition, pas de
   contexte d'empilement a demeler, et surtout le clavier reste cliquable. */
body.sauv-on header, body.sauv-on .side, body.sauv-on .now,
body.sauv-on .stage-head, body.sauv-on .score, body.sauv-on .controls,
body.sauv-on .msg, body.sauv-on .xpdet, body.sauv-on .kb-foot{
  opacity:.14;pointer-events:none;transition:opacity .35s ease}
/* seule exception : reecouter la phrase reste possible pendant la recherche.
   Treize a trente secondes sans pouvoir la redemander seraient une punition,
   pas une aide, et le compte a rebours est de toute facon suspendu le temps
   de la lecture. Les boutons restent donc atteignables, juste en retrait. */
body.sauv-on .controls,
/* ... ET pendant la restitution. Le bouton etait deja reactive cote script,
   mais cette regle-ci le rendait inerte : opacite 14 % et pointer-events none,
   donc un bouton qui a l'air disponible et qui ne repond pas. Reecouter remet
   la phrase au debut, ca se paie en recommencant, c'est bien assez cher. */
body.sauv-play .controls{opacity:.45;pointer-events:auto}
/* ... et pendant la restitution il n'est plus EN RETRAIT du tout : un bouton a
   demi efface se lit comme un bouton mort, alors qu'il marche. */
body.sauv-play .controls{opacity:1}
body.sauv-on .kb-wrap{
  box-shadow:0 0 0 2px var(--acc),0 22px 60px -24px var(--acc-glow);
  transition:box-shadow .35s ease}
/* la restitution garde le contour de l'exploration. Le cerne rouge disait
   "attention, danger" au moment precis ou l'on demande au joueur de jouer
   tranquillement ce qu'il vient de chercher. */

/* le voile ne couvre que le haut de l'ecran : le clavier occupe le bas et le
   gros compteur n'a rien a faire par-dessus. Centre dans les deux tiers
   superieurs, il tombe a peu pres sur la portee, la ou le regard est deja. */
.sauv{position:fixed;inset:0 0 32vh 0;z-index:55;display:flex;align-items:center;
  justify-content:center;padding:1.4rem;pointer-events:none;text-align:center;
  animation:sauvIn .3s ease-out}
.sauv[hidden]{display:none}
@keyframes sauvIn{from{opacity:0;transform:scale(.97)}to{opacity:1;transform:scale(1)}}
/* Le bloc a son propre fond. Sur un grand ecran il tombe sur la portee vide et
   un fond transparent suffisait ; a 360-390 px il se posait en travers du titre
   de la melodie et du bandeau du record, restes visibles a 14 % : deux textes
   l'un sur l'autre, illisibles tous les deux. */
.sv-box{display:flex;flex-direction:column;align-items:center;gap:.5rem;
  max-width:min(30rem,92vw);padding:1.1rem 1.5rem;border-radius:calc(var(--r) + 4px);
  background:color-mix(in srgb,var(--ground) 82%,transparent);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}
.sauv.sv-echec .sv-box{background:none;backdrop-filter:none;-webkit-backdrop-filter:none}
.sv-lab{font-family:"IBM Plex Mono",monospace;font-size:.64rem;font-weight:500;
  letter-spacing:.26em;text-transform:uppercase;color:var(--acc);margin:0}
.sv-num{font-family:"Bodoni Moda",Didot,serif;font-weight:400;
  font-size:clamp(4rem,15vw,8.5rem);line-height:.94;color:var(--ink);
  font-variant-numeric:tabular-nums;letter-spacing:-.03em;
  text-shadow:0 6px 40px var(--acc-glow)}
.sv-num.court{color:var(--vie);text-shadow:0 6px 40px var(--vie-glow);
  animation:svpulse .9s ease-in-out infinite}
/* la meme case, mais avec un mot a la place du chiffre : le chiffre est du
   Bodoni a huit rem, une phrase a cette taille ne tient sur aucun ecran */
.sv-num.texte{font-size:clamp(1.9rem,6vw,3.1rem);line-height:1.1;letter-spacing:-.01em;
  color:var(--ink);text-shadow:0 6px 40px var(--acc-glow)}
/* l'etiquette du cadre peut etre vide : la restitution et l'ecran d'echec n'en
   ont plus. Sans ce hidden, il reste une ligne fantome qui decale la box. */
.sv-lab[hidden]{display:none}
@keyframes svpulse{0%,100%{transform:scale(1)}50%{transform:scale(1.07)}}
.sv-sub{font-family:Archivo,sans-serif;font-size:1rem;line-height:1.45;
  color:var(--ink-2);margin:.1rem 0 0;text-wrap:balance}
.sv-sub b{color:var(--ink);font-weight:600}
.sv-bar{width:min(20rem,70vw);height:5px;border-radius:100px;background:var(--sunk);
  border:1px solid var(--line-soft);overflow:hidden;margin-top:.55rem}
.sv-bar i{display:block;height:100%;background:linear-gradient(90deg,var(--acc),var(--acc-2));
  border-radius:100px;transition:width .12s linear}
.sv-bar.court i{background:linear-gradient(90deg,var(--vie),var(--vie))}

/* l'ecran d'echec : plus lourd, plus lent, et il occupe tout */
/* l'echec, lui, prend tout l'ecran : il n'y a plus rien a jouer */
.sauv.sv-echec{inset:0;background:color-mix(in srgb,var(--ground) 88%,transparent);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px)}
.sauv.sv-echec .sv-box{gap:.7rem}
.sauv.sv-echec .sv-lab{color:var(--vie)}
.sauv.sv-echec .sv-num{font-size:clamp(2.6rem,8vw,4.4rem);color:var(--vie);
  text-shadow:0 6px 46px var(--vie-glow);animation:svechec 1.5s cubic-bezier(.2,.8,.3,1)}
@keyframes svechec{
  0%{opacity:0;transform:scale(1.3) translateY(-10px);letter-spacing:.16em}
  55%{opacity:1;transform:scale(1) translateY(0);letter-spacing:-.03em}
  100%{opacity:1}}
@media (prefers-reduced-motion:reduce){
  .sauv,.sv-num.court,.sauv.sv-echec .sv-num{animation:none}}

/* entree d'un mode special : un bandeau qui traverse la carte */
.mode-intro{position:absolute;inset:0;z-index:6;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:.3rem;border-radius:var(--r);
  pointer-events:none;background:radial-gradient(70% 70% at 50% 50%,var(--acc-soft),transparent 72%);
  animation:mifade 2.1s ease-out forwards}
.mode-intro b{font-family:"Bodoni Moda",Didot,serif;font-weight:400;font-size:2.15rem;
  letter-spacing:-.01em;color:var(--acc);text-shadow:0 2px 26px var(--acc-glow);
  animation:mislide 2.1s cubic-bezier(.2,1.2,.3,1) forwards}
.mode-intro i{font-style:normal;font-family:"IBM Plex Mono",monospace;font-size:.66rem;
  letter-spacing:.24em;text-transform:uppercase;color:var(--ink-2);
  animation:misub 2.1s ease-out forwards}
@keyframes mifade{0%{opacity:0}10%{opacity:1}76%{opacity:1}100%{opacity:0}}
@keyframes mislide{
  0%{transform:translateX(-38px) scale(.9);opacity:0}
  18%{transform:translateX(0) scale(1.04);opacity:1}
  30%{transform:scale(1)}
  76%{opacity:1}
  100%{transform:translateX(26px);opacity:0}}
@keyframes misub{0%{opacity:0;letter-spacing:.5em}22%{opacity:1;letter-spacing:.24em}
  76%{opacity:1}100%{opacity:0}}

@media (prefers-reduced-motion:reduce){
  .vies .v.pop,.vies .v.brise,.card.stage.degat,.card.stage.perdu,
  .card.stage.repeche,.repeche-flash,.repeche-flash span,.repeche-flash em,
  .mode-intro b,.mode-intro i{animation:none}
  .card.stage.perdu::after{animation:none;opacity:0}}

/* ---------- defis et seances ciblees ---------- */
.mode-intro.mi-dur  b{color:#C4761E}
.mode-intro.mi-xdur b{color:var(--vie)}
.mode-intro.mi-focus b{color:#2E7D50}
.mode-intro.mi-longue b{color:#2B6E8F}
.mode-intro.mi-sursis b{color:var(--vie)}
.mode-intro.mi-dur i,.mode-intro.mi-xdur i,.mode-intro.mi-focus i,
.mode-intro.mi-longue i,.mode-intro.mi-sursis i{opacity:.85}
.mode-intro.mi-xdur b{animation:xdurp 2.1s ease-out}
@keyframes xdurp{
  0%{opacity:0;transform:scale(.86)}
  12%{opacity:1;transform:scale(1.06)}
  20%{transform:scale(1)}
  34%{transform:scale(1.03)}
  46%{transform:scale(1)}
  74%{opacity:1}
  100%{opacity:0}
}
#msg .dDur  {color:#C4761E;font-weight:600}
#msg .dXdur {color:var(--vie);font-weight:600}
#msg .dFocus{color:#2E7D50;font-weight:600}
#msg .focus-k{font-size:.8em;color:var(--ink-3);letter-spacing:.08em}
#msg .dLongue{color:#2B6E8F;font-weight:600}
:root[data-theme="dark"] .mode-intro.mi-dur b,
:root[data-theme="dark"] #msg .dDur {color:#E09A4A}
:root[data-theme="dark"] .mode-intro.mi-focus b,
:root[data-theme="dark"] #msg .dFocus{color:#5FB183}
:root[data-theme="dark"] .mode-intro.mi-longue b,
:root[data-theme="dark"] #msg .dLongue{color:#6FB2D2}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .mode-intro.mi-dur b,
  :root:not([data-theme="light"]) #msg .dDur {color:#E09A4A}
  :root:not([data-theme="light"]) .mode-intro.mi-focus b,
  :root:not([data-theme="light"]) #msg .dFocus{color:#5FB183}
  :root:not([data-theme="light"]) .mode-intro.mi-longue b,
  :root:not([data-theme="light"]) #msg .dLongue{color:#6FB2D2}
}
@media (prefers-reduced-motion:reduce){ .mode-intro.mi-xdur b{animation:none} }

/* ============================================================================
   V3.23 : PAUSE
   Deux pauses differentes.
   - La pause de fatigue (#repos) prend tout l'ecran, toujours sombre, quel que
     soit le theme : c'est un moment a part, on eteint la piece. Un cercle
     respire 20 secondes, 4 s d'inspiration et 6 s d'expiration, deux fois.
   - La pause manuelle (.pause-voile) ne couvre que la carte de jeu : elle gele
     la partie, rien de plus.
   ========================================================================= */
.repos{position:fixed;inset:0;z-index:80;display:flex;align-items:center;justify-content:center;
  padding:1.5rem 1rem;overflow-y:auto;
  --rp-ink:#F1EEF6;--rp-ink2:#B9B2C6;--rp-ink3:#8A8399;--rp-acc:#A78CF5;--rp-acc2:#C3AEFF;
  --rp-glow:rgba(167,140,245,.42);
  background:radial-gradient(90% 70% at 50% 38%,rgba(46,30,84,.55),transparent 70%),rgba(9,7,13,.93);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  color:var(--rp-ink);opacity:0;transition:opacity .8s ease}
.repos[hidden]{display:none}
.repos.on{opacity:1}
.repos.sort{opacity:0;transition:opacity .6s ease}
.rp-box{display:flex;flex-direction:column;align-items:center;gap:1.6rem;width:min(34rem,100%);
  text-align:center;margin:auto}
.rp-souffle{position:relative;width:min(46vmin,15rem);aspect-ratio:1;display:grid;place-items:center}
.rp-rond,.rp-halo{position:absolute;inset:0;border-radius:50%;transform:scale(.58)}
.rp-rond{background:radial-gradient(circle at 50% 42%,rgba(195,174,255,.34),rgba(167,140,245,.13) 58%,rgba(167,140,245,.04) 72%);
  border:1px solid rgba(195,174,255,.42)}
.rp-halo{box-shadow:0 0 70px 18px var(--rp-glow);opacity:.35}
.rp-souffle.vit .rp-rond{animation:rpSouffle 10s cubic-bezier(.45,0,.4,1) 2 forwards}
.rp-souffle.vit .rp-halo{animation:rpHalo 10s cubic-bezier(.45,0,.4,1) 2 forwards}
@keyframes rpSouffle{0%{transform:scale(.58)}40%{transform:scale(1)}100%{transform:scale(.58)}}
@keyframes rpHalo{0%{transform:scale(.58);opacity:.3}40%{transform:scale(1);opacity:.9}100%{transform:scale(.58);opacity:.3}}
.rp-titre,.rp-mot{position:relative;margin:0;transition:opacity .6s ease}
.rp-titre{font-family:"Bodoni Moda",Didot,serif;font-weight:400;font-size:clamp(2.6rem,9vw,3.8rem);
  letter-spacing:-.01em;line-height:1;color:var(--rp-ink);text-shadow:0 4px 34px var(--rp-glow)}
.rp-mot{font-family:"IBM Plex Mono",monospace;font-size:.7rem;letter-spacing:.26em;text-transform:uppercase;
  color:var(--rp-acc2);opacity:0;position:absolute}
.rp-titre.off{opacity:0}
.rp-mot.on{opacity:1}
.rp-cit{margin:0;max-width:32rem;opacity:0;transform:translateY(6px);
  transition:opacity 1.2s ease,transform 1.2s ease}
.rp-cit.on{opacity:1;transform:none}
.rp-kick{display:block;font-family:"IBM Plex Mono",monospace;font-size:.6rem;letter-spacing:.24em;
  text-transform:uppercase;color:var(--rp-ink3);margin-bottom:.7rem}
.rp-txt{margin:0;font-family:"Bodoni Moda",Didot,serif;font-size:clamp(1.12rem,3.6vw,1.4rem);
  line-height:1.42;color:var(--rp-ink);text-wrap:pretty}
.rp-txt.dit{font-style:italic}
.rp-txt.long{font-family:Archivo,sans-serif;font-size:clamp(.95rem,3vw,1.05rem);line-height:1.6;color:var(--rp-ink)}
.rp-src{margin-top:.8rem;font-size:.78rem;line-height:1.45;color:var(--rp-ink2)}
.rp-go{opacity:0;visibility:hidden;transition:opacity .8s ease}
.rp-go.on{opacity:1;visibility:visible}
.repos button.primary{background:var(--rp-acc);border-color:var(--rp-acc);color:#120F18;
  box-shadow:0 1px 2px rgba(0,0,0,.5),0 12px 24px -14px var(--rp-glow)}
.repos button.primary:hover{background:var(--rp-acc2);border-color:var(--rp-acc2);color:#120F18}
.repos button.primary::before{content:none}
@media (prefers-reduced-motion:reduce){
  .rp-souffle.vit .rp-rond,.rp-souffle.vit .rp-halo{animation:none}
  .rp-rond,.rp-halo{transform:scale(.8)}
  .rp-souffle.vit .rp-halo{animation:rpHaloDoux 10s ease-in-out 2 forwards}
  @keyframes rpHaloDoux{0%,100%{opacity:.25}40%{opacity:.8}}
  .rp-cit{transform:none}}

/* la pause manuelle : un voile sur la carte, le reste de la page reste lisible */
#bPause{margin-left:auto}
#bPause::before{content:"";display:inline-block;width:.62em;height:.78em;margin-right:.55em;
  border-left:.2em solid currentColor;border-right:.2em solid currentColor;vertical-align:-.06em;opacity:.85}
#bPause.attente{border-color:var(--acc);color:var(--acc);background:var(--acc-soft)}
.pause-voile{position:absolute;inset:0;z-index:7;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:1rem;border-radius:var(--r);text-align:center;padding:1rem;
  background:color-mix(in srgb,var(--surface) 86%,transparent);
  backdrop-filter:blur(5px);-webkit-backdrop-filter:blur(5px);animation:cfade .25s ease}
.pause-voile[hidden]{display:none}
.pause-voile b{font-family:"Bodoni Moda",Didot,serif;font-weight:400;font-size:2.2rem;color:var(--acc);
  letter-spacing:-.01em;line-height:1}

/* client-serveur : case de consentement sur l'ecran d'accueil */
.consent{display:flex;gap:.5em;align-items:flex-start;margin-top:1em;font-size:.85em;opacity:.85;text-align:left;cursor:pointer;flex-basis:100%;max-width:480px}
.consent input{margin-top:.2em}
