:root{
  --bg:#F1F4F0;
  --bg-line: rgba(38,58,48,.09);
  --surface:#FFFFFF;
  --surface-2:#E9EDE7;
  --ink:#1A2420;
  --ink-muted:#5B6961;
  --accent:#2A5C86;
  --accent-2:#4C7EA6;
  --accent-soft:#DCEAF3;
  --border:#D3D9D0;

  --future-bg:#DDE0D9; --future-fg:#4C564E;
  --already-bg:#CFE6D4; --already-fg:#1E5C34;
  --new-bg:#CDE1F1;     --new-fg:#12395A;
  --repeat-bg:#F4DCA9;  --repeat-fg:#6B4509;
  --stick-pink:#F6D8E4;

  /* Hachures « connu par commutativité » : se posent par-dessus n'importe
     quelle couleur d'état, sans occuper de largeur ni ajouter une 5e teinte. */
  --hatch: repeating-linear-gradient(-45deg, transparent 0 3px, rgba(26,36,32,.20) 3px 5px);

  --font-display: Cambria, 'Iowan Old Style', 'Palatino Linotype', Georgia, serif;
  --font-body: Calibri, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
  --font-mono: Consolas, 'Cascadia Mono', 'SFMono-Regular', ui-monospace, monospace;

  --radius-s: 5px;
  --radius-m: 10px;
}
@media (prefers-color-scheme: dark){
  :root{
    --bg:#141E19;
    --bg-line: rgba(255,255,255,.07);
    --surface:#1B2820;
    --surface-2:#22322A;
    --ink:#EAF0EA;
    --ink-muted:#93A399;
    --accent:#7FB6DE;
    --accent-2:#5C97C4;
    --accent-soft:#20374A;
    --border:#2C3B33;

    --future-bg:#25322A; --future-fg:#8A968D;
    --already-bg:#1E3F2A; --already-fg:#7FD79E;
    --new-bg:#1D3A52;     --new-fg:#9CCBEE;
    --repeat-bg:#3C2E10;  --repeat-fg:#E7BD70;
    --hatch: repeating-linear-gradient(-45deg, transparent 0 3px, rgba(234,240,234,.22) 3px 5px);
    --stick-pink:#3E2532;
  }
}
:root[data-theme="dark"]{
  --bg:#141E19;
  --bg-line: rgba(255,255,255,.07);
  --surface:#1B2820;
  --surface-2:#22322A;
  --ink:#EAF0EA;
  --ink-muted:#93A399;
  --accent:#7FB6DE;
  --accent-2:#5C97C4;
  --accent-soft:#20374A;
  --border:#2C3B33;
  --future-bg:#25322A; --future-fg:#8A968D;
  --already-bg:#1E3F2A; --already-fg:#7FD79E;
  --new-bg:#1D3A52;     --new-fg:#9CCBEE;
  --repeat-bg:#3C2E10;  --repeat-fg:#E7BD70;
  --stick-pink:#3E2532;
  --hatch: repeating-linear-gradient(-45deg, transparent 0 3px, rgba(234,240,234,.22) 3px 5px);
}
:root[data-theme="light"]{
  --bg:#F1F4F0;
  --bg-line: rgba(38,58,48,.09);
  --surface:#FFFFFF;
  --surface-2:#E9EDE7;
  --ink:#1A2420;
  --ink-muted:#5B6961;
  --accent:#2A5C86;
  --accent-2:#4C7EA6;
  --accent-soft:#DCEAF3;
  --border:#D3D9D0;
  --future-bg:#DDE0D9; --future-fg:#4C564E;
  --already-bg:#CFE6D4; --already-fg:#1E5C34;
  --new-bg:#CDE1F1;     --new-fg:#12395A;
  --repeat-bg:#F4DCA9;  --repeat-fg:#6B4509;
  --stick-pink:#F6D8E4;
  --hatch: repeating-linear-gradient(-45deg, transparent 0 3px, rgba(26,36,32,.20) 3px 5px);
}

*,*::before,*::after{ box-sizing: border-box; }
html{ -webkit-text-size-adjust:100%; }
@media (prefers-reduced-motion: no-preference){ html{ scroll-behavior:smooth; } }
body{
  margin:0;
  background:
    linear-gradient(var(--bg-line) 1px, transparent 1px) 0 0/100% 28px,
    var(--bg);
  color:var(--ink);
  font-family: var(--font-body);
  font-size:16px;
  line-height:1.55;
}
h1,h2,h3,h4{ font-family: var(--font-display); font-weight:700; text-wrap:balance; margin:0; color:var(--ink); }
p{ margin:0; }
a{ color:var(--accent); }
a:focus-visible, button:focus-visible, .cell:focus-visible, .box:focus-visible{
  outline: 2px solid var(--accent); outline-offset: 2px;
}
.font-mono, .tabnum{ font-variant-numeric: tabular-nums; }

