/* ═══════════════════════════════════════════════════════════════════════════
   MULTIPLIKATORN — fem in, tjugo ut

   Ersatte stillbilden bilder/femtill20.jpg och kamerarundturen över den
   (js/kraftur.js, css/kraftdemo.css) - alla tre borttagna i samma ändring.
   Skälet: bilden gick inte att läsa utan att zooma, och zoomningen var i sin
   tur därför rundturen fanns. En vy som är byggd i markup behöver ingen
   kamera - den är läsbar i sin helhet direkt, skarp på varje skärm, och
   berättar sitt förlopp genom att FAKTISKT flöda.

   FÖRLOPPET ÄR BUDSKAPET. Fem personer matar in, systemet arbetar, tjugo
   personers kapacitet kommer ut. Animationen visar just den multiplikationen:
   fem pulser in, tjugo punkter ut. Ingen dekoration som inte bär den meningen.

   TEKNIKEN ÄR STROKE-DASHOFFSET, inte partiklar längs offset-path. En kort
   streckmask som glider längs en kurva ger samma "energi rör sig"-intryck,
   fungerar utan undantag i alla webbläsare vi bryr oss om, och animerar en
   egenskap webbläsaren kan hantera billigt. offset-path hade krävt en
   fallback-väg för äldre Safari; det här behöver ingen.

   TAKTEN DRIVS AV EN KLASS PÅ ROTEN. js/multiplikator.js sätter .kor när
   sektionen kommer i vy och spelar om varvet så länge den syns. CSS:en äger
   hela koreografin via animation-delay - det finns ingen tidslinje i JS som
   kan glida ur fas med den i CSS. Kärnans egen puls ligger UTANFÖR .kor och
   pågår oavbrutet; se "Två lager rörelse" längre ner för varför.
   ═══════════════════════════════════════════════════════════════════════════ */

.mx {
  /* Varvets längd. CSS-animationerna räknar sina procent mot den här, och
     js/multiplikator.js läser ut den i stället för att bära en egen kopia -
     två tal som ska vara lika är ett tal som förr eller senare inte är det.

     13s -> 20s. Berättelsen hann inte läsas: hela förloppet fem in, systemet
     arbetar, tjugo ut spelade på 3,6s och sedan drog kameran iväg. Man såg
     att något hände men hann aldrig läsa VAD som blev resultatet. Nu tar
     akten 4,6s och står sedan stilla i knappt tre sekunder innan dyket - det
     är i den pausen man läser "20 personers kapacitet". */
  --mx-varv: 20s;
  position: relative;
  margin-top: 2.2rem;
  border: 1px solid var(--line);
  border-radius: 24px;
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(79, 195, 255, .10), transparent 62%),
    linear-gradient(180deg, #0a1247, #070d33);
  overflow: hidden;
  padding: clamp(1rem, 2.2vw, 2rem);
}

/* Ljusstråket längs överkanten - samma gest som korten på resten av sajten. */
.mx::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(120, 180, 255, .55), transparent);
}

.mx-svg {
  display: block;
  width: 100%;
  height: auto;
}

/* ── Scenen: två lager ovanpå varandra ───────────────────────────────────
   Världslagret ligger i flödet och bestämmer figurens höjd. Motorlagret är
   absolut positionerat ovanpå och tar ingen plats - den ska ju vara på exakt
   samma yta, bara mycket längre in. */
.mx-scen { position: relative; }
.mx-lager-motor { position: absolute; inset: 0; }
.mx-lager-motor > .mx-svg { height: 100%; }

/* ── Två layouter, en berättelse ──────────────────────────────────────────
   Den breda vyn går inte att krympa till en telefon. Vid 390px blir dess
   text fem pixlar hög - exakt den svaghet som fällde JPG:en den ersätter.
   Därför finns en staplad variant med egen viewBox, genererad ur samma
   källa så de aldrig kan glida isär.

   Det är display, inte visibility eller opacity: den bortvalda varianten ska
   varken ta plats, målas eller animeras. */
.mx-mobil { display: none; }
@media (max-width: 860px) {
  .mx-svg:not(.mx-mobil) { display: none; }
  .mx-mobil { display: block; }
}

