/* ───────────────────────────────────────────────────────────────
   THE STUDY STAGE
   Full screen, one idea per beat. The reaction assembles itself:
   substrate, then catalyst, then what it costs, then what it makes.
   ─────────────────────────────────────────────────────────────── */

.study{
  position:fixed; inset:0; z-index:70;
  display:flex; flex-direction:column;
  background:var(--paper); color:var(--ink);
  opacity:0; visibility:hidden; transform:scale(.985); pointer-events:none;
  transition:opacity .36s var(--ease), transform .36s var(--ease), visibility .36s;
}
body.study-on .study{ opacity:1; visibility:visible; transform:none; pointer-events:auto }
body.study-on .rail,body.study-on .chest,body.study-on .strip{ pointer-events:none }

/* faint ruled paper, so the stage still reads as part of the chart */
.study::before{
  content:''; position:absolute; inset:0; pointer-events:none; opacity:.5;
  background-image:linear-gradient(var(--paper-line) 1px,transparent 1px),
                   linear-gradient(90deg,var(--paper-line) 1px,transparent 1px);
  background-size:56px 56px;
  mask-image:radial-gradient(ellipse at center,#000 15%,transparent 72%);
}

/* ── top bar ─────────────────────────────────────────────────── */
.st-bar{
  position:relative; z-index:3; flex:none;
  display:flex; align-items:center; gap:14px; padding:12px 20px 11px;
  border-bottom:1px solid var(--paper-line); background:var(--paper);
}
.st-exit{
  display:flex; align-items:center; gap:6px; flex:none; padding:5px 10px 5px 8px;
  color:#8a8375; font-size:14px; line-height:1;
  border:1px solid var(--paper-line);
}
.st-exit span{ font-size:11px; font-weight:700; letter-spacing:.11em; text-transform:uppercase }
.st-exit:hover{ color:var(--ink); border-color:#a9a192 }
.st-name{
  font-size:13px; font-weight:800; font-stretch:112%; letter-spacing:.11em;
  text-transform:uppercase;
}
.st-count{ font-size:11px; color:#938b7c }
.st-prog{ flex:1; height:2px; background:var(--paper-line); overflow:hidden }
.st-prog i{
  display:block; height:100%; width:100%; background:var(--pathway);
  transform:scaleX(0); transform-origin:left; transition:transform .35s var(--ease);
}
.st-play{
  font-size:11px; font-weight:700; letter-spacing:.11em; text-transform:uppercase;
  color:#8a8375; border:1px solid var(--paper-line); padding:4px 11px;
}
.st-play:hover{ color:var(--ink); border-color:#a9a192 }
.st-play[aria-pressed=true]{ color:var(--pathway); border-color:var(--pathway) }

/* ── body ────────────────────────────────────────────────────── */
.st-body{
  position:relative; z-index:2; flex:1; min-height:0;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:clamp(22px,4vh,46px); padding:20px clamp(18px,5vw,60px);
}

/* the body is the tap-anywhere target: a click that is not on something
   pressable advances a beat */
.st-bar,.st-foot,.st-body{ position:relative }
.st-body{ z-index:2; cursor:pointer }
.st-body [data-term],.st-body button,.st-body a{ cursor:default }

/* ── caption: never more than a sentence ─────────────────────── */
.st-caption{
  position:relative; z-index:2; margin:0; max-width:40ch; text-align:center;
  font-size:clamp(19px,2.5vw,27px); line-height:1.4; font-weight:400;
  letter-spacing:-.012em; color:#2e2a25; min-height:1.4em;
}
.st-caption b{ font-weight:700; color:var(--ink) }
.st-caption.in{ animation:capIn .4s var(--ease) both }
@keyframes capIn{ from{ opacity:0; transform:translateY(7px) } }
.st-caption.tone-why{
  font-size:clamp(17px,2vw,21px); color:#5c5648; font-style:italic; max-width:46ch;
}
.st-caption.tone-story{ font-size:clamp(18px,2.2vw,24px); color:#3a352e }

/* ── reaction theatre ────────────────────────────────────────── */
.mode-card .theatre{ display:none }
.mode-theatre .card{ display:none }

.theatre{
  position:relative; z-index:2;
  display:flex; flex-direction:column; align-items:center; gap:clamp(8px,1.4vh,18px);
  width:100%; max-width:1240px;
}
.th-step{
  font-family:'Plex Mono',monospace; font-size:11px; letter-spacing:.17em;
  text-transform:uppercase; color:#a39b8c; margin-bottom:4px;
}
.th-row{
  display:flex; align-items:center; justify-content:center;
  gap:clamp(12px,3vw,48px); width:100%;
}
.th-side{
  flex:0 1 auto; display:flex; flex-wrap:wrap; gap:10px; justify-content:center; min-width:0;
  transition:max-width .5s var(--ease), opacity .4s var(--ease);
}
/* the product column has no width until the product exists, so the
   substrate starts centred and the row opens out as the reaction builds */
/* overflow stays visible so the product can animate out of a zero-width
   column, which also means it is still hit-testable before it exists */
.th-side-to{ max-width:0; opacity:0; overflow:visible; pointer-events:none }
.s-to .th-side-to{ max-width:46vw; opacity:1; pointer-events:auto }

/* molecules */
.mol{
  display:inline-grid; place-items:center;
  padding:clamp(16px,2.4vh,30px) clamp(18px,2vw,34px); min-width:clamp(140px,15vw,230px);
  background:var(--paper); border:2px solid var(--ink);
  opacity:0; transform:translateX(-26px) scale(.9);
  transition:opacity .42s var(--ease), transform .42s var(--ease),
             border-color .3s, color .3s, box-shadow .3s;
}
.mol-t{
  font-size:clamp(13px,1.75vw,21px); font-weight:700; font-stretch:80%;
  letter-spacing:.045em; text-transform:uppercase; line-height:1.2; text-align:center;
}
.s-from .mol-from{ opacity:1; transform:none }
.s-to   .mol-to  { opacity:1; transform:none; animation:landed .5s var(--ease) }
.s-to   .mol-from{ opacity:.4; transform:scale(.93) }
@keyframes landed{
  0%{ transform:scale(.8); border-color:var(--pathway) }
  55%{ border-color:var(--pathway) }
  100%{ transform:none; border-color:var(--ink) }
}
.is-key.s-to .mol-to{ border-color:var(--pathway); color:var(--pathway) }
.is-split.s-to .mol-to{ animation:landed .5s var(--ease) both }
.is-split.s-to .mol-to:nth-child(2){ animation-delay:.16s }

/* the arrow and its catalyst */
.th-mid{
  flex:0 0 clamp(170px,26vw,420px); min-width:0; display:flex; flex-direction:column;
  align-items:center; gap:6px; position:relative;
  transition:flex-basis .5s var(--ease), opacity .4s var(--ease);
}
.theatre:not(.s-enz) .th-mid{ flex-basis:0; opacity:0 }
.th-enz{
  font-size:clamp(12px,1.5vw,19px); font-weight:700; font-stretch:90%;
  color:var(--enzyme); text-align:center; line-height:1.25;
  opacity:0; transform:translateY(7px); transition:opacity .36s var(--ease), transform .36s var(--ease);
}
.s-enz .th-enz{ opacity:1; transform:none }
.th-arrow{ position:relative; display:block; width:100%; height:16px }
.th-arrow i{
  position:absolute; left:0; top:7px; height:2.5px; width:100%; background:var(--ink);
  transform:scaleX(0); transform-origin:left; transition:transform .5s var(--ease);
}
/* a pulse runs the arrow when the product lands */
.th-arrow b{
  position:absolute; top:3.5px; left:0; width:10px; height:10px;
  background:var(--pathway); border-radius:50%; opacity:0;
}
.s-to .th-arrow b{ animation:flow .75s var(--ease) both }
@keyframes flow{
  0%{ left:0; opacity:0 } 15%{ opacity:1 } 85%{ opacity:1 } 100%{ left:100%; opacity:0 }
}
.th-arrow::after{
  content:''; position:absolute; right:0; top:2px;
  border:6px solid transparent; border-left-color:var(--ink);
  opacity:0; transition:opacity .25s .34s;
}
.s-enz .th-arrow i{ transform:scaleX(1) }
.s-enz .th-arrow::after{ opacity:1 }
.th-badge{
  font-family:'Plex Mono',monospace; font-size:10px; letter-spacing:.09em;
  text-transform:uppercase; color:var(--pathway);
  border:1px solid var(--pathway); padding:1px 7px;
  opacity:0; transform:translateY(-4px); transition:opacity .3s .1s, transform .3s .1s;
}
.s-enz .th-badge{ opacity:1; transform:none }

/* cofactors arc in from above and drop out below */
.th-cof{
  display:flex; gap:10px; justify-content:center; flex-wrap:wrap;
  min-height:clamp(34px,5vh,52px); align-items:center;
}
.cof{
  display:inline-flex; align-items:center; gap:6px; padding:clamp(7px,1vh,11px) clamp(12px,1.3vw,18px);
  border:1.5px solid var(--inhibit); color:var(--inhibit);
  font-size:clamp(12px,1.35vw,17px); font-weight:600; background:var(--paper);
  opacity:0; transition:opacity .4s var(--ease), transform .4s var(--ease);
}
.cof-s{ font-family:'Plex Mono',monospace; font-weight:600 }
.th-in  .cof{ transform:translateY(-46px) rotate(-6deg) scale(.92) }
.th-out .cof{ transform:translateY(46px) rotate(6deg) scale(.92) }
.s-use  .th-in  .cof{ opacity:1; transform:none }
.s-make .th-out .cof{ opacity:1; transform:none }
.th-in .cof:nth-child(2),.th-out .cof:nth-child(2){ transition-delay:.09s }
.th-in .cof:nth-child(3),.th-out .cof:nth-child(3){ transition-delay:.18s }

/* ── cards for the non-reaction beats ────────────────────────── */
.card{ position:relative; z-index:2; display:grid; place-items:center; width:100%; max-width:980px }

.c-title{ text-align:center }
.c-eyebrow{
  display:block; margin-bottom:14px; font-size:11px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--pathway);
}
.c-title h2{
  margin:0; font-size:clamp(34px,7vw,74px); line-height:.94; font-weight:800;
  font-stretch:120%; letter-spacing:-.03em; text-transform:uppercase;
  animation:capIn .5s var(--ease) both;
}
.c-chip{
  display:inline-block; padding:12px 24px; border:2px solid var(--enzyme); color:var(--enzyme);
  font-size:clamp(14px,2vw,20px); font-weight:700; font-stretch:92%;
  animation:capIn .45s var(--ease) both;
}
.c-io{ display:flex; align-items:center; gap:clamp(14px,4vw,46px); flex-wrap:wrap; justify-content:center }
.c-io-col{ display:flex; flex-direction:column; align-items:center; gap:10px; max-width:380px }
.c-io-col h4{
  margin:0 0 2px; font-size:10px; letter-spacing:.15em; text-transform:uppercase;
  color:#938b7c; font-weight:700;
}
.c-io-col .cbox{ animation:capIn .4s var(--ease) both;
  font-size:clamp(13px,1.45vw,18px); padding:clamp(9px,1.3vh,14px) clamp(13px,1.4vw,20px) }
.c-io-col .cbox:nth-child(3){ animation-delay:.07s }
.c-io-col .cbox:nth-child(4){ animation-delay:.14s }
.c-io-col .cbox:nth-child(5){ animation-delay:.21s }
.c-io-arrow{ font-size:clamp(26px,4vw,44px); color:var(--pathway) }

.c-recap{ display:flex; flex-wrap:wrap; gap:7px 9px; align-items:center; justify-content:center }
.rc{
  padding:7px 11px; border:1.5px solid var(--ink); font-size:clamp(10px,1.1vw,12.5px);
  font-weight:700; font-stretch:80%; letter-spacing:.04em; text-transform:uppercase;
  animation:capIn .4s var(--ease) both;
}
.rc-arrow{ color:var(--pathway); font-size:13px }

/* ── foot ────────────────────────────────────────────────────── */
.st-foot{
  position:relative; z-index:3; flex:none;
  display:flex; align-items:center; gap:16px; padding:14px 20px;
  border-top:1px solid var(--paper-line); background:var(--paper);
}
.st-nav,.st-next{
  padding:10px 18px; font-size:12px; font-weight:700; letter-spacing:.1em;
  text-transform:uppercase; border:1.5px solid var(--ink);
}
.st-nav{ border-color:var(--paper-line); color:#8a8375 }
.st-nav:hover:not(:disabled){ color:var(--ink); border-color:#a9a192 }
.st-nav:disabled{ opacity:.35; pointer-events:none }
.st-next{ background:var(--pathway); border-color:var(--pathway); color:#fff; margin-left:auto }
.st-next:hover{ background:#d94e14; border-color:#d94e14 }

.st-chain{ display:flex; align-items:center; gap:3px; flex-wrap:wrap; justify-content:center; flex:1 }
.ch-dot{
  width:7px; height:7px; background:#ddd8cc; transform:rotate(45deg);
  transition:background .3s, transform .3s var(--ease);
}
.ch-dot.done{ background:#b9b2a2 }
.ch-dot.now{ background:var(--pathway); transform:rotate(45deg) scale(1.75) }
.ch-link{ width:7px; height:1px; background:#e4dfd3 }

/* the chain is navigation, not decoration: each dot jumps to its step */
.ch-dot{
  cursor:pointer; padding:0; border:0;
  transition:transform .2s var(--ease), background .2s;
}
.ch-dot:hover{ background:var(--pathway); transform:rotate(45deg) scale(1.9) }
.ch-dot.now:hover{ transform:rotate(45deg) scale(2.1) }
.ch-dot:focus-visible{ outline:2px solid var(--pathway); outline-offset:4px }
/* a bigger target than the mark it draws */
.ch-dot::after{ content:''; position:absolute; inset:-9px }
.ch-dot{ position:relative }

/* ── the steps already walked, stacked in the margin ─────────── */
.st-ledger{
  position:absolute; left:clamp(14px,2.2vw,30px); top:clamp(12px,2vh,24px);
  width:clamp(142px,15vw,218px); max-height:calc(100% - 34px);
  margin:0; padding:0; list-style:none; overflow-y:auto; overscroll-behavior:contain;
  z-index:4; scrollbar-width:thin;
}
.st-ledger[hidden]{ display:none }
.st-ledger::-webkit-scrollbar{ width:5px }
.st-ledger::-webkit-scrollbar-thumb{ background:#ddd6c6 }
.lg-row{
  display:flex; align-items:flex-start; gap:7px; width:100%; padding:5px 6px 5px 0;
  text-align:left; color:#9a9284; border-left:2px solid transparent;
  transition:color .2s, border-color .2s, opacity .2s;
}
.lg-row:hover{ color:var(--ink); border-left-color:var(--pathway) }
.lg-row:focus-visible{ outline:2px solid var(--pathway); outline-offset:1px }
.lg-n{ font-size:10px; line-height:1.5; color:#b9b2a2; flex:none; width:12px; text-align:right }
.lg-row:hover .lg-n{ color:var(--pathway) }
.lg-body{ min-width:0; display:block }
.lg-pair{
  display:block; font-size:11px; font-weight:600; font-stretch:88%; line-height:1.3;
  overflow-wrap:anywhere;
}
.lg-pair i{ color:var(--pathway); font-style:normal }
.lg-enz{
  display:block; margin-top:1px; font-size:9.5px; font-weight:500; line-height:1.25;
  color:#a9a192; overflow-wrap:anywhere;
}
.lg-row:hover .lg-enz{ color:var(--enzyme) }
/* the newest entry is the one worth reading */
.st-ledger li:last-child .lg-row{ color:#6d6659 }
.st-ledger li:last-child .lg-n{ color:#9a9284 }

/* ── narrow screens ──────────────────────────────────────────── */
@media (max-width:760px){
  .st-body{ gap:18px; padding:14px }
  .st-ledger{ display:none }
  .st-chain{ display:none }
  .st-bar{ padding:10px 12px; gap:9px }
  .st-exit span{ display:none }
  .st-exit{ padding:5px 7px }
  .st-name{ font-size:11px }
  .mol{ padding:12px 14px; min-width:0; width:100% }

  /* the reaction runs top to bottom on a phone */
  .th-row{ flex-direction:column; gap:8px; width:100% }
  .th-side{ width:100%; max-width:none }
  .th-side-to{ max-width:none; max-height:0; opacity:0; overflow:hidden;
               transition:max-height .5s var(--ease), opacity .4s var(--ease) }
  .s-to .th-side-to{ max-height:44vh; opacity:1 }
  .th-mid{ pointer-events:none }
  .s-enz .th-mid{ pointer-events:auto }

  .th-mid{ flex:none; width:100%; max-height:120px; overflow:hidden }
  .theatre:not(.s-enz) .th-mid{ flex-basis:auto; max-height:0; opacity:0 }

  .th-arrow{ width:16px; height:48px; margin:2px auto }
  .th-arrow i{ left:7px; top:0; width:2.5px; height:100%; transform:scaleY(0); transform-origin:top }
  .s-enz .th-arrow i{ transform:scaleY(1) }
  .th-arrow::after{
    right:auto; left:2px; top:auto; bottom:-3px;
    border-left-color:transparent; border-top-color:var(--ink);
  }
  .th-arrow b{ display:none }
  .th-cof{ min-height:0 }
}

@media (prefers-reduced-motion:reduce){
  .mol,.cof,.th-enz,.th-arrow i,.th-arrow::after,.th-badge{ transition:none }
  .st-caption.in,.c-title h2,.c-chip,.rc,.c-io-col .cbox{ animation:none }
  .mol,.cof,.th-enz,.th-badge{ transform:none }
}

/* ───────────────────────────────────────────────────────────────
   MOTIFS
   A beat that is only words still gets something to watch. Each motif
   is a diagram that means what the sentence means: a box that splits
   for splitting, cells that charge for ATP, a gate for regulation.
   One motif on screen at a time, drawn in the chart's four inks.
   ─────────────────────────────────────────────────────────────── */

.mo{
  position:relative; display:flex; align-items:center; justify-content:center;
  width:min(680px,82vw); height:clamp(162px,30vh,330px);
  animation:moIn .45s var(--ease) both;
}
@keyframes moIn{ from{ opacity:0; transform:translateY(12px) scale(.97) } }

/* ── energy: cells charging inside a cassette ─────────────────── */
.mo-energy .eo{
  display:flex; align-items:flex-end; gap:clamp(10px,2vw,21px);
  height:clamp(118px,21vh,206px); padding:clamp(11px,1.8vh,18px);
  border:2px solid var(--ink);
}
.mo-energy .eb{ position:relative; width:clamp(21px,4.2vw,42px); height:100%; background:#ece6d8 }
.mo-energy .eb::after{
  content:''; position:absolute; inset:0; background:var(--pathway);
  transform:scaleY(0); transform-origin:bottom;
  animation:ebFill 2.6s var(--ease) infinite;
  animation-delay:calc(var(--i) * .17s);
}
@keyframes ebFill{ 0%{transform:scaleY(0)} 30%,72%{transform:scaleY(1)} 100%{transform:scaleY(0)} }
.mo-energy .ez{
  position:absolute; top:11%; left:50%; width:clamp(13px,2vw,19px); height:clamp(13px,2vw,19px);
  margin-left:calc(clamp(13px,2vw,19px) / -2);
  background:var(--pathway); transform:rotate(45deg) scale(0);
  animation:ezPop 2.6s var(--ease) infinite .68s;
}
@keyframes ezPop{ 0%,8%{transform:rotate(45deg) scale(0)} 22%{transform:rotate(45deg) scale(1)}
                  60%{transform:rotate(45deg) scale(1)} 74%,100%{transform:rotate(45deg) scale(0)} }

/* ── redox: an electron hops donor to acceptor ────────────────── */
.mo-redox .rx-n{
  position:absolute; top:50%; width:clamp(66px,12vw,114px); height:clamp(66px,12vw,114px);
  margin-top:calc(clamp(66px,12vw,114px) / -2);
  border:2px solid var(--ink); border-radius:50%; background:var(--paper);
}
.mo-redox .rx-a{ left:10% } .mo-redox .rx-b{ right:10% }
.mo-redox .rx-track{
  position:absolute; left:26%; right:26%; top:50%; height:0;
  border-top:2px dashed #c9c2b1;
}
.mo-redox .rx-e{
  position:absolute; top:50%; width:clamp(15px,2.4vw,22px); height:clamp(15px,2.4vw,22px);
  margin-top:calc(clamp(15px,2.4vw,22px) / -2); border-radius:50%; background:var(--pathway);
  animation:rxHop 2.4s var(--ease) infinite;
}
@keyframes rxHop{
  0%,12%{ left:16%; opacity:0 } 20%{ opacity:1 }
  64%{ left:72%; opacity:1 } 76%,100%{ left:72%; opacity:0 }
}

/* ── transport: through the membrane ──────────────────────────── */
.mo-transport .tp-mem{
  position:absolute; left:8%; right:8%; top:50%; height:clamp(16px,2.6vh,24px);
  margin-top:calc(clamp(16px,2.6vh,24px) / -2);
  border-top:2px solid var(--ink); border-bottom:2px solid var(--ink);
}
.mo-transport .tp-chan{
  position:absolute; left:50%; top:50%; width:clamp(30px,5vw,48px);
  height:clamp(20px,3vh,28px); margin-left:calc(clamp(30px,5vw,48px) / -2);
  margin-top:calc(clamp(20px,3vh,28px) / -2);
  background:var(--paper); border-left:2px solid var(--enzyme); border-right:2px solid var(--enzyme);
}
.mo-transport .tp-dot{
  position:absolute; left:50%; width:clamp(16px,2.6vw,24px); height:clamp(16px,2.6vw,24px);
  margin-left:calc(clamp(16px,2.6vw,24px) / -2); background:var(--pathway);
  transform:rotate(45deg); animation:tpCross 2.6s var(--ease) infinite;
}
@keyframes tpCross{
  0%{ top:78%; opacity:0 } 14%{ opacity:1 }
  78%{ top:12%; opacity:1 } 100%{ top:12%; opacity:0 }
}

/* ── split: one box becomes two ───────────────────────────────── */
.mo-split .sp,.mo-build .bd{
  position:absolute; top:50%; width:clamp(112px,20vw,184px); height:clamp(76px,13vh,128px);
  margin-top:calc(clamp(76px,13vh,128px) / -2);
  border:2px solid var(--ink); background:var(--paper);
}
.mo-split .sp-a{ left:50%; margin-left:calc(clamp(112px,20vw,184px) * -1); animation:spLeft 2.8s var(--ease) infinite }
.mo-split .sp-b{ left:50%; animation:spRight 2.8s var(--ease) infinite }
@keyframes spLeft{ 0%,22%{transform:none} 58%,82%{transform:translateX(-26%)} 100%{transform:none} }
@keyframes spRight{ 0%,22%{transform:none} 58%,82%{transform:translateX(26%)} 100%{transform:none} }
.mo-split .sp-seam{
  position:absolute; left:50%; top:50%; width:2px; height:clamp(96px,17vh,152px);
  margin-top:calc(clamp(96px,17vh,152px) / -2); background:var(--pathway);
  transform:scaleY(0); animation:spSeam 2.8s var(--ease) infinite;
}
@keyframes spSeam{ 0%,18%{transform:scaleY(0);opacity:0} 34%{transform:scaleY(1);opacity:1}
                   74%{transform:scaleY(1);opacity:1} 90%,100%{transform:scaleY(0);opacity:0} }

/* ── build: two boxes become one ──────────────────────────────── */
.mo-build .bd-a{ left:50%; margin-left:calc(clamp(112px,20vw,184px) * -1); animation:bdLeft 2.8s var(--ease) infinite }
.mo-build .bd-b{ left:50%; animation:bdRight 2.8s var(--ease) infinite }
@keyframes bdLeft{ 0%,14%{transform:translateX(-26%)} 56%,86%{transform:none} 100%{transform:translateX(-26%)} }
@keyframes bdRight{ 0%,14%{transform:translateX(26%)} 56%,86%{transform:none} 100%{transform:translateX(26%)} }
.mo-build .bd-weld{
  position:absolute; left:50%; top:50%; width:clamp(16px,2.6vw,24px);
  height:clamp(16px,2.6vw,24px); margin:calc(clamp(16px,2.6vw,24px) / -2) 0 0 calc(clamp(16px,2.6vw,24px) / -2);
  background:var(--pathway); transform:rotate(45deg) scale(0);
  animation:bdWeld 2.8s var(--ease) infinite;
}
@keyframes bdWeld{ 0%,48%{transform:rotate(45deg) scale(0)} 60%{transform:rotate(45deg) scale(1.25)}
                   72%,86%{transform:rotate(45deg) scale(1)} 96%,100%{transform:rotate(45deg) scale(0)} }

/* ── cycle: a marker goes round and comes back ────────────────── */
.mo-cycle .cy-ring{
  position:absolute; top:50%; left:50%; width:clamp(128px,23vh,232px); height:clamp(128px,23vh,232px);
  margin:calc(clamp(128px,23vh,232px) / -2) 0 0 calc(clamp(128px,23vh,232px) / -2);
  border:2.5px dashed #c3bcab; border-radius:50%;
}
.mo-cycle .cy-tick{
  position:absolute; top:50%; left:50%; width:10px; height:10px; background:var(--ink);
  margin:-5px 0 0 -5px; transform:rotate(45deg)
    translate(calc(clamp(128px,23vh,232px) / 2), 0);
}
.mo-cycle .cy-tick:nth-child(3){ transform:rotate(135deg) translate(calc(clamp(128px,23vh,232px) / 2),0) }
.mo-cycle .cy-tick:nth-child(4){ transform:rotate(225deg) translate(calc(clamp(128px,23vh,232px) / 2),0) }
.mo-cycle .cy-tick:nth-child(5){ transform:rotate(315deg) translate(calc(clamp(128px,23vh,232px) / 2),0) }
.mo-cycle .cy-arm{
  position:absolute; top:50%; left:50%; width:clamp(128px,23vh,232px); height:clamp(128px,23vh,232px);
  margin:calc(clamp(128px,23vh,232px) / -2) 0 0 calc(clamp(128px,23vh,232px) / -2);
  animation:cySpin 3.6s linear infinite;
}
@keyframes cySpin{ to{ transform:rotate(360deg) } }
.mo-cycle .cy-dot{
  position:absolute; top:0; left:50%; width:clamp(17px,2.8vw,26px); height:clamp(17px,2.8vw,26px);
  margin:calc(clamp(17px,2.8vw,26px) / -2) 0 0 calc(clamp(17px,2.8vw,26px) / -2);
  background:var(--pathway); transform:rotate(45deg);
}

/* ── store: bars pile up ──────────────────────────────────────── */
.mo-store{ --sh:clamp(18px,3vh,28px) }
.mo-store .so{
  position:absolute; left:50%; width:clamp(156px,30vw,262px); height:var(--sh);
  margin-left:calc(clamp(156px,30vw,262px) / -2);
  bottom:calc(16% + var(--i) * (var(--sh) + 7px));
  background:var(--paper); border:2px solid var(--ink);
  animation:soDrop 3.4s var(--ease) infinite;
  animation-delay:calc(var(--i) * .22s);
}
@keyframes soDrop{
  0%{ opacity:0; transform:translateY(-34px) } 12%,86%{ opacity:1; transform:none }
  100%{ opacity:0; transform:translateY(-34px) }
}
.mo-store .so:nth-child(5){ border-color:var(--pathway) }

/* ── control: a gate that opens and shuts ─────────────────────── */
.mo-control .ct-rail{
  position:absolute; left:9%; right:9%; top:50%; height:2.5px; background:var(--ink);
}
.mo-control .ct-gate{
  position:absolute; left:50%; width:clamp(22px,3.8vw,34px); height:clamp(52px,10vh,94px);
  margin-left:calc(clamp(22px,3.8vw,34px) / -2); background:var(--enzyme);
  animation:ctGate 3s var(--ease) infinite;
}
.mo-control .ct-up{ bottom:50%; transform-origin:top }
.mo-control .ct-dn{ top:50%; transform-origin:bottom }
@keyframes ctGate{ 0%,20%{transform:scaleY(1)} 42%,72%{transform:scaleY(.16)} 92%,100%{transform:scaleY(1)} }
.mo-control .ct-dot{
  position:absolute; top:50%; width:clamp(15px,2.4vw,22px); height:clamp(15px,2.4vw,22px);
  margin-top:calc(clamp(15px,2.4vw,22px) / -2); border-radius:50%; background:var(--pathway);
  animation:ctRun 3s var(--ease) infinite;
}
@keyframes ctRun{
  0%{ left:9%; opacity:0 } 30%{ left:34%; opacity:1 }
  44%{ left:44%; opacity:1 } 68%{ left:84%; opacity:1 } 80%,100%{ left:84%; opacity:0 }
}

/* ── release: something leaves and is gone ────────────────────── */
.mo-release .rl-box{
  position:absolute; bottom:14%; left:50%; width:clamp(144px,26vw,228px);
  height:clamp(66px,11.5vh,106px); margin-left:calc(clamp(144px,26vw,228px) / -2);
  border:2px solid var(--ink); background:var(--paper);
}
.mo-release .rl-p{
  position:absolute; bottom:44%; left:50%; width:clamp(14px,2.2vw,20px); height:clamp(14px,2.2vw,20px);
  border-radius:50%; border:2px solid var(--inhibit);
  margin-left:calc(clamp(14px,2.2vw,20px) / -2);
  animation:rlUp 2.6s var(--ease) infinite;
  animation-delay:calc(var(--i) * .42s);
}
@keyframes rlUp{
  0%{ transform:translate(0,0) scale(.6); opacity:0 }
  18%{ opacity:1 }
  100%{ transform:translate(calc(-28px + var(--i) * 28px),-96px) scale(1.15); opacity:0 }
}

/* ── speed: it happens fast ───────────────────────────────────── */
.mo-speed .sx-rail{
  position:absolute; left:8%; right:8%; top:50%; height:2px; background:#ddd6c6;
}
.mo-speed .sx-t{
  position:absolute; top:50%; width:clamp(22px,4.4vw,42px); height:4px; margin-top:-2px;
  background:var(--pathway); animation:sxRun 1.25s linear infinite;
  animation-delay:calc(var(--i) * .17s);
}
@keyframes sxRun{
  0%{ left:6%; opacity:0; transform:scaleX(.4) } 18%{ opacity:1; transform:scaleX(1) }
  76%{ opacity:1 } 100%{ left:88%; opacity:0; transform:scaleX(.4) }
}

/* ── balance: it can tip either way ───────────────────────────── */
.mo-balance .bl-piv{
  position:absolute; top:50%; left:50%; margin-left:-14px;
  border:14px solid transparent; border-bottom:22px solid var(--ink); border-top:0;
}
.mo-balance .bl-beam{
  position:absolute; top:50%; left:50%; width:clamp(232px,42vw,392px); height:5px;
  margin:-3px 0 0 calc(clamp(232px,42vw,392px) / -2);
  background:var(--ink); animation:blRock 3.6s ease-in-out infinite;
}
@keyframes blRock{ 0%,100%{transform:rotate(-7deg)} 50%{transform:rotate(7deg)} }
.mo-balance .bl-pan{
  position:absolute; top:5px; width:clamp(58px,11vw,95px); height:clamp(32px,5.6vh,49px);
  border:2px solid var(--ink); border-top:0; background:var(--paper);
}
.mo-balance .bl-l{ left:0 } .mo-balance .bl-r{ right:0; border-color:var(--pathway) }

/* ── branch: the path forks ───────────────────────────────────── */
.mo-branch .br-trunk{
  position:absolute; left:10%; top:50%; width:40%; height:2.5px; margin-top:-1px; background:var(--ink);
}
.mo-branch .br-trunk::after{
  content:''; position:absolute; right:0; top:50%; width:2.5px; height:clamp(90px,17vh,152px);
  margin-top:calc(clamp(90px,17vh,152px) / -2); background:var(--ink);
}
.mo-branch .br-arm{
  position:absolute; left:50%; width:30%; height:2.5px; background:var(--ink);
  top:calc(50% + (var(--i) - 1) * clamp(45px,8.5vh,76px));
}
.mo-branch .br-end{
  position:absolute; left:80%; width:clamp(17px,2.8vw,26px); height:clamp(17px,2.8vw,26px);
  margin:calc(clamp(17px,2.8vw,26px) / -2) 0 0 0;
  top:calc(50% + (var(--i) - 1) * clamp(45px,8.5vh,76px));
  border:2px solid var(--ink); background:var(--paper);
  animation:brPick 3.6s var(--ease) infinite;
  animation-delay:calc(var(--i) * 1.2s);
}
@keyframes brPick{
  0%,4%{ background:var(--paper); border-color:var(--ink); transform:none }
  12%,26%{ background:var(--pathway); border-color:var(--pathway); transform:scale(1.22) }
  36%,100%{ background:var(--paper); border-color:var(--ink); transform:none }
}
.mo-branch .br-dot{
  position:absolute; top:50%; width:clamp(14px,2.2vw,21px); height:clamp(14px,2.2vw,21px);
  margin-top:calc(clamp(14px,2.2vw,21px) / -2); background:var(--pathway); transform:rotate(45deg);
  animation:brRun 1.2s var(--ease) infinite;
}
@keyframes brRun{ 0%{ left:9%; opacity:0 } 20%{ opacity:1 } 80%{ opacity:1 } 100%{ left:48%; opacity:0 } }

/* ── link: everything meets here ──────────────────────────────── */
.mo-link .lk-hub{
  position:absolute; top:50%; left:50%; width:clamp(37px,6vw,56px); height:clamp(37px,6vw,56px);
  margin:calc(clamp(37px,6vw,56px) / -2) 0 0 calc(clamp(37px,6vw,56px) / -2);
  background:var(--pathway); transform:rotate(45deg);
}
.mo-link .lk-arm{
  position:absolute; top:50%; left:50%; width:clamp(92px,17vw,152px); height:2.5px;
  margin-top:-1px; background:var(--ink); transform-origin:left center;
  transform:rotate(calc(45deg + var(--i) * 90deg)) scaleX(0);
  animation:lkArm 3.8s var(--ease) infinite;
  animation-delay:calc(var(--i) * .13s);
}
@keyframes lkArm{
  0%{ transform:rotate(calc(45deg + var(--i) * 90deg)) scaleX(0) }
  22%,80%{ transform:rotate(calc(45deg + var(--i) * 90deg)) scaleX(1) }
  100%{ transform:rotate(calc(45deg + var(--i) * 90deg)) scaleX(0) }
}
.mo-link .lk-node{
  position:absolute; top:50%; left:50%; width:clamp(27px,4.4vw,42px); height:clamp(27px,4.4vw,42px);
  margin:calc(clamp(27px,4.4vw,42px) / -2) 0 0 calc(clamp(27px,4.4vw,42px) / -2);
  border:2px solid var(--ink); background:var(--paper);
  transform:rotate(calc(45deg + var(--i) * 90deg)) translateX(clamp(92px,17vw,152px)) rotate(-45deg) scale(0);
  animation:lkNode 3.8s var(--ease) infinite;
  animation-delay:calc(.2s + var(--i) * .13s);
}
@keyframes lkNode{
  0%{ transform:rotate(calc(45deg + var(--i) * 90deg)) translateX(clamp(92px,17vw,152px)) rotate(-45deg) scale(0) }
  20%,80%{ transform:rotate(calc(45deg + var(--i) * 90deg)) translateX(clamp(92px,17vw,152px)) rotate(-45deg) scale(1) }
  100%{ transform:rotate(calc(45deg + var(--i) * 90deg)) translateX(clamp(92px,17vw,152px)) rotate(-45deg) scale(0) }
}

/* ── block: the pathway stops here ────────────────────────────── */
.mo-block{ --bkd:clamp(16px,2.6vw,24px) }
.mo-block .bk-rail{
  position:absolute; left:8%; right:8%; top:50%; height:2.5px; margin-top:-1px; background:var(--ink);
}
.mo-block .bk-bar{
  position:absolute; left:64%; top:50%; width:clamp(10px,1.7vw,15px); height:clamp(86px,16vh,146px);
  margin-top:calc(clamp(86px,16vh,146px) / -2); background:var(--inhibit);
  animation:bkBar 2.2s var(--ease) infinite;
}
@keyframes bkBar{ 0%,52%{transform:scaleY(1)} 62%{transform:scaleY(1.16)} 76%,100%{transform:scaleY(1)} }
.mo-block .bk-dot{
  position:absolute; top:50%; width:var(--bkd); height:var(--bkd);
  margin-top:calc(var(--bkd) / -2); border-radius:50%; background:var(--pathway);
  left:calc(60% - var(--i) * (var(--bkd) + 6px));
  animation:bkStop 2.2s var(--ease) infinite; animation-delay:calc(var(--i) * .16s);
}
@keyframes bkStop{
  0%{ left:7%; opacity:0 } 12%{ opacity:1 }
  52%,86%{ left:calc(60% - var(--i) * (var(--bkd) + 6px)); opacity:1 }
  100%{ left:calc(60% - var(--i) * (var(--bkd) + 6px)); opacity:0 }
}

/* ── history: a marker walks the years ────────────────────────── */
.mo-history .hs-rail{
  position:absolute; left:9%; right:9%; top:50%; height:2.5px; margin-top:-1px; background:var(--ink);
}
.mo-history .hs-t{
  position:absolute; top:50%; width:3px; height:clamp(32px,6vh,54px); background:#c7c0ae;
  left:calc(12% + var(--i) * 14.4%); margin-top:calc(clamp(32px,6vh,54px) / -2);
  animation:hsLit 3.6s var(--ease) infinite; animation-delay:calc(var(--i) * .72s);
}
@keyframes hsLit{
  0%,4%{ background:#c7c0ae; transform:scaleY(1) }
  12%,24%{ background:var(--pathway); transform:scaleY(1.45) }
  38%,100%{ background:#c7c0ae; transform:scaleY(1) }
}
.mo-history .hs-mark{
  position:absolute; top:50%; left:69.6%; width:clamp(18px,2.9vw,27px); height:clamp(18px,2.9vw,27px);
  margin-top:calc(clamp(18px,2.9vw,27px) / -2); background:var(--pathway); transform:rotate(45deg);
  animation:hsRun 3.6s steps(5,end) infinite;
}
@keyframes hsRun{ from{ left:12% } to{ left:84% } }

/* ── species: who can do this, and who cannot ─────────────────── */
.mo-species{ gap:clamp(11px,2.5vw,26px) }
.mo-species .ss-c{
  position:relative; width:clamp(62px,11vw,104px); height:clamp(62px,11vw,104px);
  border:2px solid var(--ink); background:var(--paper);
  animation:ssIn .55s var(--ease) both; animation-delay:calc(var(--i) * .13s);
}
@keyframes ssIn{ from{ opacity:0; transform:translateY(16px) scale(.84) } }
.mo-species .ss-c:nth-child(odd){ background:var(--pathway); border-color:var(--pathway) }
.mo-species .ss-c:nth-child(even)::before,
.mo-species .ss-c:nth-child(even)::after{
  content:''; position:absolute; left:16%; right:16%; top:50%; height:3px;
  margin-top:-1.5px; background:var(--inhibit);
}
.mo-species .ss-c:nth-child(even)::before{
  transform:rotate(45deg); animation:ssXa .5s var(--ease) both; animation-delay:calc(.45s + var(--i) * .13s);
}
.mo-species .ss-c:nth-child(even)::after{
  transform:rotate(-45deg); animation:ssXb .5s var(--ease) both; animation-delay:calc(.45s + var(--i) * .13s);
}
@keyframes ssXa{ from{ transform:rotate(45deg) scaleX(0) } to{ transform:rotate(45deg) scaleX(1) } }
@keyframes ssXb{ from{ transform:rotate(-45deg) scaleX(0) } to{ transform:rotate(-45deg) scaleX(1) } }

/* ── scale: how much, next to how little ──────────────────────── */
.mo-scale .sc-base{
  position:absolute; left:16%; right:16%; bottom:16%; height:2.5px; background:var(--ink);
}
.mo-scale .sc-a,.mo-scale .sc-b{
  position:absolute; bottom:16%; width:clamp(50px,9vw,84px);
  border:2px solid var(--ink); background:var(--paper); transform-origin:bottom;
}
.mo-scale .sc-a{ left:28%; height:clamp(20px,3.4vh,30px) }
.mo-scale .sc-b{
  right:28%; height:clamp(104px,20vh,182px);
  background:var(--pathway); border-color:var(--pathway);
  animation:scGrow 3s var(--ease) infinite;
}
@keyframes scGrow{ 0%{ transform:scaleY(.09) } 42%,78%{ transform:scaleY(1) } 100%{ transform:scaleY(.09) } }

/* ── drain: it runs out ───────────────────────────────────────── */
.mo-drain .dr-jar{
  position:absolute; left:50%; top:50%; width:clamp(104px,19vw,170px); height:clamp(112px,20vh,184px);
  margin:calc(clamp(112px,20vh,184px) / -2) 0 0 calc(clamp(104px,19vw,170px) / -2);
  border:2px solid var(--ink); border-top:0; background:var(--paper);
}
.mo-drain .dr-fill{
  position:absolute; left:50%; top:50%; width:calc(clamp(104px,19vw,170px) - 10px);
  height:calc(clamp(112px,20vh,184px) - 8px);
  margin:calc((clamp(112px,20vh,184px) - 8px) / -2) 0 0 calc((clamp(104px,19vw,170px) - 10px) / -2);
  background:var(--pathway); transform-origin:bottom;
  animation:drFall 2.8s var(--ease) infinite;
}
@keyframes drFall{ 0%,8%{ transform:scaleY(1) } 62%,86%{ transform:scaleY(.06) } 100%{ transform:scaleY(1) } }
.mo-drain .dr-drop{
  position:absolute; left:50%; width:clamp(11px,1.8vw,16px); height:clamp(11px,1.8vw,16px);
  margin-left:calc(clamp(11px,1.8vw,16px) / -2); border-radius:50% 50% 50% 0;
  background:var(--pathway); transform:rotate(-45deg);
  animation:drDrip 2.8s var(--ease) infinite; animation-delay:calc(var(--i) * .3s);
}
@keyframes drDrip{
  0%,10%{ top:62%; opacity:0 } 18%{ opacity:1 }
  46%{ top:88%; opacity:1 } 56%,100%{ top:88%; opacity:0 }
}

/* ── flood: it builds up where it should not ─────────────────── */
.mo-flood .fl-vessel{
  position:absolute; left:50%; top:50%; width:clamp(132px,24vw,214px); height:clamp(104px,19vh,172px);
  margin:calc(clamp(104px,19vh,172px) / -2) 0 0 calc(clamp(132px,24vw,214px) / -2);
  border:2px solid var(--ink); background:var(--paper);
}
.mo-flood .fl-level{
  position:absolute; left:50%; top:50%; width:calc(clamp(132px,24vw,214px) - 10px);
  height:calc(clamp(104px,19vh,172px) - 8px);
  margin:calc((clamp(104px,19vh,172px) - 8px) / -2) 0 0 calc((clamp(132px,24vw,214px) - 10px) / -2);
  background:var(--inhibit); transform-origin:bottom;
  animation:flRise 3s var(--ease) infinite;
}
@keyframes flRise{ 0%,6%{ transform:scaleY(.08) } 58%,84%{ transform:scaleY(1) } 100%{ transform:scaleY(.08) } }
.mo-flood .fl-bub{
  position:absolute; left:calc(40% + var(--i) * 10%); width:clamp(9px,1.5vw,14px); height:clamp(9px,1.5vw,14px);
  border-radius:50%; border:2px solid var(--paper);
  animation:flBub 3s var(--ease) infinite; animation-delay:calc(var(--i) * .36s);
}
@keyframes flBub{
  0%,12%{ top:66%; opacity:0 } 24%{ opacity:.95 }
  62%{ top:38%; opacity:.95 } 72%,100%{ top:38%; opacity:0 }
}

/* ── detour: the way round a block ───────────────────────────── */
.mo-detour{ --dtr:clamp(70px,13vh,118px) }
.mo-detour .dt-main{
  position:absolute; left:10%; right:10%; top:62%; height:2.5px; background:var(--ink);
}
.mo-detour .dt-gap{
  position:absolute; left:50%; top:62%; width:clamp(42px,7vw,66px); height:11px;
  margin:-5px 0 0 calc(clamp(42px,7vw,66px) / -2); background:var(--paper);
  border-left:2.5px solid var(--inhibit); border-right:2.5px solid var(--inhibit);
}
.mo-detour .dt-arc{
  position:absolute; left:50%; top:62%; width:calc(var(--dtr) * 2); height:var(--dtr);
  margin:calc(var(--dtr) * -1) 0 0 calc(var(--dtr) * -1);
  border:2.5px dashed #c3bcab; border-bottom:0;
  border-radius:var(--dtr) var(--dtr) 0 0;
}
.mo-detour .dt-arm{
  position:absolute; left:50%; top:62%; width:calc(var(--dtr) * 2); height:calc(var(--dtr) * 2);
  margin:calc(var(--dtr) * -1) 0 0 calc(var(--dtr) * -1);
  animation:dtSwing 2.6s var(--ease) infinite;
}
@keyframes dtSwing{ 0%,8%{ transform:rotate(-90deg) } 70%,86%{ transform:rotate(90deg) } 100%{ transform:rotate(-90deg) } }
.mo-detour .dt-dot{
  position:absolute; top:0; left:50%; width:clamp(15px,2.4vw,22px); height:clamp(15px,2.4vw,22px);
  margin:calc(clamp(15px,2.4vw,22px) / -2) 0 0 calc(clamp(15px,2.4vw,22px) / -2);
  background:var(--pathway); transform:rotate(45deg);
}

/* ── family: near-identical, one detail apart ────────────────── */
.mo-family{ gap:clamp(8px,1.8vw,18px) }
.mo-family .fm-u{
  position:relative; width:clamp(44px,8vw,74px); height:clamp(76px,14vh,128px);
  border:2px solid var(--ink); background:var(--paper);
  animation:fmIn .5s var(--ease) both; animation-delay:calc(var(--i) * .1s);
}
@keyframes fmIn{ from{ opacity:0; transform:translateY(14px) } }
.mo-family .fm-u::after{
  content:''; position:absolute; left:50%; width:clamp(14px,2.4vw,22px); height:clamp(14px,2.4vw,22px);
  margin-left:calc(clamp(14px,2.4vw,22px) / -2); background:var(--pathway); transform:rotate(45deg);
  top:calc(14% + var(--i) * 17%);
  animation:fmMark 3.4s var(--ease) infinite; animation-delay:calc(var(--i) * .17s);
}
@keyframes fmMark{ 0%,10%{ opacity:.2; transform:rotate(45deg) scale(.7) }
                   24%,74%{ opacity:1; transform:rotate(45deg) scale(1) }
                   90%,100%{ opacity:.2; transform:rotate(45deg) scale(.7) } }

/* ── colour: you can see it ──────────────────────────────────── */
.mo-colour{ gap:clamp(9px,2vw,20px) }
.mo-colour .cl-sw{
  width:clamp(56px,10vw,96px); height:clamp(84px,15vh,142px); border:2px solid var(--ink);
  animation:clShift 4s var(--ease) infinite; animation-delay:calc(var(--i) * .25s);
}
@keyframes clShift{
  0%,100%{ background:var(--paper) }
  20%{ background:var(--pathway) }
  40%{ background:var(--enzyme) }
  60%{ background:var(--inhibit) }
  80%{ background:var(--activate) }
}

/* ── light: a photon does the work ───────────────────────────── */
.mo-light .lt-src{
  position:absolute; top:16%; left:50%; width:clamp(34px,5.6vw,52px); height:clamp(34px,5.6vw,52px);
  margin-left:calc(clamp(34px,5.6vw,52px) / -2); border-radius:50%;
  background:var(--pathway); animation:ltPulse 2.4s var(--ease) infinite;
}
@keyframes ltPulse{ 0%,100%{ transform:scale(.88) } 46%{ transform:scale(1.1) } }
.mo-light .lt-ray{
  position:absolute; top:34%; left:50%; width:3px; height:clamp(44px,8vh,76px);
  background:var(--pathway); transform-origin:top;
  transform:rotate(calc(-24deg + var(--i) * 16deg));
  animation:ltRay 2.4s var(--ease) infinite; animation-delay:calc(var(--i) * .11s);
}
@keyframes ltRay{ 0%,8%{ opacity:0; transform:rotate(calc(-24deg + var(--i) * 16deg)) scaleY(.2) }
                  34%,70%{ opacity:1; transform:rotate(calc(-24deg + var(--i) * 16deg)) scaleY(1) }
                  92%,100%{ opacity:0; transform:rotate(calc(-24deg + var(--i) * 16deg)) scaleY(.2) } }
.mo-light .lt-target{
  position:absolute; bottom:14%; left:50%; width:clamp(116px,21vw,186px); height:clamp(34px,6vh,54px);
  margin-left:calc(clamp(116px,21vw,186px) / -2); border:2px solid var(--ink); background:var(--paper);
  animation:ltHit 2.4s var(--ease) infinite;
}
@keyframes ltHit{ 0%,36%{ background:var(--paper); border-color:var(--ink) }
                  52%,76%{ background:#fdf0d8; border-color:var(--pathway) }
                  92%,100%{ background:var(--paper); border-color:var(--ink) } }

/* ── pulse: the quiet default ─────────────────────────────────── */
.mo-pulse .pu-core{
  position:absolute; top:50%; left:50%; width:clamp(32px,5.4vw,49px); height:clamp(32px,5.4vw,49px);
  margin:calc(clamp(32px,5.4vw,49px) / -2) 0 0 calc(clamp(32px,5.4vw,49px) / -2);
  background:var(--pathway); transform:rotate(45deg);
}
.mo-pulse .pu-ring{
  position:absolute; top:50%; left:50%; width:clamp(32px,5.4vw,49px); height:clamp(32px,5.4vw,49px);
  margin:calc(clamp(32px,5.4vw,49px) / -2) 0 0 calc(clamp(32px,5.4vw,49px) / -2);
  border:2px solid var(--pathway);
  animation:puRing 3s var(--ease) infinite;
  animation-delay:calc(var(--i) * 1s);
}
@keyframes puRing{
  0%{ transform:rotate(45deg) scale(1); opacity:.9 }
  100%{ transform:rotate(45deg) scale(4.2); opacity:0 }
}

/* ── steps: the count is the picture ──────────────────────────── */
.mo-steps{ gap:clamp(5px,1.1vw,11px); flex-wrap:wrap; padding:0 10px }
.mo-steps .sq-rail{
  position:absolute; left:4%; right:4%; top:50%; height:2px; background:#e4ded0;
}
.mo-steps .sq-t{
  position:relative; width:clamp(8px,1.8vw,16px); height:clamp(48px,10vh,92px);
  background:#ddd6c6; animation:sqOn .5s var(--ease) both;
  animation-delay:calc(.1s + var(--i) * .07s);
}
@keyframes sqOn{
  from{ transform:scaleY(.2); background:#ddd6c6 }
  to{ transform:scaleY(1); background:var(--pathway) }
}

/* ── the "why" beat: the reaction is built, so it signs itself ── */
.theatre.is-why .th-row::after{
  content:''; position:absolute; left:0; right:0; bottom:-10px; height:2px;
  background:var(--pathway); transform-origin:left;
  animation:whyRule .7s var(--ease) both;
}
.th-row{ position:relative }
@keyframes whyRule{ from{ transform:scaleX(0); opacity:.4 } to{ transform:scaleX(1); opacity:1 } }
.theatre.is-why .mol-to{ border-color:var(--pathway) }

@media (max-width:760px){
  .mo{ width:94vw; height:clamp(140px,25vh,240px) }
}

@media (prefers-reduced-motion:reduce){
  .mo,.mo *{ animation:none!important }
  .mo-energy .eb::after,.mo-steps .sq-t{ transform:none; background:var(--pathway) }
  .mo-energy .ez,.mo-build .bd-weld{ transform:rotate(45deg) }
  .mo-link .lk-arm{ transform:rotate(calc(45deg + var(--i) * 90deg)) }
  .mo-link .lk-node{ transform:rotate(calc(45deg + var(--i) * 90deg))
    translateX(clamp(92px,17vw,152px)) rotate(-45deg) }
  .mo-split .sp-seam{ transform:none }
  .mo-drain .dr-fill,.mo-flood .fl-level{ transform:scaleY(1) }
  .mo-detour .dt-arm{ transform:rotate(90deg) }
  .mo-family .fm-u::after{ opacity:1; transform:rotate(45deg) }
  .mo-colour .cl-sw{ background:var(--pathway) }
  .mo-light .lt-ray{ transform:rotate(calc(-24deg + var(--i) * 16deg)) }
  .theatre.is-why .th-row::after{ transform:none }
}

/* ───────────────────────────────────────────────────────────────
   GLOSSARY
   Anything named is a handle. Hover or focus opens the card, click
   pins it. What it says about a term is mostly derived from the
   chart data, so the card can speak about any of 2,265 names.
   ─────────────────────────────────────────────────────────────── */

[data-term]{ position:relative }
.st-body [data-term]{ cursor:help }
/* a dotted rule under a name is the whole affordance */
.st-caption b[data-term],.rc[data-term],.cbox[data-term]{
  text-decoration:underline dotted #c3bcab 1.5px; text-underline-offset:3px;
  transition:text-decoration-color .2s, color .2s;
}
.st-caption b[data-term]:hover,.rc[data-term]:hover,.cbox[data-term]:hover,
.st-caption b.term-on,.rc.term-on,.cbox.term-on{ text-decoration-color:var(--pathway) }
.mol[data-term]::after,.th-enz[data-term]::after{
  content:''; position:absolute; left:14%; right:14%; bottom:5px; height:1.5px;
  background:repeating-linear-gradient(90deg,#c3bcab 0 2px,transparent 2px 4px);
  opacity:0; transition:opacity .2s;
}
.mol[data-term]:hover::after,.th-enz[data-term]:hover::after,
.mol.term-on::after,.th-enz.term-on::after{ opacity:1 }
.th-enz[data-term]{ position:relative; padding-bottom:4px }
[data-term]:focus-visible{ outline:2px solid var(--pathway); outline-offset:3px }
.mol.term-on{ border-color:var(--pathway) }
.th-enz.term-on{ color:var(--pathway) }

.gl-card{
  position:fixed; z-index:120; width:min(380px,calc(100vw - 20px));
  max-height:min(62vh,520px); overflow-y:auto; overscroll-behavior:contain;
  padding:14px 16px 13px; background:var(--paper); color:var(--ink);
  border:1.5px solid var(--ink); box-shadow:0 14px 34px rgba(35,31,33,.17);
  opacity:0; transform:translateY(5px); transition:opacity .16s var(--ease), transform .16s var(--ease);
}
.gl-card.in{ opacity:1; transform:none }
.gl-card[hidden]{ display:none }
/* the pointer sits on whichever edge faces the term */
.gl-card::after{
  content:''; position:absolute; left:var(--arrow,50%); bottom:-7px; margin-left:-7px;
  border:7px solid transparent; border-top-color:var(--paper);
  filter:drop-shadow(0 1.5px 0 var(--ink));
}
.gl-card.is-below::after{ bottom:auto; top:-7px;
  border-top-color:transparent; border-bottom-color:var(--paper);
  filter:drop-shadow(0 -1.5px 0 var(--ink)); }

.gl-head{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; margin-bottom:8px }
.gl-kind{
  font-family:'Plex Mono',monospace; font-size:9px; letter-spacing:.13em; text-transform:uppercase;
  padding:2px 6px; border:1px solid currentColor; flex:none;
}
.gl-enzyme{ color:var(--enzyme) }
.gl-compound{ color:var(--ink) }
.gl-cofactor{ color:var(--inhibit) }
.gl-name{
  font-size:16px; font-weight:800; font-stretch:92%; letter-spacing:-.012em;
  line-height:1.2; flex:1 1 auto; min-width:0;
}
.gl-sq{ font-size:10px; color:var(--pathway); flex:none }

.gl-what{ margin:0 0 7px; font-size:14.5px; line-height:1.45 }
.gl-what b{ font-weight:700 }
.gl-more{ margin:0 0 9px; font-size:12.5px; line-height:1.5; color:#5c5648 }
.gl-fam{ margin:0 0 9px; font-size:11px; line-height:1.4; color:#938b7c; font-style:italic }

.gl-facts{ border-top:1px solid var(--paper-line); padding-top:9px }
.gl-facts:empty{ display:none }
.gl-row{
  display:grid; grid-template-columns:auto 1fr; gap:2px 9px; align-items:baseline;
  margin:0 0 6px; font-size:12px; line-height:1.4;
}
.gl-row:last-child{ margin-bottom:0 }
.gl-lab{
  font-family:'Plex Mono',monospace; font-size:9px; letter-spacing:.1em; text-transform:uppercase;
  color:#a39b8c; white-space:nowrap; padding-top:1px;
}
.gl-row i{ color:var(--pathway); font-style:normal }
.gl-row em{ grid-column:2; font-size:10.5px; font-style:normal; color:#938b7c }
.gl-note{
  margin:0 0 7px; padding-left:9px; border-left:2px solid var(--paper-line);
  font-size:12px; line-height:1.45; color:#5c5648;
}
.gl-in span:not(.gl-lab){ color:#5c5648 }

@media (max-width:760px){
  .gl-card{ width:calc(100vw - 20px); max-height:54vh; padding:13px 14px }
  .gl-name{ font-size:15px }
}
@media (prefers-reduced-motion:reduce){
  .gl-card{ transition:none }
}
