/* Gewebe-Hintergrund, Ressourcen, Viren, Antikörper – ebenfalls reines CSS */
#bg {
  position: absolute; left: 0; top: 0; overflow: hidden;
  background:
    radial-gradient(ellipse at 28% 22%, #3a3f93 0, transparent 55%),
    radial-gradient(ellipse at 76% 72%, #2c3280 0, transparent 60%),
    linear-gradient(160deg, #1d2559, #131b3d 60%, #1b1753);
  box-shadow: inset 0 0 0 8px rgba(255, 255, 255, .06), inset 0 0 140px 30px rgba(0, 0, 0, .5);
}
#bg::before {                                                       /* Fasern der extrazellulären Matrix */
  content: ""; position: absolute; inset: 0;
  background: repeating-linear-gradient(115deg, transparent 0 90px, rgba(255, 255, 255, .028) 90px 92px);
}
.bgcell {
  position: absolute; border-radius: var(--br, 46% 54% 50% 50% / 52% 48% 52% 48%); rotate: var(--r);
  background: radial-gradient(circle at 40% 35%, hsl(var(--bh, 232) 70% 72% / .17), hsl(var(--bh, 232) 50% 55% / .09) 70%);
  border: 3px solid hsl(var(--bh, 232) 80% 78% / .12);
}
.bgcell::after {                                                   /* Zellkern der Nachbarzelle, nicht mittig und nicht rund */
  content: ""; position: absolute; left: var(--nx, 34%); top: var(--ny, 34%); width: 26%; height: 22%;
  border-radius: 56% 44% 50% 50% / 48% 56% 44% 52%; background: hsl(var(--bh, 232) 60% 66% / .15);
}
.bgcell.live { animation: bgFloat var(--bt, 30s) ease-in-out var(--bd, 0s) infinite alternate; }
@keyframes bgFloat {
  from { translate: 0 0; rotate: var(--r); }
  to { translate: var(--bx, 16px) var(--by, -12px); rotate: calc(var(--r) + 7deg); scale: 1.035; }
}
.dust {                                                            /* treibende Bläschen und Schwebeteilchen im Gewebe */
  position: absolute; width: var(--sz); height: var(--sz); border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, rgba(200, 210, 255, .5), rgba(120, 140, 255, .1));
  animation: dust var(--dur) ease-in-out var(--dl) infinite alternate;
}
@keyframes dust { to { translate: var(--dx) var(--dy); opacity: .35; } }

#ents { position: absolute; inset: 0; z-index: 2; }
#floats { position: absolute; inset: 0; z-index: 6; pointer-events: none; }   /* schwebende Zahlen: vor Zelle und Teilchen */
.ent { position: absolute; left: 0; top: 0; display: grid; place-items: center; will-change: transform; pointer-events: none; }
.ent.v { z-index: 4; }

/* Teilchen und Moleküle: Größe über --s (Schriftgröße), alles in em */
.res { position: relative; display: block; width: 1em; height: 1em; font-size: var(--s, 22px); line-height: 1; font-style: normal; flex: none; }
.res span {
  position: relative; z-index: 1; display: grid; place-items: center; width: 100%; height: 100%;
  font-size: .4em; font-weight: 800; color: #05324d; font-style: normal;
}

/* Eigenbewegung der Teilchen: jede Sorte schwingt anders (Dauer --d und Startversatz --dl sind je Teilchen zufällig).
   Drehungen laufen über die Eigenschaft rotate, Pulsieren über transform – so bleibt scale für die Vorschau frei. */