/* ── Två lager rörelse ────────────────────────────────────────────────────
   TAKTEN (.kor) är berättelsen: fem tänds, banden dras, tjugo fylls. Den har
   en början och ett slut och spelas om varv efter varv.

   PULSEN (utan .kor) är kärnan som arbetar. Den startar när sidan laddas och
   stannar aldrig - inte mellan varven, inte medan man läser. Det är just den
   uthålligheten som säger "dygnet runt".

   Att hålla isär dem är inte en stilfråga. Låg man rotationen under .kor
   skulle den nollställas vid varje nytt varv, och ringen skulle rycka tillbaka
   till utgångsläget var åttonde sekund - synligt, och precis tvärtemot det
   bilden påstår.

   Utan JS står takt-lagret kvar i sitt SLUTLÄGE, inte tomt: bilden ska vara
   hel och läsbar i en skärmläsare och i en utskrift. */
.mx-person, .mx-punkt, .mx-etikett, .mx-resultat, .mx-band { opacity: 1; }

/* ── Takten ──────────────────────────────────────────────────────────────── */
/* Varaktigheterna följer med den utsträckta takten: ett steg som tar .5s att
   tona in men står kvar dubbelt så länge innan nästa läses som en tvekan,
   inte som ett lugnare tempo. */
.mx.kor .mx-person   { animation: mx-tand .75s cubic-bezier(.2,.8,.3,1) backwards; }
.mx.kor .mx-etikett  { animation: mx-tand .7s ease-out backwards; }
.mx.kor .mx-band     { animation: mx-band 1.0s ease-out backwards; }
.mx.kor .mx-punkt    { animation: mx-punkt .6s cubic-bezier(.2,.9,.3,1) backwards; }
.mx.kor .mx-resultat { animation: mx-tand .85s cubic-bezier(.2,.8,.3,1) backwards; }
.mx-puls             { animation: mx-puls 1.6s linear infinite backwards; opacity: 0; }

@keyframes mx-tand {
  from { opacity: 0; transform: translateX(-14px); }
  to   { opacity: 1; transform: none; }
}
@keyframes mx-band {
  from { opacity: 0; stroke-dashoffset: 260; }
  to   { opacity: 1; stroke-dashoffset: 0; }
}
@keyframes mx-punkt {
  from { opacity: 0; transform: scale(.3); }
  to   { opacity: 1; transform: none; }
}

/* Pulsen: en kort streckmask som vandrar hela banan och slocknar i ändarna,
   så den aldrig "hoppar" tillbaka till start medan den syns. */
@keyframes mx-puls {
  0%        { opacity: 0; stroke-dashoffset: 300; }
  12%, 82%  { opacity: 1; }
  100%      { opacity: 0; stroke-dashoffset: 0; }
}

/* ── Kärnan: ett team i arbete ───────────────────────────────────────────
   Allt i det här blocket löper OAVBRUTET och osynkroniserat. Det är hela
   poängen: rörelsen har ingen början och inget slut, den bara pågår, och det
   är den som säger "dygnet runt" - inte bildtexten under.

   Allt roterar kring samma punkt. Talen är viewBox-koordinater, inte pixlar
   på skärmen: för SVG-element är transform-box: view-box förvalt, så origo
   följer med när bilden skalas. Därför överlever den här raden att vyn ritas
   i halva storleken på en telefon. */
.mx-karna [class^="mx-"], .mx-karna { transform-origin: 580px 262px; }
.mx-karna-m [class^="mx-"], .mx-karna-m { transform-origin: 210px 452px; }

/* Ringarna går åt var sitt håll och i olika takt. Två ringar åt samma håll
   hade lästs som en enda tjock ring. */
.mx-ring-yttre { animation: mx-snurr 44s linear infinite; }
.mx-ring-inre  { animation: mx-snurr 26s linear infinite reverse; }
@keyframes mx-snurr { to { transform: rotate(360deg); } }

/* Omloppsbanan. Långsam - agenterna ska verka arbeta, inte snurra runt. */
.mx-bana { animation: mx-snurr 38s linear infinite; }

/* Varje agent lyser upp när den "tar ett pass". Sex noder med förskjuten fas
   ger ett flimmer av aktivitet som aldrig upprepar sig synligt. */
.mx-agent {
  animation: mx-arbetar 3.4s ease-in-out infinite;
  animation-delay: calc(var(--a) * -.57s);   /* negativ: fasen är redan igång */
  transform-origin: center;
}
@keyframes mx-arbetar {
  0%, 100% { opacity: .5; }
  45%      { opacity: 1; }
}
.mx-nod-glod {
  animation: mx-nodpuls 3.4s ease-in-out infinite;
  animation-delay: calc(var(--a) * -.57s);
}
@keyframes mx-nodpuls {
  0%, 100% { opacity: .12; }
  45%      { opacity: .85; }
}