/* ---------- Top bar ---------- */
.topbar{
  position: sticky; top:0; z-index:50;
  display:flex; align-items:center; justify-content:space-between; gap:1rem;
  padding:.6rem 1.25rem;
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  backdrop-filter: blur(6px);
  border-bottom:1px solid var(--border);
  flex-wrap:wrap;
}
.topbar .brand{ font-family:var(--font-display); font-weight:700; font-size:1rem; white-space:nowrap; text-decoration:none; color:var(--ink); }
.legend{ display:flex; gap:.5rem; flex-wrap:wrap; align-items:center; }
.legend-chip{
  display:flex; align-items:center; gap:.4rem;
  font-size:.72rem; padding:.22rem .55rem .22rem .4rem;
  border-radius:999px; border:1px solid var(--border);
  background:var(--surface-2); color:var(--ink-muted);
  white-space:nowrap;
}
.legend-chip i{ width:.6rem; height:.6rem; border-radius:2px; display:inline-block; }
.legend-chip.lc-future i{ background:var(--future-bg); border:1px solid var(--future-fg); }
.legend-chip.lc-already i{ background:var(--already-bg); }
.legend-chip.lc-new i{ background:var(--new-bg); }
.legend-chip.lc-repeat i{ background:var(--repeat-bg); }
.legend-chip.lc-comm i{ background-color:var(--already-bg); background-image:var(--hatch); }
.motion-toggle{ display:flex; align-items:center; gap:.4rem; font-size:.72rem; padding:.22rem .6rem; border-radius:999px; border:1px solid var(--border); background:var(--surface-2); color:var(--ink-muted); cursor:pointer; white-space:nowrap; }
.motion-toggle:hover{ border-color:var(--accent); color:var(--ink); }
.motion-toggle[aria-pressed="true"]{ background:var(--accent-soft); border-color:var(--accent); color:var(--accent); font-weight:700; }

/* ---------- Shell / layout ---------- */
.shell{ max-width:1320px; margin:0 auto; display:grid; grid-template-columns: 210px minmax(0,1fr); gap:2.5rem; padding: 0 1.25rem; }
@media (max-width: 860px){ .shell{ grid-template-columns: 1fr; } }

.rail{ position:sticky; top:3.2rem; align-self:start; padding:1.5rem 0; max-height: calc(100vh - 3.2rem); overflow:auto; }
@media (max-width:860px){
  .rail{ position:static; max-height:none; padding:.75rem 0; overflow-x:auto; }
  .rail ol{ display:flex !important; gap:.4rem; }
  .rail li{ flex:0 0 auto; }
}
.rail h4{ font-size:.7rem; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-muted); margin-bottom:.6rem; font-family:var(--font-body); font-weight:700; }
.rail ol{ list-style:none; margin:0 0 1.5rem 0; padding:0; display:flex; flex-direction:column; gap:.15rem; }
.rail a{ display:block; padding:.3rem .5rem; border-radius:var(--radius-s); text-decoration:none; color:var(--ink-muted); font-size:.86rem; border-left:2px solid transparent; }
.rail a:hover{ color:var(--ink); background:var(--surface-2); }
.rail a.active{ color:var(--ink); background:var(--surface-2); border-left-color:var(--accent); font-weight:700; }
.rail a b{ font-family:var(--font-mono); color:var(--ink-muted); margin-right:.4rem; }
.rail a.active b{ color:var(--accent); }

main{ min-width:0; padding: 2.5rem 0 4rem; }
.prose{ max-width:680px; }
.wide{ max-width:1080px; }

/* ---------- Hero ---------- */
.hero{ max-width:720px; margin-bottom:3rem; }
.hero .eyebrow{ font-family:var(--font-mono); font-size:.78rem; letter-spacing:.08em; text-transform:uppercase; color:var(--accent); margin-bottom:.6rem; display:block; }
.hero h1{ font-size:2.15rem; line-height:1.15; margin-bottom:.9rem; }
.hero .thesis{ font-size:1.05rem; color:var(--ink-muted); max-width:56ch; }
.stats-row{ display:flex; gap:0; margin-top:1.75rem; border:1px solid var(--border); border-radius:var(--radius-m); overflow:hidden; background:var(--surface); }
.stat{ flex:1; padding:.9rem 1rem; border-right:1px solid var(--border); }
.stat:last-child{ border-right:none; }
.stat .n{ font-family:var(--font-mono); font-size:1.5rem; font-weight:700; color:var(--ink); display:block; }
.stat .l{ font-size:.76rem; color:var(--ink-muted); margin-top:.15rem; display:block; }

/* ---------- Section shells ---------- */
section.block{ margin-bottom:3.5rem; scroll-margin-top:4rem; }
section.block > h2{ font-size:1.05rem; letter-spacing:.02em; color:var(--ink-muted); text-transform:uppercase; font-family:var(--font-body); font-weight:700; margin-bottom:1rem; }

/* ---------- Overview grid ---------- */
.ov-wrap{ display:flex; gap:2rem; flex-wrap:wrap; align-items:flex-start; }
.ov-grid{ display:grid; grid-template-columns: repeat(11, 30px); grid-auto-rows:30px; gap:2px; }
.ov-cell{ display:flex; align-items:center; justify-content:center; font-family:var(--font-mono); font-size:.68rem; border-radius:3px; background:var(--future-bg); color:var(--future-fg); cursor:pointer; border:none; padding:0; transition:transform .15s ease; }
.ov-cell.head{ background:transparent; color:var(--ink-muted); font-weight:700; cursor:default; }
.ov-cell.learned{ background:var(--already-bg); color:var(--already-fg); font-weight:700; }
.ov-cell.pulse{ animation: pulse .9s ease; }
.ov-note{ max-width:340px; font-size:.9rem; color:var(--ink-muted); }
.ov-note strong{ color:var(--ink); }