.res.glucose, .res.fattyAcids, .res.lipid, .res.antibody { animation: sway var(--d, 3.5s) ease-in-out var(--dl, 0s) infinite alternate; }
.res.aminoAcids { animation: wiggle calc(var(--d, 3s) * .6) ease-in-out var(--dl, 0s) infinite alternate; }
.res.nucleotides { animation: tumble calc(var(--d, 3s) * 3) linear var(--dl, 0s) infinite; }
.res.oxygen, .res.foldedProtein { animation: bubble var(--d, 3s) ease-in-out var(--dl, 0s) infinite alternate; }
.res.atp { animation: flicker .8s ease-in-out var(--dl, 0s) infinite alternate; }
.res.mrna { animation: undulate calc(var(--d, 3s) * .7) ease-in-out var(--dl, 0s) infinite alternate; }
.res.protein { animation: blobSmall calc(var(--d, 3s) * .9) ease-in-out var(--dl, 0s) infinite; }
@keyframes sway { from { rotate: -12deg; } to { rotate: 12deg; } }
@keyframes wiggle { from { rotate: -16deg; } to { rotate: 16deg; } }
@keyframes tumble { to { rotate: 360deg; } }
@keyframes bubble { from { transform: scale(.92); } to { transform: scale(1.1) translateY(-.06em); } }
@keyframes flicker { from { transform: scale(.94); filter: brightness(.95); } to { transform: scale(1.08); filter: brightness(1.3); } }
@keyframes undulate { from { rotate: -14deg; } to { rotate: -2deg; } }