/* Ljuset ut längs ekern, i takt med att agenten lyser upp. Samma delay som
   noden, så det läser som ETT skeende: kärnan skickar, agenten tänds. */
.mx-eker-puls {
  animation: mx-eker 3.4s ease-in-out infinite;
  animation-delay: calc(var(--a) * -.57s);
}
@keyframes mx-eker {
  0%        { stroke-dashoffset: var(--l); opacity: 0; }
  18%       { opacity: .95; }
  55%       { stroke-dashoffset: 0; opacity: .95; }
  70%, 100% { stroke-dashoffset: 0; opacity: 0; }
}

/* Kärnpunkten slår långsammare än agenterna - den är navet de arbetar mot.
   Ringen kring den går åt motsatt håll mot omloppsbanan, så navet aldrig ser
   ut att dras med av agenterna. */
.mx-hjarta-ring { animation: mx-snurr 12s linear infinite reverse; }
.mx-hjarta-glod { animation: mx-andas 2.6s ease-in-out infinite; }
.mx-glod        { animation: mx-andas 5.2s ease-in-out infinite; }
@keyframes mx-andas {
  0%, 100% { opacity: .38; transform: scale(1); }
  50%      { opacity: .95; transform: scale(1.07); }
}

/* Statuslampan. Enda gröna i hela vyn, och den enda rörelse som är en ren
   signal snarare än en illustration: systemet kör just nu. */
.mx-lampa { animation: mx-lampa 2.2s ease-in-out infinite; }
@keyframes mx-lampa {
  0%, 100% { opacity: 1; }
  50%      { opacity: .25; }
}

/* ── Sekvensen ───────────────────────────────────────────────────────────
   En enda plats där tiderna bor. Ändra här, inte i markup.

   UTSTRÄCKT FÖR ATT KUNNA LÄSAS. Förloppet gick förut på 3,6s: personerna
   var uppe på en halv sekund, banden dragna vid 1,4 och de tjugo fyllda vid
   3,1 - sedan drog kameran iväg. Ögat hann se att något rörde sig men inte
   läsa vad. Varje steg har nu ungefär dubbla tiden, och --d-värdena i
   markupen skalas med --mx-takt i stället för att skrivas om på tio ställen.

   Ny tidtabell: personerna 0,15-1,05s · banden 1,3-2,3 · de tjugo 2,8-4,6 ·
   sedan står bilden stilla till 7,5 innan dyket börjar. */
.mx { --mx-takt: 1.65; }
.mx.kor .mx-person   { animation-delay: calc(.15s + var(--i) * .22s); }
.mx.kor .mx-etikett  { animation-delay: calc(var(--d) * var(--mx-takt)); }
/* Resultatrutan följer INTE takten, den har en egen tid. Skalad med 1.65
   landade den på 3,14s medan räknaren i js/multiplikator.js börjar skriva
   vid 2,80 - siffran räknade alltså en tredjedels sekund innan den syntes.
   2,30 sätter upp rutan först och låter talet räknas i den. */
.mx.kor .mx-resultat { animation-delay: 2.30s; }
.mx.kor .mx-band     { animation-delay: 1.30s; }

/* Pulserna bär sitt index i markup i ordningen 0,3,1,4,2 - inte 0..4. Ett
   jämnt intervall hade lett som en maskin som tickar; det här läser som fem
   personer som arbetar var för sig. */
.mx-puls-in  { animation-delay: calc(2.10s + var(--i) * .18s); }
.mx-puls-ut  { animation-delay: calc(3.10s + var(--i) * .15s); }

/* Punkterna fylls i fyra vågor om fem - multiplikationen syns i takten.
   .09s per punkt i stället för .055: tjugo punkter tar nu 1,8s att fylla,
   och det är den takten räknaren i js/multiplikator.js speglar. */
.mx.kor .mx-punkt    { animation-delay: calc(2.80s + var(--i) * .09s); }

.mx-tal { font-variant-numeric: tabular-nums; }

/* ── Bildtexten under vyn ───────────────────────────────────────────────── */
.mx-fot {
  margin-top: 1.1rem;
  display: flex;
  flex-wrap: wrap;
  gap: .5rem 1.6rem;
  color: var(--muted);
  font-size: .88rem;
}
.mx-fot b { color: var(--text); font-weight: 600; }