/* ---------- Videos ---------- */
.video-grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(320px,1fr)); gap:1.5rem; }
.video-card{ margin:0; }
.video-embed{ position:relative; aspect-ratio:16/9; border-radius:var(--radius-m); overflow:hidden; border:1px solid var(--border); background:var(--surface-2); }
.video-embed iframe{ position:absolute; inset:0; width:100%; height:100%; border:0; }
.video-card figcaption{ margin-top:.5rem; font-size:.85rem; color:var(--ink-muted); }
.video-link-card{ display:flex; align-items:center; gap:1rem; border:1px solid var(--border); border-radius:var(--radius-m); background:var(--surface); padding:1rem 1.2rem; text-decoration:none; color:inherit; transition:border-color .15s ease, transform .15s ease; }
.video-link-card:hover{ border-color:var(--accent); transform:translateY(-2px); }
.play-badge{ flex:0 0 auto; width:2.6rem; height:2.6rem; border-radius:50%; background:var(--accent-soft); color:var(--accent); display:flex; align-items:center; justify-content:center; font-size:1rem; }
.vlabel{ font-size:.92rem; color:var(--ink); }
.vlabel small{ display:block; color:var(--ink-muted); font-size:.78rem; margin-top:.15rem; }

/* ---------- Sequence cards (index) ---------- */
.seq-cards{ display:grid; grid-template-columns:repeat(auto-fill,minmax(250px,1fr)); gap:1rem; }
.seq-card{ border:1px solid var(--border); border-radius:var(--radius-m); background:var(--surface); padding:1.1rem 1.2rem; text-decoration:none; color:inherit; display:flex; flex-direction:column; gap:.45rem; transition: border-color .15s ease, transform .15s ease; }
.seq-card:hover{ border-color:var(--accent); transform:translateY(-2px); }
.seq-card .k{ font-family:var(--font-mono); color:var(--accent); font-size:.78rem; }
.seq-card h3{ font-size:1.02rem; font-family:var(--font-body); font-weight:700; }
.seq-card p{ font-size:.83rem; color:var(--ink-muted); line-height:1.45; }
.seq-card .chips{ display:flex; gap:.4rem; margin-top:.15rem; }

/* ---------- Sequence page header ---------- */
.seq-stats-inline{ display:flex; gap:.5rem; margin-top:1rem; }

table.seances{ width:100%; border-collapse:collapse; font-size:.9rem; }
table.seances th{ text-align:left; font-size:.72rem; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-muted); font-weight:700; padding:.4rem .6rem; border-bottom:1px solid var(--border); }
table.seances td{ padding:.55rem .6rem; border-bottom:1px solid var(--border); vertical-align:top; }
table.seances tr:last-child td{ border-bottom:none; }
table.seances td.n{ font-family:var(--font-mono); color:var(--ink-muted); width:2.2rem; }
table.seances td.note{ color:var(--ink-muted); font-size:.85rem; width:34%; }

h3.section-label{ font-size:.95rem; margin-bottom:.75rem; }

/* ---------- Diagrams: the number stick ---------- */
/* A single graduated stick per table (Jill Mansergh's "number stick" /
   counting-stick method): 0 at the left, ×10 at the right, the "nose"
   (×5, half of ×10) marked at the centre, and a jump-arc showing the
   decomposition the séquence is teaching. Same 4-colour state language
   as the Pythagoras grid, just worn by dots instead of cells. */
.diagrams{ display:flex; flex-direction:column; gap:1.5rem; }
figure.diagram{ margin:0; }
figure.diagram svg{ display:block; max-width:100%; height:auto; }
figure.diagram-stick{ width:100%; }
figure.diagram-stick svg{ width:100%; }
figure.diagram-compact{ align-self:flex-start; }
figure.diagram figcaption{ margin-top:.5rem; font-size:.85rem; color:var(--ink-muted); font-family:var(--font-mono); }
.tick{ font-size:9px; fill:var(--ink-muted); font-family:var(--font-mono); }
.tone-a{ fill:var(--accent); stroke:var(--surface); stroke-width:1.5; }
.toolbox-note{ font-size:.88rem; color:var(--ink-muted); max-width:60ch; }

/* The 10 cases: a static, neutral reference row, one position per case —
   big and physical, like a real counting stick. All ten are the same
   colour; colour is spent entirely on the animated ring below, so it
   reads as "here's the manipulation happening" rather than being spread
   thin across every case. The position (×1…×10) is always printed on
   the case itself; the result gets stamped on top of it once that fact
   has actually come up. */
.stick-box{ stroke-width:3.5; stroke:var(--border); }
.stick-box.alt-a{ fill:var(--surface); }
.stick-box.alt-b{ fill:var(--stick-pink); }
.stick-box-label{ font-family:var(--font-mono); font-weight:800; font-size:40px; text-anchor:middle; dominant-baseline:central; fill:var(--ink); }
.stick-idx2{ font-family:var(--font-mono); font-weight:700; font-size:26px; fill:var(--ink-muted); text-anchor:middle; dominant-baseline:central; }
.stick-nose{ stroke:var(--ink-muted); stroke-width:1.5; stroke-dasharray:3 3; }
.stick-nose-label{ font-family:var(--font-body); font-size:13px; fill:var(--ink-muted); font-style:italic; text-anchor:middle; }

/* The manipulation itself: a ring growing/shrinking over the first k
   cases, one stage at a time, in a loop — this is what "stands out".
   Coloration pleine plutôt que contour, même principe que la coloration
   des états sur le quadrillage (Pythagore) et la liste des tables. */