/* Glukose: Sechseck */
.res.glucose, .res.glucose::after { clip-path: polygon(25% 3%, 75% 3%, 100% 50%, 75% 97%, 25% 97%, 0 50%); }
.res.glucose { background: #b86a00; }
.res.glucose::after { content: ""; position: absolute; inset: .13em; background: linear-gradient(135deg, #ffd36e, #f6a623); }

/* Aminosäure: Kugel mit Kettenenden */
.res.aminoAcids { width: .74em; height: .74em; margin: .13em; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #b3d8ff, #2f7de1 72%); box-shadow: 0 0 0 .06em #1c4f9a; }
.res.aminoAcids::before { content: ""; position: absolute; left: -.28em; top: .16em; width: .28em; height: .28em; border-radius: 50%; background: #5fa4f5; box-shadow: 0 0 0 .05em #1c4f9a; }
.res.aminoAcids::after { content: ""; position: absolute; right: -.26em; bottom: .04em; width: .28em; height: .28em; border-radius: 50%; background: #1c4f9a; }

/* Nukleotid: Phosphat (Kreis) – Zucker (Fünfeck) – Base (Balken) */
.res.nucleotides { height: .46em; margin: .27em 0; border-radius: .1em; background: linear-gradient(90deg, transparent 0 58%, #2fbf71 58% 100%); box-shadow: 0 0 0 .04em rgba(26, 127, 74, .0); }
.res.nucleotides::before { content: ""; position: absolute; left: 0; top: .08em; width: .3em; height: .3em; border-radius: 50%; background: #ffb347; box-shadow: 0 0 0 .04em #b36b00; }
.res.nucleotides::after { content: ""; position: absolute; left: .27em; top: -.02em; width: .36em; height: .5em; background: #e8f06a; clip-path: polygon(50% 0, 100% 38%, 82% 100%, 18% 100%, 0 38%); }

/* Fettsäure: Kopf + Kohlenwasserstoff-Schwanz */
.res.fattyAcids { width: .7em; margin-left: .3em; height: .32em; margin-top: .34em; border-radius: 0 .16em .16em 0; background: repeating-linear-gradient(90deg, #ffcf3f 0 .09em, #d99a00 .09em .18em); }
.res.fattyAcids::before { content: ""; position: absolute; left: -.3em; top: -.09em; width: .5em; height: .5em; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff1a8, #f2b800); box-shadow: 0 0 0 .05em #a87800; }

/* Sauerstoff: Bläschen */
.res.oxygen { width: .9em; height: .9em; margin: .05em; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff, #c6ecff 55%, #6cc0f0); box-shadow: 0 0 0 .06em #3a9ad6, 0 0 .4em rgba(108, 192, 240, .7); }
.res.oxygen span { font-size: .34em; }

/* ATP: Energieblitz */
.res.atp, .res.atp::after { clip-path: polygon(58% 0, 10% 56%, 44% 56%, 32% 100%, 90% 38%, 56% 38%); }
.res.atp { background: #d98500; }
.res.atp::after { content: ""; position: absolute; inset: .07em; background: linear-gradient(135deg, #fff58a, #ffc400); }

/* mRNA: Wellenband */
.res.mrna { height: .34em; margin-top: .33em; border-radius: .17em; rotate: -8deg; background: repeating-linear-gradient(90deg, #b36cf0 0 .1em, #7d3fc4 .1em .2em); box-shadow: 0 0 0 .04em #4a1f8a; }
.res.mrna::before { content: ""; position: absolute; left: -.05em; top: -.12em; width: .14em; height: .58em; border-radius: .07em; background: #e3b8ff; }

/* Protein: Klumpen */
.res.protein { width: .9em; height: .9em; margin: .05em; border-radius: 58% 42% 55% 45% / 48% 62% 38% 52%; background: radial-gradient(circle at 35% 30%, #ffc2dd, #e0408f 70%); box-shadow: 0 0 0 .05em #8f1c55; }
.res.protein::after { content: ""; position: absolute; left: .5em; top: .5em; width: .28em; height: .28em; border-radius: 50%; background: #ff7ab8; box-shadow: -.34em -.22em 0 -.04em #ff7ab8; }

/* gefaltetes Protein: Ringe */
.res.foldedProtein { width: .9em; height: .9em; margin: .05em; border-radius: 50%; background: repeating-radial-gradient(circle at 50% 50%, #ff9ccc 0 .09em, #c93a87 .09em .18em); box-shadow: 0 0 0 .05em #8f1c55; }

/* Membranlipid: Kopf mit zwei Schwänzen */
.res.lipid { width: .46em; height: .46em; margin: .02em .27em 0; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #fff1a8, #f2b800); box-shadow: 0 0 0 .05em #a87800; }
.res.lipid::before, .res.lipid::after { content: ""; position: absolute; top: .44em; width: .1em; height: .54em; border-radius: .05em; background: #d9a400; }
.res.lipid::before { left: .06em; }
.res.lipid::after { right: .06em; }

/* Antikörper: Y */
.res.antibody { background: linear-gradient(#1fb89a, #1fb89a) 50% 100% / .2em .55em no-repeat; }
.res.antibody::before, .res.antibody::after { content: ""; position: absolute; left: .4em; top: .02em; width: .2em; height: .58em; border-radius: .1em; background: #1fb89a; transform-origin: 50% 100%; box-shadow: 0 0 0 .03em #0b6b5a; }
.res.antibody::before { transform: rotate(-32deg); }
.res.antibody::after { transform: rotate(32deg); }
.res.antibody span { display: none; }

/* Virus: Kapsid (Sechseck) mit Spikes (Stern) und Erbgut */
.virus {
  position: relative; display: block; width: 1em; height: 1em; font-size: var(--s, 56px); font-style: normal; animation: spin 16s linear infinite;
  filter: drop-shadow(0 0 .08em rgba(255, 70, 100, .5));
}
.virus::before {
  animation: spikes var(--vd, 1.4s) ease-in-out var(--vl, 0s) infinite alternate;
  content: ""; position: absolute; inset: 0; background: #e35d70;
  clip-path: polygon(50% 0%, 58.5% 18.1%, 75% 6.7%, 73.3% 26.7%, 93.3% 25%, 81.9% 41.5%, 100% 50%, 81.9% 58.5%, 93.3% 75%, 73.3% 73.3%, 75% 93.3%, 58.5% 81.9%, 50% 100%, 41.5% 81.9%, 25% 93.3%, 26.7% 73.3%, 6.7% 75%, 18.1% 58.5%, 0% 50%, 18.1% 41.5%, 6.7% 25%, 26.7% 26.7%, 25% 6.7%, 41.5% 18.1%);
}
.virus::after {
  content: ""; position: absolute; inset: .2em; background: radial-gradient(circle at 40% 35%, #ff9aa8, #b3243d 72%);
  clip-path: polygon(50% 0, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%); animation: spinBack 22s linear infinite;
}
.virus b { position: absolute; z-index: 1; left: 50%; top: 50%; width: .18em; height: .18em; margin: -.09em 0 0 -.09em; border-radius: 50%; background: #fff3b0; box-shadow: 0 0 .2em #fff3b0; animation: coreGlow 1.2s ease-in-out infinite; }
@keyframes spin { to { rotate: 360deg; } }
@keyframes spinBack { to { rotate: -360deg; } }
@keyframes spikes { from { scale: .92; } to { scale: 1.08; rotate: 7deg; } }
@keyframes coreGlow { 50% { scale: 1.55; opacity: .7; } }

/* Bakterium: grünes Stäbchen (Zellwand, Nukleoid-Knäuel, Ribosomen-Punkte) mit Geißel. Resistent: dicke violette Doppelwand und Plasmid-Ring */
.bact {
  position: relative; display: block; width: 1em; height: 1em; font-size: var(--s, 48px); font-style: normal;
  filter: drop-shadow(0 0 .06em rgba(222, 240, 70, .6));
}
.bact::before {                                         /* Körper mit Zellwand */
  content: ""; position: absolute; left: .2em; right: .02em; top: .27em; bottom: .27em; border-radius: .23em;
  background:
    radial-gradient(circle, rgba(30, 70, 10, .55) 0 .018em, transparent .02em) 0 0 / .1em .1em,
    linear-gradient(#f4f78e, #bcd82e 55%, #84a014);
  box-shadow: 0 0 0 .04em #5c6e0b, inset 0 .035em .05em rgba(255, 255, 255, .5);
}
.bact b {                                               /* Nukleoid: frei liegendes, geknäueltes Erbgut */
  position: absolute; left: .36em; top: .36em; width: .34em; height: .28em; border-radius: 50%;
  border: .035em solid rgba(255, 246, 170, .9); border-top-color: transparent; border-left-color: rgba(255, 246, 170, .5); rotate: 20deg;
  animation: nucleoid calc(var(--bd, 1.2s) * 3) ease-in-out var(--bl, 0s) infinite alternate;
}
.bact span {                                            /* Geißel: wellt sich am hinteren Ende */
  position: absolute; left: -.02em; top: .38em; width: .26em; height: .24em; border-radius: 50%;
  border: .035em solid #5c6e0b; border-right-color: transparent; border-bottom-color: transparent; transform-origin: 100% 50%;
  animation: flagellum var(--bd, 1.2s) ease-in-out var(--bl, 0s) infinite alternate;
}
@keyframes nucleoid { to { rotate: 200deg; scale: 1.08; } }
@keyframes flagellum { from { rotate: -26deg; } to { rotate: 26deg; scale: 1 .8; } }
.bact.resist { filter: drop-shadow(0 0 .07em rgba(170, 90, 255, .75)); }
.bact.resist::before {
  background:
    radial-gradient(circle, rgba(40, 10, 70, .55) 0 .018em, transparent .02em) 0 0 / .1em .1em,
    linear-gradient(#cfa8ff, #8a4fd6 55%, #5b2a9c);
  box-shadow: 0 0 0 .05em #3d1a73, 0 0 0 .095em #b98aff, inset 0 .035em .05em rgba(255, 255, 255, .45);
}
.bact.resist b { border-color: #fff0a8; border-top-color: transparent; }
.bact.resist span { border-color: #6d37b8; border-right-color: transparent; border-bottom-color: transparent; }
.ent.marked .bact { filter: drop-shadow(0 0 .05em #2ee6a8) drop-shadow(0 0 .12em #2ee6a8); }
.ent.b::after { content: none; }
.ent.lysed { transition: none; }
.ent.lysed .bact { animation: lyse .9s ease-out forwards; }
@keyframes lyse { 0% { scale: 1; opacity: 1; filter: brightness(1.4); } 35% { scale: 1.35 .8; opacity: 1; filter: brightness(2) saturate(.4); } 100% { scale: 1.9 .3; opacity: 0; filter: blur(.05em); } }

/* Antikörper: leuchtende Spur hinter dem Y (die Spitze zeigt in Flugrichtung) */
.ent.ab::before {
  content: ""; position: absolute; left: 50%; top: 62%; width: 9px; height: 54px; margin-left: -4.5px; border-radius: 5px;
  background: linear-gradient(rgba(46, 230, 168, .6), transparent); z-index: -1;
}

/* Mutanten: achteckige Hülle und orange Stacheln (nicht nur die Farbe unterscheidet sie); .hit = ein Antikörper sitzt schon */
.ent.mutant .virus { filter: drop-shadow(0 0 .08em rgba(255, 170, 40, .65)); }
.ent.mutant .virus::before { background: #ffa63d; }
.ent.mutant .virus::after {
  background: radial-gradient(circle at 40% 35%, #ffe3a6, #c4650a 72%);
  clip-path: polygon(30% 0, 70% 0, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0 70%, 0 30%);
}
.ent.hit:not(.marked)::before { content: ""; position: absolute; inset: -5px; border-radius: 50%; border: 3px solid rgba(46, 230, 168, .55); }
.ent { transition: opacity 1.2s ease; }
.ent.gone { opacity: 0; }                      /* Tauchgang: Sauerstoff-Teilchen sind weg */

.ent.infecting .virus::after { background: radial-gradient(circle at 40% 35%, #e0b8ff, #7a2fc4 72%); }
.ent.marked .virus { filter: drop-shadow(0 0 .05em #2ee6a8) drop-shadow(0 0 .12em #2ee6a8); }
.ent.marked::before {
  content: ""; position: absolute; inset: -5px; border-radius: 50%; border: 3px dotted #2ee6a8; animation: spin 6s linear infinite;
}

/* Schwebende Zahlen */
.float {
  --k: 1;                                    /* gleicht den Kamera-Zoom aus (siehe js/entities.js) */
  position: absolute; font-weight: 800; font-size: calc(20px * var(--k)); color: #fff; pointer-events: none;
  text-shadow: 0 2px 4px rgba(0, 0, 0, .65); translate: -50% -50%; animation: floatUp 1.4s ease-out forwards;
}
/* Aufgenommener Stoff: Symbol + Menge in einer Plakette, damit man beim Fahren sieht, was und wie viel hereinkam */
.float.pick {
  display: inline-flex; align-items: center; gap: calc(5px * var(--k)); white-space: nowrap; line-height: 1;
  padding: calc(2px * var(--k)) calc(9px * var(--k)) calc(2px * var(--k)) calc(5px * var(--k)); font-size: calc(19px * var(--k));
  border-radius: 999px; border: calc(2px * var(--k)) solid currentColor; background: rgba(8, 12, 40, .84);
  box-shadow: 0 calc(3px * var(--k)) calc(10px * var(--k)) rgba(0, 0, 0, .5); text-shadow: none; letter-spacing: .3px;
  animation: pickUp 1.9s ease-out forwards;
}
.float.pick .res { flex: none; font-size: calc(17px * var(--k)); }
@keyframes pickUp {
  0% { scale: .6; opacity: 0; }
  10% { scale: 1.1; opacity: 1; }
  22% { scale: 1; }
  68% { opacity: 1; }
  100% { opacity: 0; translate: -50% calc(-50% - 60px * var(--k)); }
}
.float.dim { color: #d6d9ee; font-size: calc(16px * var(--k)); font-style: italic; }
.float.bad { color: var(--bad); }
.float.good { color: var(--good); }
.float.res-glucose { color: #ffd36e; }
.float.res-oxygen { color: #bfe9ff; }
.float.res-aminoAcids { color: #9cc9ff; }
.float.res-nucleotides { color: #8be8b4; }
.float.res-fattyAcids { color: #ffe27a; }
@keyframes floatUp { to { opacity: 0; translate: -50% -100px; } }

/* Pause friert alle Animationen in der Welt ein */
body.paused #world *, body.paused #world *::before, body.paused #world *::after { animation-play-state: paused !important; }