/* ── Mobil ───────────────────────────────────────────────────────────────
   Under 760px staplas vyn: SVG:n byter viewBox via JS-fri media-regel går
   inte, så i stället skalas den och de tre zonerna får mer luft genom att
   ramen tappar sin padding. Texten i SVG:n är redan satt i px mot viewBox,
   alltså skalar den med bilden och förblir läsbar. */
@media (max-width: 760px) {
  .mx { border-radius: 18px; padding: .7rem; }
  .mx-fot { font-size: .82rem; gap: .4rem 1rem; }
}

/* ── Reducerad rörelse ───────────────────────────────────────────────────
   Slutläget, direkt och stillastående. Vyn är fullt läsbar utan förloppet -
   det är därför grundtillståndet ovan är slutläget och inte ett tomt fält. */
@media (prefers-reduced-motion: reduce) {
  /* ALLT, inte en lista. Den här regeln var tidigare en uppräkning av de
     klasser som fanns när den skrevs, och varje lager som tillkommit sedan
     dess - omloppsbanan, agenterna, ekerljusen, statuslampan och hela
     motorns insida - fortsatte röra sig för den som uttryckligen bett om att
     slippa rörelse. En uppräkning måste underhållas; det här behöver inte det.

     Selektorn täcker även .mx själv, eftersom en animation kan sitta där. */
  .mx, .mx *, .mx *::before, .mx *::after { animation: none !important; }

  /* Kvar står slutläget: översikten hel och läsbar, motorn stängd, och inga
     ljuspulser liggande halvvägs längs sina banor. */
  .mx-puls, .mx-eker-puls, .mx-m-ut, .mx-m-in { opacity: 0; }
  .mx-lager-motor { opacity: 0; }
  .mx-lager-varld { opacity: 1; transform: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   DYKET — kameran åker in i motorn

   Andra halvan av varvet. Översikten har visat VAD som händer; dyket visar
   VEM som gör det. Kameran åker rakt in genom kärnan och ut på insidan, där
   de sex agenterna står och arbetar var för sig.

   DET ÄR EN KAMERARÖRELSE, INTE EN ÖVERTONING. Båda lagren skalas kring exakt
   samma punkt - kärnans mitt, 580/262 - och rör sig åt samma håll samtidigt:
   världen växer förbi betraktaren medan motorn växer fram bakom den. Hade de
   bara tonat över varandra vore det två bilder efter varandra; nu är det en
   enda rörelse genom ett djup.

   Accelerationen bär illusionen. Världen far iväg med ease-in (långsam start,
   snabbt slut - man lämnar den), motorn kommer emot med ease-out (snabb
   ankomst som bromsar in). Samma kurva åt båda hållen hade känts som en
   skjutdörr.

   ARBETET INUTI LIGGER UTANFÖR .kor, precis som kärnans puls i översikten:
   bågarna, ekerljusen, lamporna och uppgiftsraderna löper i sin egen takt och
   återstartar aldrig med varvet. Kameran är det enda som följer .kor.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Kärnan ligger mitt i desktopvariantens viewBox, så origo är helt enkelt
   mitten av lagret. Mobilvariantens kärna sitter högre upp i sin egen, längre
   viewBox (452 av 1062) - kameran måste åka in GENOM kärnan, annars blir
   dyket en zoom mot ingenting. */
.mx-lager { transform-origin: 50% 50%; }
@media (max-width: 860px) { .mx-lager { transform-origin: 50% 42.6%; } }
.mx-lager-motor { opacity: 0; }

/* will-change bara medan varvet går, inte permanent: den befordrar lagret till
   en egen kompositoryta, och två ytor i den här storleken är inget att hålla
   liggande på en telefon som scrollar förbi resten av sidan. Kostnaden syns i
   dyket, där SVG-filtren måste ritas om för varje skalsteg. */
.mx.kor .mx-lager-varld { animation: mx-varld-bort var(--mx-varv) both; will-change: transform, opacity; }
.mx.kor .mx-lager-motor { animation: mx-motor-fram var(--mx-varv) both; will-change: transform, opacity; }

/* Procenten är räknade mot --mx-varv (20s):
   0-37.5%     översikten spelar OCH STÅR STILLA               (0 - 7.5s)
   37.5-44%    dyket in                                        (7.5 - 8.8s)
   44-82.5%    inne i motorn                                   (8.8 - 16.5s)
   82.5-88.5%  dyket ut                                        (16.5 - 17.7s)
   88.5-100%   översikten står kvar igen                       (17.7 - 20.0s)

   PAUSEN FÖRE DYKET VAR KORT MED FLIT OCH BLEV FEL. De tjugo är fyllda vid
   4,6s och kameran drog förut iväg en halv sekund senare - man hann se att
   något hände men inte läsa vad det blev. Nu står den färdiga bilden stilla i
   2,9 sekunder. Det är i den pausen hela poängen läses: fem matar in, tjugo
   kommer ut.

   VISIBILITY ÄR INTE DEKORATION UTAN PRESTANDA. Uppmätt låg 163 element och
   animerade samtidigt, varav 96 inne i motorlagret - som har opacity 0 under
   halva varvet. Webbläsaren ritade alltså nittiosex animationer ingen kunde
   se, och det var det som ryckte. opacity 0 räcker inte: lagret finns kvar i
   renderingsträdet och dess animationer tickar vidare. visibility: hidden
   plockar bort hela underträdet ur både målning och animering.

   Nu löper bara ETT av lagren åt gången. Enligt spec blir visibility synligt
   direkt när intervallet mot ett visible-värde börjar, så lagret är vaket när
   dyket startar och släcks först när det är helt borta - ingen ruta där något
   saknas. */
@keyframes mx-varld-bort {
  0%, 37.5% { transform: scale(1); opacity: 1; visibility: visible; }
  44%       { transform: scale(6.2); opacity: 0; visibility: hidden; animation-timing-function: cubic-bezier(.55,0,.9,.35); }
  82.5%     { transform: scale(6.2); opacity: 0; visibility: hidden; }
  88.5%     { transform: scale(1); opacity: 1; visibility: visible; animation-timing-function: cubic-bezier(.16,1,.3,1); }
  100%      { transform: scale(1); opacity: 1; visibility: visible; }
}
@keyframes mx-motor-fram {
  0%, 37.5% { transform: scale(.16); opacity: 0; visibility: hidden; }
  44%       { transform: scale(1); opacity: 1; visibility: visible; animation-timing-function: cubic-bezier(.14,.9,.25,1); }
  82.5%     { transform: scale(1); opacity: 1; visibility: visible; }
  88.5%     { transform: scale(.16); opacity: 0; visibility: hidden; animation-timing-function: cubic-bezier(.55,0,.9,.35); }
  100%      { transform: scale(.16); opacity: 0; visibility: hidden; }
}

/* ── Arbetet inuti ────────────────────────────────────────────────────────── */

/* Bågen runt varje agent fylls och töms: ett pass som börjar och blir klart.
   Sex agenter med förskjuten fas gör att något alltid är på gång någonstans -
   det är den osynkroniserade takten som läser som arbete och inte som en
   maskin som tickar. */
.mx-m-bage {
  animation: mx-bage 5.4s cubic-bezier(.5,0,.5,1) infinite;
  animation-delay: calc(var(--a) * -.83s);
}
@keyframes mx-bage {
  0%       { stroke-dashoffset: 251; }
  62%      { stroke-dashoffset: 0; }
  74%,100% { stroke-dashoffset: -251; }
}

/* Ljuset ut till agenten, och svaret tillbaka. Riktningen är hela poängen:
   navet delar ut, agenten levererar. Svaret är grönt - den enda färg i vyn
   som betyder "klart". */
.mx-m-ut {
  animation: mx-arm 5.4s ease-in-out infinite;
  animation-delay: calc(var(--a) * -.83s);
}
.mx-m-in {
  animation: mx-arm 5.4s ease-in-out infinite;
  animation-delay: calc(var(--a) * -.83s + 2.4s);
}
@keyframes mx-arm {
  0%       { stroke-dashoffset: var(--l); opacity: 0; }
  12%      { opacity: 1; }
  46%      { stroke-dashoffset: 0; opacity: 1; }
  60%,100% { stroke-dashoffset: 0; opacity: 0; }
}

/* Uppgiftsraden. Tre texter på samma plats, var sin tredjedel av cykeln, med
   en kort överlappning så bytet blir ett tonskifte och inte ett hopp. */
.mx-m-txt {
  opacity: 0;
  animation: mx-uppgift 5.4s ease-in-out infinite;
  animation-delay: calc(var(--a) * -.83s + var(--j) * 1.8s);
}
@keyframes mx-uppgift {
  0%          { opacity: 0; }
  4%, 29%     { opacity: 1; }
  33%, 100%   { opacity: 0; }
}

.mx-m-glod {
  animation: mx-m-andas 3.6s ease-in-out infinite;
  animation-delay: calc(var(--a) * -.6s);
}
@keyframes mx-m-andas {
  0%, 100% { opacity: .12; }
  50%      { opacity: .5; }
}

.mx-m-lampa {
  animation: mx-lampa 2.2s ease-in-out infinite;
  animation-delay: calc(var(--a) * -.37s);
}

.mx-m-navglod { animation: mx-andas 3.2s ease-in-out infinite; transform-origin: 580px 262px; }
.mx-m-navring { animation: mx-snurr 18s linear infinite; transform-origin: 580px 262px; }
.mx-m-ring    { animation: mx-snurr 60s linear infinite reverse; transform-origin: 580px 262px; }
.mx-motor-m .mx-m-navglod,
.mx-motor-m .mx-m-navring,
.mx-motor-m .mx-m-ring { transform-origin: 210px 430px; }

/* Rubriken inne i motorn kommer en gnutta efter kameran: den ska landa när
   man redan är inne, inte flyga in tillsammans med väggarna. */
.mx.kor .mx-m-rubrik { animation: mx-m-rubrik var(--mx-varv) both; }
@keyframes mx-m-rubrik {
  0%, 40%   { opacity: 0; transform: translateY(-8px); }
  48%, 80%  { opacity: 1; transform: none; }
  86%, 100% { opacity: 0; transform: translateY(-8px); }
}

/* ── Sidopanelerna inne i motorn ──────────────────────────────────────────
   Panelerna kommer in EFTER kameran, förskjutet mot varandra. Allt som anländer
   samtidigt läses som en enda bild som tonar upp; anländer det i tur och ordning
   läses det som ett rum man kommer in i och hinner se sig omkring i. */
.mx.kor .mx-m-vanster { animation: mx-m-panel-v var(--mx-varv) both; }
.mx.kor .mx-m-hoger   { animation: mx-m-panel-h var(--mx-varv) both; }
@keyframes mx-m-panel-v {
  0%, 42%   { opacity: 0; transform: translateX(-22px); }
  50%, 80%  { opacity: 1; transform: none; }
  86%, 100% { opacity: 0; transform: translateX(-22px); }
}
@keyframes mx-m-panel-h {
  0%, 44%   { opacity: 0; transform: translateX(22px); }
  52%, 80%  { opacity: 1; transform: none; }
  86%, 100% { opacity: 0; transform: translateX(22px); }
}

/* Händelseraderna tänds en i taget och blir kvar tända - en ström som fylls
   på, inte ett blinkande ljusspel. Deltat under varje tal pulserar svagt av
   samma skäl: det ska antyda att siffran är på väg någonstans. */
.mx-m-rad {
  animation: mx-m-rad 5.4s ease-out infinite;
  animation-delay: calc(var(--k) * .42s);
}
@keyframes mx-m-rad {
  0%       { opacity: 0; transform: translateY(9px); }
  9%, 88%  { opacity: 1; transform: none; }
  100%     { opacity: 0; transform: translateY(-6px); }
}
.mx-m-delta {
  animation: mx-m-delta 4.2s ease-in-out infinite;
  animation-delay: calc(var(--k) * -1.1s);
}
@keyframes mx-m-delta {
  0%, 100% { opacity: .35; }
  50%      { opacity: 1; }
}


/* ── Samarbetet mellan agenterna ──────────────────────────────────────────
   Paketen glider från agent till agent längs ringen och bär MOTTAGARENS färg,
   så man ser vart något är på väg innan det kommit fram. De går i en annan
   takt än ekrarna in mot navet - två rytmer som inte delar nämnare gör att
   bilden aldrig hamnar i lås och börjar se ut som en slinga. */
.mx-m-paket {
  animation: mx-m-paket 4.1s cubic-bezier(.45,0,.55,1) infinite;
  animation-delay: calc(var(--k) * -.71s);
}
@keyframes mx-m-paket {
  0%       { stroke-dashoffset: var(--b); opacity: 0; }
  10%      { opacity: 1; }
  52%      { stroke-dashoffset: 0; opacity: 1; }
  62%,100% { stroke-dashoffset: 0; opacity: 0; }
}

/* Genomströmningsringen i navet fylls om och om igen. Ett tal hade behövt
   vara sant; en ring som bara går säger samma sak utan att påstå något. */
.mx-m-flode { animation: mx-m-flode 2.9s cubic-bezier(.4,0,.6,1) infinite; }
@keyframes mx-m-flode {
  0%       { stroke-dashoffset: 302; opacity: .25; }
  55%      { stroke-dashoffset: 0; opacity: .9; }
  70%,100% { stroke-dashoffset: -302; opacity: 0; }
}