.stick-ring{ fill:var(--future-bg); stroke:none; }
.stick-ring.state-already{ fill:var(--already-bg); }
.stick-ring.state-new{ fill:var(--new-bg); }
.stick-stage-label{ font-family:var(--font-body); font-weight:800; font-size:20px; text-anchor:middle; fill:var(--future-fg); }
.stick-stage-label.state-already{ fill:var(--already-fg); }
.stick-stage-label.state-new{ fill:var(--new-fg); }
.stick-brace{ stroke:var(--ink-muted); stroke-width:1.75; fill:none; }
.stick-brace-label{ font-family:var(--font-body); font-weight:800; font-size:23px; text-anchor:middle; fill:var(--future-fg); }
.stick-brace-label.state-already{ fill:var(--already-fg); }
.stick-brace-label.state-new{ fill:var(--new-fg); }

/* ---------- Diagram build/loop animation ---------- */
/* Static, correct end-state by default: every unit fully visible, no motion.
   This is also the complete picture shown under prefers-reduced-motion. */
figure.diagram .unit{ opacity:1; }
figure.diagram figcaption{ transition:none; }

@media (prefers-reduced-motion: no-preference){
  figure.diagram .unit{ transform-box: fill-box; transform-origin: center; }
  figure.diagram figcaption{ animation: cap-emph var(--dur,5.6s) ease-in-out infinite; }
  @keyframes cap-emph{
    0%,60%  { color:var(--ink-muted); font-weight:400; }
    68%     { color:var(--accent); font-weight:700; }
    82%     { color:var(--accent); font-weight:700; }
    92%,100%{ color:var(--ink-muted); font-weight:400; }
  }
}
:root[data-force-motion="on"] figure.diagram figcaption{ animation: cap-emph var(--dur,5.6s) ease-in-out infinite; }

/* Twelve evenly-spread entrance steps, shared timeline so every diagram
   (however many units it has) still holds together and fades together. */
@keyframes stagger-pop-0  { 0%,4%{opacity:0;transform:scale(.5);}  10%{opacity:1;transform:scale(1);} 82%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.5);} }
@keyframes stagger-pop-1  { 0%,8.5%{opacity:0;transform:scale(.5);} 14.5%{opacity:1;transform:scale(1);} 82%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.5);} }
@keyframes stagger-pop-2  { 0%,13%{opacity:0;transform:scale(.5);} 19%{opacity:1;transform:scale(1);} 82%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.5);} }
@keyframes stagger-pop-3  { 0%,17.5%{opacity:0;transform:scale(.5);} 23.5%{opacity:1;transform:scale(1);} 82%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.5);} }
@keyframes stagger-pop-4  { 0%,22%{opacity:0;transform:scale(.5);} 28%{opacity:1;transform:scale(1);} 82%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.5);} }
@keyframes stagger-pop-5  { 0%,26.5%{opacity:0;transform:scale(.5);} 32.5%{opacity:1;transform:scale(1);} 82%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.5);} }
@keyframes stagger-pop-6  { 0%,31%{opacity:0;transform:scale(.5);} 37%{opacity:1;transform:scale(1);} 82%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.5);} }
@keyframes stagger-pop-7  { 0%,35.5%{opacity:0;transform:scale(.5);} 41.5%{opacity:1;transform:scale(1);} 82%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.5);} }
@keyframes stagger-pop-8  { 0%,40%{opacity:0;transform:scale(.5);} 46%{opacity:1;transform:scale(1);} 82%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.5);} }
@keyframes stagger-pop-9  { 0%,44.5%{opacity:0;transform:scale(.5);} 50.5%{opacity:1;transform:scale(1);} 82%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.5);} }
@keyframes stagger-pop-10 { 0%,49%{opacity:0;transform:scale(.5);} 55%{opacity:1;transform:scale(1);} 82%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.5);} }
@keyframes stagger-pop-11 { 0%,53.5%{opacity:0;transform:scale(.5);} 59.5%{opacity:1;transform:scale(1);} 82%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.5);} }
@keyframes stagger-pop-12 { 0%,58%{opacity:0;transform:scale(.5);} 64%{opacity:1;transform:scale(1);} 82%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.5);} }
@keyframes stagger-pop-13 { 0%,62.5%{opacity:0;transform:scale(.5);} 68.5%{opacity:1;transform:scale(1);} 82%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.5);} }
@media (prefers-reduced-motion: no-preference){
  .stagger-0{ animation: stagger-pop-0 var(--dur,5.6s) ease-in-out infinite; }
  .stagger-1{ animation: stagger-pop-1 var(--dur,5.6s) ease-in-out infinite; }
  .stagger-2{ animation: stagger-pop-2 var(--dur,5.6s) ease-in-out infinite; }
  .stagger-3{ animation: stagger-pop-3 var(--dur,5.6s) ease-in-out infinite; }
  .stagger-4{ animation: stagger-pop-4 var(--dur,5.6s) ease-in-out infinite; }
  .stagger-5{ animation: stagger-pop-5 var(--dur,5.6s) ease-in-out infinite; }
  .stagger-6{ animation: stagger-pop-6 var(--dur,5.6s) ease-in-out infinite; }
  .stagger-7{ animation: stagger-pop-7 var(--dur,5.6s) ease-in-out infinite; }
  .stagger-8{ animation: stagger-pop-8 var(--dur,5.6s) ease-in-out infinite; }
  .stagger-9{ animation: stagger-pop-9 var(--dur,5.6s) ease-in-out infinite; }
  .stagger-10{ animation: stagger-pop-10 var(--dur,5.6s) ease-in-out infinite; }
  .stagger-11{ animation: stagger-pop-11 var(--dur,5.6s) ease-in-out infinite; }
  .stagger-12{ animation: stagger-pop-12 var(--dur,5.6s) ease-in-out infinite; }
  .stagger-13{ animation: stagger-pop-13 var(--dur,5.6s) ease-in-out infinite; }
}
:root[data-force-motion="on"] .stagger-0{ animation: stagger-pop-0 var(--dur,5.6s) ease-in-out infinite; }
:root[data-force-motion="on"] .stagger-1{ animation: stagger-pop-1 var(--dur,5.6s) ease-in-out infinite; }
:root[data-force-motion="on"] .stagger-2{ animation: stagger-pop-2 var(--dur,5.6s) ease-in-out infinite; }
:root[data-force-motion="on"] .stagger-3{ animation: stagger-pop-3 var(--dur,5.6s) ease-in-out infinite; }
:root[data-force-motion="on"] .stagger-4{ animation: stagger-pop-4 var(--dur,5.6s) ease-in-out infinite; }
:root[data-force-motion="on"] .stagger-5{ animation: stagger-pop-5 var(--dur,5.6s) ease-in-out infinite; }
:root[data-force-motion="on"] .stagger-6{ animation: stagger-pop-6 var(--dur,5.6s) ease-in-out infinite; }
:root[data-force-motion="on"] .stagger-7{ animation: stagger-pop-7 var(--dur,5.6s) ease-in-out infinite; }
:root[data-force-motion="on"] .stagger-8{ animation: stagger-pop-8 var(--dur,5.6s) ease-in-out infinite; }
:root[data-force-motion="on"] .stagger-9{ animation: stagger-pop-9 var(--dur,5.6s) ease-in-out infinite; }
:root[data-force-motion="on"] .stagger-10{ animation: stagger-pop-10 var(--dur,5.6s) ease-in-out infinite; }
:root[data-force-motion="on"] .stagger-11{ animation: stagger-pop-11 var(--dur,5.6s) ease-in-out infinite; }
:root[data-force-motion="on"] .stagger-12{ animation: stagger-pop-12 var(--dur,5.6s) ease-in-out infinite; }
:root[data-force-motion="on"] .stagger-13{ animation: stagger-pop-13 var(--dur,5.6s) ease-in-out infinite; }
:root[data-force-motion="on"] figure.diagram .unit{ transform-box: fill-box; transform-origin: center; }

/* Stage-by-stage manipulation: one ring+equation visible at a time, in
   a loop — 1, 2, 3 or 4 stages depending on the strategy. Under reduced
   motion, only the first stage shows, statically, as one worked example. */
.stage-fx{ opacity:0; transform-box: fill-box; transform-origin: center; }
.stage1-a, .stage2-a, .stage3-a, .stage4-a{ opacity:1; }
/* Case reveals synced to the stage that first shows them: pop in at the
   same moment as that stage's ring, then — unlike the ring — hold all
   the way to the end of the loop instead of fading with it, so results
   accumulate on the stick (6, then 12, then 24) instead of flickering. */
@keyframes box2-a{ 0%,8%{opacity:0;transform:scale(.8);} 14%{opacity:1;transform:scale(1);} 88%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.8);} }
@keyframes box3-a{ 0%,6%{opacity:0;transform:scale(.8);} 11%{opacity:1;transform:scale(1);} 89%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.8);} }
@keyframes box3-b{ 0%,37%{opacity:0;transform:scale(.8);} 42%{opacity:1;transform:scale(1);} 89%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.8);} }
@keyframes box4-a{ 0%,4%{opacity:0;transform:scale(.8);} 8%{opacity:1;transform:scale(1);} 96%{opacity:1;transform:scale(1);} 100%{opacity:0;transform:scale(.8);} }
@keyframes box4-b{ 0%,29%{opacity:0;transform:scale(.8);} 33%{opacity:1;transform:scale(1);} 96%{opacity:1;transform:scale(1);} 100%{opacity:0;transform:scale(.8);} }
@keyframes box4-c{ 0%,54%{opacity:0;transform:scale(.8);} 58%{opacity:1;transform:scale(1);} 96%{opacity:1;transform:scale(1);} 100%{opacity:0;transform:scale(.8);} }
@media (prefers-reduced-motion: no-preference){
  .box2-a{ animation: box2-a var(--dur,8s) ease-in-out infinite; }
  .box3-a{ animation: box3-a var(--dur,8s) ease-in-out infinite; }
  .box3-b{ animation: box3-b var(--dur,8s) ease-in-out infinite; }
  .box4-a{ animation: box4-a var(--dur,8s) ease-in-out infinite; }
  .box4-b{ animation: box4-b var(--dur,8s) ease-in-out infinite; }
  .box4-c{ animation: box4-c var(--dur,8s) ease-in-out infinite; }
}
:root[data-force-motion="on"] .box2-a{ animation: box2-a var(--dur,8s) ease-in-out infinite; }
:root[data-force-motion="on"] .box3-a{ animation: box3-a var(--dur,8s) ease-in-out infinite; }
:root[data-force-motion="on"] .box3-b{ animation: box3-b var(--dur,8s) ease-in-out infinite; }
:root[data-force-motion="on"] .box4-a{ animation: box4-a var(--dur,8s) ease-in-out infinite; }
:root[data-force-motion="on"] .box4-b{ animation: box4-b var(--dur,8s) ease-in-out infinite; }
:root[data-force-motion="on"] .box4-c{ animation: box4-c var(--dur,8s) ease-in-out infinite; }
@keyframes stage1-a{ 0%,8%{opacity:0;transform:scale(.92);} 16%{opacity:1;transform:scale(1);} 84%{opacity:1;transform:scale(1);} 92%,100%{opacity:0;transform:scale(.92);} }
@keyframes stage2-a{ 0%,8%{opacity:0;transform:scale(.92);} 14%{opacity:1;transform:scale(1);} 42%{opacity:1;transform:scale(1);} 48%,100%{opacity:0;transform:scale(.92);} }
@keyframes stage2-b{ 0%,54%{opacity:0;transform:scale(.92);} 60%{opacity:1;transform:scale(1);} 88%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.92);} }
@keyframes stage3-a{ 0%,6%{opacity:0;transform:scale(.92);} 11%{opacity:1;transform:scale(1);} 27%{opacity:1;transform:scale(1);} 32%,100%{opacity:0;transform:scale(.92);} }
@keyframes stage3-b{ 0%,37%{opacity:0;transform:scale(.92);} 42%{opacity:1;transform:scale(1);} 58%{opacity:1;transform:scale(1);} 63%,100%{opacity:0;transform:scale(.92);} }
@keyframes stage3-c{ 0%,68%{opacity:0;transform:scale(.92);} 73%{opacity:1;transform:scale(1);} 89%{opacity:1;transform:scale(1);} 94%,100%{opacity:0;transform:scale(.92);} }
@keyframes stage4-a{ 0%,4%{opacity:0;transform:scale(.92);} 8%{opacity:1;transform:scale(1);} 21%{opacity:1;transform:scale(1);} 25%,100%{opacity:0;transform:scale(.92);} }
@keyframes stage4-b{ 0%,29%{opacity:0;transform:scale(.92);} 33%{opacity:1;transform:scale(1);} 46%{opacity:1;transform:scale(1);} 50%,100%{opacity:0;transform:scale(.92);} }
@keyframes stage4-c{ 0%,54%{opacity:0;transform:scale(.92);} 58%{opacity:1;transform:scale(1);} 71%{opacity:1;transform:scale(1);} 75%,100%{opacity:0;transform:scale(.92);} }
@keyframes stage4-d{ 0%,79%{opacity:0;transform:scale(.92);} 83%{opacity:1;transform:scale(1);} 96%{opacity:1;transform:scale(1);} 100%,100%{opacity:0;transform:scale(.92);} }
@media (prefers-reduced-motion: no-preference){
  .stage1-a{ animation: stage1-a var(--dur,8s) ease-in-out infinite; }
  .stage2-a{ animation: stage2-a var(--dur,8s) ease-in-out infinite; }
  .stage2-b{ animation: stage2-b var(--dur,8s) ease-in-out infinite; }
  .stage3-a{ animation: stage3-a var(--dur,8s) ease-in-out infinite; }
  .stage3-b{ animation: stage3-b var(--dur,8s) ease-in-out infinite; }
  .stage3-c{ animation: stage3-c var(--dur,8s) ease-in-out infinite; }
  .stage4-a{ animation: stage4-a var(--dur,8s) ease-in-out infinite; }
  .stage4-b{ animation: stage4-b var(--dur,8s) ease-in-out infinite; }
  .stage4-c{ animation: stage4-c var(--dur,8s) ease-in-out infinite; }
  .stage4-d{ animation: stage4-d var(--dur,8s) ease-in-out infinite; }
}
:root[data-force-motion="on"] .stage1-a{ animation: stage1-a var(--dur,8s) ease-in-out infinite; }
:root[data-force-motion="on"] .stage2-a{ animation: stage2-a var(--dur,8s) ease-in-out infinite; }
:root[data-force-motion="on"] .stage2-b{ animation: stage2-b var(--dur,8s) ease-in-out infinite; }
:root[data-force-motion="on"] .stage3-a{ animation: stage3-a var(--dur,8s) ease-in-out infinite; }
:root[data-force-motion="on"] .stage3-b{ animation: stage3-b var(--dur,8s) ease-in-out infinite; }
:root[data-force-motion="on"] .stage3-c{ animation: stage3-c var(--dur,8s) ease-in-out infinite; }
:root[data-force-motion="on"] .stage4-a{ animation: stage4-a var(--dur,8s) ease-in-out infinite; }
:root[data-force-motion="on"] .stage4-b{ animation: stage4-b var(--dur,8s) ease-in-out infinite; }
:root[data-force-motion="on"] .stage4-c{ animation: stage4-c var(--dur,8s) ease-in-out infinite; }
:root[data-force-motion="on"] .stage4-d{ animation: stage4-d var(--dur,8s) ease-in-out infinite; }

/* ---------- Calc objectives: dual view ---------- */
.calc-objectives h3{ font-size:.95rem; margin-bottom:.75rem; }
.dual{ display:grid; grid-template-columns: 1fr 1fr; gap:1.75rem; align-items:start; }
@media (max-width:760px){ .dual{ grid-template-columns:1fr; } }
.panel h4{ font-size:.78rem; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-muted); font-family:var(--font-body); font-weight:700; margin-bottom:.6rem; }
.panel-scroll{ overflow-x:auto; padding-bottom:.25rem; }

.pytha-grid{ display:grid; grid-template-columns: repeat(11, 36px); grid-auto-rows:36px; gap:3px; width:max-content; }
.cell{ display:flex; align-items:center; justify-content:center; font-family:var(--font-mono); font-size:.82rem; border-radius:4px; cursor:pointer; border:none; padding:0; background:var(--future-bg); color:var(--future-fg); transition: transform .15s ease; }
.cell.head{ background:transparent; color:var(--ink-muted); cursor:default; font-weight:700; }
.cell.head.touched{ color:var(--accent); font-weight:700; }
.cell.diag{ box-shadow: inset 0 0 0 1px var(--border); }
.cell.state-already{ background:var(--already-bg); color:var(--already-fg); }
.cell.state-new{ background:var(--new-bg); color:var(--new-fg); font-weight:700; }
.cell.state-repeat{ background:var(--repeat-bg); color:var(--repeat-fg); font-weight:700; }
.cell.static{ cursor:default; }
/* Après les règles d'état : elles posent `background` en raccourci, qui
   effacerait les hachures si celles-ci étaient déclarées avant. */
.cell.comm{ background-image:var(--hatch); }
.cell.pulse{ animation: pulse .9s ease; }
@media (prefers-reduced-motion: reduce){ .cell.pulse, .ov-cell.pulse{ animation:none; outline:2px solid var(--accent); } }
@keyframes pulse{ 0%{ transform:scale(1); } 30%{ transform:scale(1.28); box-shadow:0 0 0 3px var(--accent); } 100%{ transform:scale(1); } }
.grid-note{ margin-top:.6rem; font-size:.8rem; color:var(--ink-muted); min-height:1.2em; }
.grid-note strong{ color:var(--ink); }

/* Liste des tables — format "affiche" : une carte par table, faits écrits en entier */
.liste{ display:grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap:.6rem; }
.table-card{ background:var(--surface); border:1px solid var(--border); border-radius:var(--radius-m); padding:.45rem .4rem .5rem; }
.table-card.touched{ border-color:var(--accent); background:var(--accent-soft); }
.table-card-head{ display:flex; align-items:center; gap:.3rem; margin-bottom:.35rem; padding-left:.15rem; min-height:1.7rem; }
.table-badge{ width:1.7rem; height:1.7rem; flex:0 0 auto; border-radius:50%; display:flex; align-items:center; justify-content:center; background:var(--future-bg); color:var(--future-fg); font-family:var(--font-mono); font-size:.82rem; font-weight:700; }
.table-card.touched .table-badge{ background:var(--accent); color:var(--surface); }
.liste-tag{ font-size:.6rem; text-transform:uppercase; letter-spacing:.04em; background:var(--accent); color:var(--surface); border-radius:999px; padding:.08rem .4rem; font-weight:700; }
.table-lines{ list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:2px; }
.table-line{ display:flex; align-items:center; gap:.28rem; padding:.14rem .32rem; border-radius:3px; font-family:var(--font-mono); font-size:.72rem; background:var(--future-bg); color:var(--future-fg); }
.tl-op{ flex:1 1 auto; text-align:right; }
.tl-sign{ flex:0 0 auto; opacity:.7; }
.tl-res{ flex:0 0 auto; min-width:2.3em; text-align:left; }
.table-line.state-already{ background:var(--already-bg); color:var(--already-fg); }
.table-line.state-new{ background:var(--new-bg); color:var(--new-fg); font-weight:700; }
.table-line.state-repeat{ background:var(--repeat-bg); color:var(--repeat-fg); font-weight:700; }
.table-line.comm{ background-image:var(--hatch); }
.empty-note{ font-size:.88rem; color:var(--ink-muted); font-style:italic; }

/* ---------- Carrousel d'intro : les dix états successifs des deux vues ---------- */
.carousel{ border:1px solid var(--border); border-radius:var(--radius-m); background:var(--surface); padding:1rem 1.1rem 1.1rem; }
.carousel-viewport{ overflow:hidden; }
.carousel-track{ display:flex; transition: transform .55s cubic-bezier(.4,0,.2,1); }
@media (prefers-reduced-motion: reduce){
  :root:not([data-force-motion="on"]) .carousel-track{ transition:none; }
}
.carousel-slide{ flex:0 0 100%; min-width:0; }
.carousel-caption{ display:flex; align-items:baseline; gap:.7rem; flex-wrap:wrap; margin-bottom:.9rem; min-height:2rem; }
.carousel-step{ font-family:var(--font-mono); font-size:.72rem; letter-spacing:.06em; text-transform:uppercase; color:var(--accent); font-weight:700; }
.carousel-caption h3{ margin:0; font-size:1.05rem; font-family:var(--font-display); font-weight:400; }
.carousel-views{ display:grid; grid-template-columns: 1fr auto; gap:1.5rem; align-items:start; }
.carousel-view h4{ font-size:.72rem; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-muted); font-weight:700; margin:0 0 .5rem; }
/* Séparateur entre les deux vues : le trait est centré dans le gap plutôt
   que collé à la deuxième vue (marge négative = moitié du gap, compensée
   par un padding égal, pour ne pas déplacer le contenu). */
.carousel-view + .carousel-view{ border-left:1px solid var(--ink-muted); margin-left:-.75rem; padding-left:.75rem; }
/* Les deux vues en entier, d'un coup d'œil : plus compactes que sur une page de séquence. */
.carousel .liste{ grid-template-columns: repeat(5, minmax(0,1fr)); gap:.45rem; }
.carousel .table-card{ padding:.35rem .3rem .4rem; }
.carousel .table-card-head{ margin-bottom:.25rem; min-height:1.35rem; }
.carousel .table-badge{ width:1.35rem; height:1.35rem; font-size:.7rem; }
.carousel .liste-tag{ font-size:.5rem; padding:.05rem .3rem; }
.carousel .table-line{ font-size:.6rem; padding:.08rem .25rem; gap:.2rem; }
.carousel .tl-res{ min-width:2.1em; }
.carousel .pytha-grid{ grid-template-columns: repeat(11, 26px); grid-auto-rows:26px; gap:2px; }
.carousel .cell{ font-size:.62rem; border-radius:3px; }
.carousel-controls{ display:flex; align-items:center; gap:.6rem; margin-bottom:1rem; padding-bottom:.85rem; border-bottom:1px solid var(--border); flex-wrap:wrap; }
.carousel-center{ flex:1 1 auto; min-width:0; display:flex; flex-direction:row; flex-wrap:wrap; align-items:center; justify-content:center; gap:.7rem; }
.carousel-arrow{ width:1.9rem; height:1.9rem; flex:0 0 auto; border:1px solid var(--border); border-radius:50%; background:var(--surface); color:var(--ink); font-size:1rem; line-height:1; cursor:pointer; }
.carousel-arrow:hover{ border-color:var(--accent); color:var(--accent); }
.carousel-dots{ display:flex; gap:.3rem; }
.carousel-dot{ width:.55rem; height:.55rem; padding:0; border:none; border-radius:50%; background:var(--future-bg); cursor:pointer; transition:background .2s ease, transform .2s ease; }
.carousel-dot:hover{ background:var(--accent-2); }
.carousel-dot.on{ background:var(--accent); transform:scale(1.25); }
.carousel-play{ flex:0 0 auto; font:inherit; font-size:.74rem; padding:.25rem .7rem; border:1px solid var(--border); border-radius:999px; background:var(--surface); color:var(--ink-muted); cursor:pointer; }
.carousel-play:hover{ border-color:var(--accent); color:var(--accent); }
@media (max-width:900px){
  .carousel-views{ grid-template-columns:1fr; }
  .carousel .liste{ grid-template-columns: repeat(auto-fill, minmax(104px,1fr)); }
  .carousel-view + .carousel-view{ border-left:none; border-top:1px solid var(--ink-muted); margin-left:0; padding-left:0; margin-top:-.75rem; padding-top:1.5rem; }
}

/* ---------- Training / spaced-review panel ---------- */
.training-panel{ border:1px solid var(--border); border-radius:var(--radius-m); background:var(--surface-2); padding:1.25rem 1.5rem; display:flex; flex-direction:column; gap:.9rem; }
.training-panel h3{ font-size:.95rem; }
.training-activity{ font-size:.9rem; }
.training-activity b{ color:var(--accent); }
.chip-group{ display:flex; flex-direction:column; gap:.35rem; }
.chip-group-label{ font-size:.7rem; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-muted); }
.chip-row{ display:flex; flex-wrap:wrap; gap:.4rem; }
.fact-chip{ font-family:var(--font-mono); font-size:.74rem; padding:.25rem .55rem; border-radius:999px; background:var(--surface); border:1px solid var(--border); }
.fact-chip.spaced{ border-color:var(--repeat-fg); color:var(--repeat-fg); background:var(--repeat-bg); }
.fact-chip.today{ border-color:var(--new-fg); color:var(--new-fg); background:var(--new-bg); }

/* ---------- Page nav (prev/next) ---------- */
.pagenav{ display:flex; justify-content:space-between; gap:1rem; margin-top:3rem; padding-top:1.5rem; border-top:1px solid var(--border); }
.pagenav a{ flex:1; padding:.9rem 1.1rem; border:1px solid var(--border); border-radius:var(--radius-m); text-decoration:none; color:var(--ink); background:var(--surface); max-width:48%; }
.pagenav a:hover{ border-color:var(--accent); }
.pagenav a.next{ text-align:right; }
.pagenav .lbl{ display:block; font-size:.7rem; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-muted); margin-bottom:.2rem; }

/* ---------- Recap ---------- */
section.recap{ max-width:960px; }
section.recap h2{ font-size:1.4rem; margin-bottom:.4rem; }
section.recap > p{ color:var(--ink-muted); margin-bottom:1.25rem; max-width:60ch; }
table.recap-table{ width:100%; border-collapse:collapse; font-size:.88rem; }
table.recap-table th, table.recap-table td{ padding:.5rem .7rem; border-bottom:1px solid var(--border); text-align:left; }
table.recap-table th{ font-size:.7rem; text-transform:uppercase; letter-spacing:.05em; color:var(--ink-muted); }
table.recap-table td.num{ font-family:var(--font-mono); text-align:right; }
table.recap-table td a{ color:var(--ink); text-decoration:none; }
table.recap-table td a:hover{ color:var(--accent); }
table.recap-table tfoot td{ font-weight:700; border-top:2px solid var(--border); border-bottom:none; }
.closing{ margin-top:2rem; font-size:.92rem; color:var(--ink-muted); max-width:62ch; }
