/* ═══════════════════════════════════════════════════════════════
   DUSZEK STUDNI — komponent współdzielony (landing + aplikacja)
   Jedno źródło prawdy. Nie edytuj kopii — edytuj ten plik i skopiuj.

   Użycie:
     <span class="dz" data-duszek></span>                  spoczynek
     <span class="dz mysli" data-duszek style="--r:40px"></span>
   Rozmiar: --r (domyślnie 88px). Stan: klasa CSS.

   Samowystarczalny: wszystkie zmienne mają fallback, więc działa
   w dowolnym projekcie bez dopisywania czegokolwiek do jego :root.
   ═══════════════════════════════════════════════════════════════ */

:where(.dz){--r:88px}
.dz{
  --dz-akcent:var(--accent,#B8860B);
  --dz-akcent-2:var(--accent-2,#E0A93C);
  --dz-glab:var(--deep,#0E1620);
  --dz-miekki:var(--e-miekki,cubic-bezier(.37,0,.63,1));
  --dz-zywy:var(--e-zywy,cubic-bezier(.34,1.56,.64,1));
  --dz-wyj:var(--e-wyj,cubic-bezier(.22,.61,.36,1));
  --cykl:4s;
  width:var(--r);height:var(--r);display:inline-block;position:relative;flex:none
}
.dz svg{width:100%;height:100%;overflow:visible;display:block;position:relative;z-index:1}
/* Poświata pod każdym duszkiem — osadza go w tle zamiast zostawiać
   wyciętą naklejkę. Skalowana względem rozmiaru, więc działa i przy 24 px,
   i przy 470 px. Wyłączana klasą .bez-blasku. */
.dz::before{content:"";position:absolute;inset:-16%;border-radius:50%;z-index:0;
  pointer-events:none;
  background:radial-gradient(circle,
    color-mix(in srgb,var(--dz-akcent-2) 26%,transparent) 0%,
    color-mix(in srgb,var(--dz-akcent-2) 8%,transparent) 46%,
    transparent 70%)}
.dz.bez-blasku::before{display:none}
/* w ciemnym motywie poświata musi być mocniejsza, żeby ją było widać */
[data-theme="dark"] .dz::before{
  background:radial-gradient(circle,
    color-mix(in srgb,var(--dz-akcent-2) 34%,transparent) 0%,
    color-mix(in srgb,var(--dz-akcent-2) 11%,transparent) 46%,
    transparent 70%)}
/* w małych glifach (logo, przyciski) poświata tylko rozmywa kształt */
.logo .gl .dz::before,.side-top .gl .dz::before,.gate .gl .dz::before,
.dz-sterowanie::before{display:none}

.dz-cialo{fill:url(#dzGf)}
.dz-oko{fill:var(--dz-glab)}
.dz-blask{fill:var(--dz-akcent-2);opacity:.08}
.dz-usta{stroke:var(--dz-glab);stroke-width:2.5;fill:none;stroke-linecap:round}
.dz-refleks{fill:#fff;opacity:.22}
.dz-cien{fill:var(--dz-glab);opacity:.08}
.dz-policzek{fill:#E8734A;opacity:.2}
.dz-kropla{fill:url(#dzGk)}
.dz-powieka{fill:none;stroke:var(--dz-glab);stroke-width:1.3;stroke-linecap:round;opacity:.32}
.dz-krawedz{fill:none;stroke:var(--dz-akcent);stroke-width:.9;opacity:.35}

/* ── ruch podstawowy ── */
@keyframes dz-unos{0%,100%{transform:translateY(0) rotate(0)}50%{transform:translateY(-3px) rotate(-.8deg)}}
@keyframes dz-oddech{0%,100%{transform:scale(1,1)}50%{transform:scale(1.014,.988)}}
/* Falowanie dołu szło przez animowanie atrybutu `d`, czyli przeglądarka
   liczyła geometrię ścieżki i przemalowywała ją przy każdej klatce, bez
   końca i na każdym duszku w widoku. Profil JavaScriptu tego nie widzi,
   bo dzieje się poza nim — zmierzone: jedyna animacja w aplikacji, która
   nie schodzi na kartę graficzną. Ten sam falujący efekt robimy ruchem,
   który karta graficzna wykonuje sama. */
@keyframes dz-fala{0%,100%{transform:translateY(0) scaleY(1)}
  50%{transform:translateY(.6px) scaleY(1.045)}}
@keyframes dz-mrug{0%,85%,100%{transform:scaleY(1)}87%{transform:scaleY(.07)}89%{transform:scaleY(1)}
  91%{transform:scaleY(.07)}93%{transform:scaleY(1)}}
@keyframes dz-cien{0%,100%{transform:scale(1);opacity:.08}50%{transform:scale(.88);opacity:.055}}
@keyframes dz-kropla{0%,70%,100%{transform:translateY(0) scaleY(1)}
  78%{transform:translateY(.8px) scaleY(1.15)}86%{transform:translateY(0) scaleY(.95)}}

/* ── stany ── */
@keyframes dz-puls{0%,100%{opacity:.07;transform:scale(1)}50%{opacity:.17;transform:scale(1.16)}}
@keyframes dz-mysl{0%{opacity:0;transform:translateY(7px) scale(.5)}
  28%{opacity:1;transform:translateY(0) scale(1)}100%{opacity:0;transform:translateY(-12px) scale(.78)}}
@keyframes dz-czyta{0%,100%{transform:rotate(-7deg)}50%{transform:rotate(7deg)}}
@keyframes dz-skok{0%{transform:translateY(0) scale(1,1)}
  14%{transform:translateY(2px) scale(1.04,.96)}
  34%{transform:translateY(-11px) scale(.97,1.05)}
  56%{transform:translateY(0) scale(1.05,.95)}
  74%{transform:translateY(-2px) scale(.99,1.01)}
  100%{transform:translateY(0) scale(1,1)}}
@keyframes dz-machaj{0%,100%{transform:rotate(0)}25%{transform:rotate(-17deg)}75%{transform:rotate(17deg)}}
@keyframes dz-spi{0%,100%{transform:translateY(0) scale(1,1)}50%{transform:translateY(3px) scale(1.035,.955)}}
@keyframes dz-zzz{0%{opacity:0;transform:translate(0,0) scale(.5)}25%{opacity:.9}
  100%{opacity:0;transform:translate(12px,-17px) scale(1.2)}}
@keyframes dz-wynurz{0%{transform:translateY(28px);opacity:0}40%{opacity:1}
  72%{transform:translateY(-4px)}100%{transform:translateY(0);opacity:1}}
@keyframes dz-skan{0%,100%{transform:translateX(-1.8px)}50%{transform:translateX(1.8px)}}
@keyframes dz-zaskocz{0%{transform:translateY(0) scale(1)}10%{transform:translateY(2px) scale(1.05,.94)}
  25%{transform:translateY(-8px) scale(.95,1.07)}50%{transform:translateY(0) scale(1.03,.97)}
  100%{transform:translateY(0) scale(1)}}
@keyframes dz-oko-duze{0%{transform:scale(1)}22%{transform:scale(1.28)}60%{transform:scale(1.1)}
  100%{transform:scale(1.15)}}
@keyframes dz-smutek{0%,100%{transform:translateY(0) rotate(0)}50%{transform:translateY(4px) rotate(1.5deg)}}
@keyframes dz-pisze{0%,100%{transform:rotate(-9deg) translateY(0)}50%{transform:rotate(5deg) translateY(-2px)}}
@keyframes dz-konfetti{0%{opacity:0;transform:translateY(-6px) rotate(0)}15%{opacity:1}
  100%{opacity:0;transform:translateY(34px) rotate(240deg)}}
@keyframes dz-blad{0%,100%{transform:translateX(0)}20%{transform:translateX(-2.5px) rotate(-1.2deg)}
  40%{transform:translateX(2.5px) rotate(1.2deg)}60%{transform:translateX(-1.8px) rotate(-.8deg)}
  80%{transform:translateX(1.8px) rotate(.8deg)}}
@keyframes dz-zdziw{0%,100%{transform:rotate(-9deg)}50%{transform:rotate(-4deg)}}
@keyframes dz-pytajnik{0%,100%{opacity:.9;transform:translateY(0) rotate(-6deg)}
  50%{opacity:1;transform:translateY(-3px) rotate(6deg)}}

/* Wspólny cykl: wszystko na --cykl albo jego wielokrotności — bez rozjazdu faz.
   Mruganie i kropla celowo dłuższe (nieregularność wygląda naturalnie). */
.dz .g{animation:dz-unos var(--cykl) var(--dz-miekki) infinite}
.dz .glowa{animation:dz-oddech var(--cykl) var(--dz-miekki) infinite}
.dz .dol{animation:dz-fala var(--cykl) var(--dz-miekki) infinite;
  transform-box:fill-box;transform-origin:50% 0}
.dz .dz-cien{animation:dz-cien var(--cykl) var(--dz-miekki) infinite;transform-box:fill-box;transform-origin:center}
.dz .oko{animation:dz-mrug calc(var(--cykl) * 1.75) infinite;
  transform-box:fill-box;transform-origin:center}
.dz .dz-kropla{animation:dz-kropla calc(var(--cykl) * 2) var(--dz-miekki) infinite;
  transform-box:fill-box;transform-origin:50% 0}
.dz .reka{transform-box:fill-box;transform-origin:50% 16%}
.dz .oczy{transition:transform .28s var(--dz-wyj)}

.dz.mysli{--cykl:2s}
.dz.mysli .dz-blask{animation:dz-puls 2s var(--dz-miekki) infinite}
.dz.mysli .k1{animation:dz-mysl 1.7s infinite}
.dz.mysli .k2{animation:dz-mysl 1.7s .28s infinite}
.dz.mysli .k3{animation:dz-mysl 1.7s .56s infinite}
.dz.uczy .glowa{animation:dz-czyta calc(var(--cykl) * .75) var(--dz-miekki) infinite;transform-origin:50% 70%}
.dz.skanuje .oczy{animation:dz-skan calc(var(--cykl) * .45) var(--dz-miekki) infinite}
.dz.cieszy,.dz.swietuje{--skok:.95s}
.dz.cieszy .g,.dz.swietuje .g{animation:dz-skok var(--skok) var(--dz-zywy) infinite}
.dz.cieszy .reka,.dz.swietuje .reka{
  animation:dz-machaj calc(var(--skok) / 2) var(--dz-miekki) calc(var(--skok) / 14) infinite}
.dz.swietuje .kon1{animation:dz-konfetti calc(var(--skok) * 2) infinite}
.dz.swietuje .kon2{animation:dz-konfetti calc(var(--skok) * 2) calc(var(--skok) * .35) infinite}
.dz.swietuje .kon3{animation:dz-konfetti calc(var(--skok) * 2) calc(var(--skok) * .7) infinite}
.dz.swietuje .kon4{animation:dz-konfetti calc(var(--skok) * 2) calc(var(--skok) * 1.05) infinite}
.dz.macha .reka:last-of-type{animation:dz-machaj .62s var(--dz-miekki) infinite}
.dz.pisze .reka:last-of-type{animation:dz-pisze .44s var(--dz-miekki) infinite}
.dz.zaskoczony .g{animation:dz-zaskocz 1.7s var(--dz-zywy) infinite}
.dz.zaskoczony .oko{animation:dz-oko-duze 1.7s infinite;transform-box:fill-box;transform-origin:center}
.dz.zaskoczony .wykrz{opacity:1}
.dz.zmartwiony .g{animation:dz-smutek 2.7s var(--dz-miekki) infinite}
.dz.zmartwiony .dz-usta{d:path("M45 55 Q50 50.5 55 55")}
.dz.spi{--cykl:6s}
.dz.spi .g{animation:dz-spi 6s var(--dz-miekki) infinite}
.dz.spi .oko{animation:none;transform:scaleY(.1);transform-box:fill-box;transform-origin:center}
.dz.spi .z1{animation:dz-zzz 2.6s infinite}
.dz.spi .z2{animation:dz-zzz 2.6s .9s infinite}
.dz.wynurza .g{animation:dz-wynurz 2.8s var(--dz-wyj) infinite}
.dz.blad .g{animation:dz-blad .55s var(--dz-miekki) infinite}
.dz.blad .dz-usta{d:path("M45 55.5 Q50 51.5 55 55.5")}
.dz.zdziwiony .glowa{animation:dz-zdziw 2.2s var(--dz-miekki) infinite;transform-origin:50% 72%}
.dz.zdziwiony .pytajnik{opacity:1;animation:dz-pytajnik 2.2s var(--dz-miekki) infinite;
  transform-box:fill-box;transform-origin:center}

/* Jednorazowe wejście — dla momentów, w których duszek się pojawia */
@keyframes dz-wejscie{0%{opacity:0;transform:translateY(14px) scale(.86)}
  60%{opacity:1;transform:translateY(-3px) scale(1.03)}100%{opacity:1;transform:translateY(0) scale(1)}}
.dz.wchodzi{animation:dz-wejscie .62s var(--dz-zywy) both}

/* ── preferencja użytkownika (ustawiana na <html data-maskotka="...">) ── */
[data-maskotka="spokojny"] .dz *{animation:none!important}
[data-maskotka="spokojny"] .dz .oko{animation:dz-mrug 8s infinite!important}
[data-maskotka="spokojny"] .dz .dz-blask,
[data-maskotka="spokojny"] .dz .dz-policzek{opacity:.06}
/* Duszek w przycisku sterującym NIE znika — inaczej przycisk robi się pusty
   i nie ma jak włączyć maskotki z powrotem. Zamiast tego gaśnie i dostaje ukośnik. */
[data-maskotka="brak"] .dz:not(.dz-sterowanie){display:none}
[data-maskotka="brak"] .dz.dz-sterowanie{opacity:.4;filter:grayscale(1)}
.dz-sterowanie{position:relative}
[data-maskotka="brak"] .dz-sterowanie::after{content:"";position:absolute;inset:0;
  background:linear-gradient(to bottom right,transparent 44%,currentColor 44%,
    currentColor 56%,transparent 56%);opacity:.8}
[data-maskotka="brak"] .dz-zamiennik{display:inline-flex!important}

/* neutralny wskaźnik dla wyłączonej maskotki */
.dz-zamiennik{display:none;align-items:center;gap:.5rem;
  font-family:var(--f-mono,monospace);font-size:11px;color:var(--ink-3,#949BA4);letter-spacing:.06em}
.dz-zamiennik .kropki{display:inline-flex;gap:3px}
.dz-zamiennik .kropki i{width:5px;height:5px;border-radius:50%;background:var(--accent,#B8860B);
  animation:dz-kropki 1.2s var(--dz-miekki,cubic-bezier(.37,0,.63,1)) infinite}
.dz-zamiennik .kropki i:nth-child(2){animation-delay:.2s}
.dz-zamiennik .kropki i:nth-child(3){animation-delay:.4s}
@keyframes dz-kropki{0%,100%{opacity:.25;transform:translateY(0)}50%{opacity:1;transform:translateY(-3px)}}

@media(prefers-reduced-motion:reduce){.dz *{animation:none!important;transition:none!important}}

/* ═══ STUDNIA Z DUSZKIEM ═══
   Trzy warstwy w jednym stosie: tył (otwór) → duszek → przód (cembrowina).
   Duszek siedzi między nimi, więc wynurza się Z otworu, a nie przed nim.
   Rozmiar skalujesz przez --sz na .dz-studnia. */
.dz-studnia{--sz:264px;position:relative;width:var(--sz);height:calc(var(--sz) * .644);}
.dz-studnia > *{position:absolute;left:0;bottom:0;width:100%;}
.dz-studnia .st-tyl,.dz-studnia .st-przod{height:auto;display:block;}
/* .dz-studnia przed selektorem, bo .dz ustawia position:relative
   przy tej samej specyficzności i wygrałoby kolejnością plików */
.dz-studnia .st-duszek{position:absolute;left:50%;transform:translateX(-50%);
  bottom:calc(var(--sz) * .258);width:auto;z-index:2;}
.dz-studnia .st-przod{z-index:3;}
.dz-studnia .st-mur{fill:var(--bg-2,#F3F2ED);stroke:var(--line,#E7E5DF);stroke-width:1.5;}
.dz-studnia .st-fuga{stroke:var(--line,#E7E5DF);stroke-width:1.2;fill:none;opacity:.75;}
.dz-studnia .st-krawedz{fill:none;stroke:var(--accent,#B8860B);stroke-width:2.5;opacity:.5;}
[data-theme="dark"] .dz-studnia .st-mur{fill:var(--surface);}
/* w ciemnym motywie otwór na przezroczystości zlewał się z tłem */
[data-theme="dark"] .dz-studnia .st-wnetrze{fill:#04080D;opacity:1;}

/* Wariant statyczny: bez ruchu poza rzadkim mrugnięciem.
   Na stronie sprzedażowej maskotka ma być obecna, nie rozpraszać. */
.dz.statyczny *{animation:none!important}
.dz.statyczny .oko{animation:dz-mrug 7s infinite!important;
  transform-box:fill-box;transform-origin:center}

/* ═══════════════ MIMIKA (statyczna) ═══════════════
   Stany wyżej są ruchem. Gdy duszek stoi (na stronie sprzedażowej),
   wszystkie wyglądałyby identycznie — dlatego mina to osobna warstwa
   zbudowana z geometrii, nie z animacji. Klasy .mina-* są niezależne
   od stanów, więc da się je łączyć. */
.dz-oko-luk{fill:none;stroke:var(--dz-glab);stroke-width:3.4;stroke-linecap:round;display:none}
.dz-brew{fill:none;stroke:var(--dz-glab);stroke-width:2.2;stroke-linecap:round;opacity:0}

/* radość: oczy w podkówkę, szeroki uśmiech, mocniejsze rumieńce */
.dz.mina-radosc .oko,.dz.mina-radosc .dz-powieka{display:none}
.dz.mina-radosc .dz-oko-luk.gora{display:block}
.dz.mina-radosc .dz-usta{d:path("M43 50.5 Q50 58.5 57 50.5");stroke-width:2.8}
.dz.mina-radosc .dz-policzek{opacity:.32}

/* gdy brew jest widoczna, powieka znika — dwie kreski nad okiem to za dużo */
.dz.mina-skupienie .dz-powieka,.dz.mina-zdziwienie .dz-powieka,
.dz.mina-ciekawosc .dz-powieka{display:none}
/* skupienie: brwi w dół do środka, usta w prostą kreskę */
.dz.mina-skupienie .dz-brew{opacity:.55}
.dz.mina-skupienie .dz-brew.l{d:path("M29 26.5 Q36 25.5 43 29")}
.dz.mina-skupienie .dz-brew.p{d:path("M57 29 Q64 25.5 71 26.5")}
.dz.mina-skupienie .dz-usta{d:path("M45.5 53.5 L54.5 53.5")}

/* zdziwienie: brwi wysoko, usta w kółko, oczy szerzej otwarte */
.dz.mina-zdziwienie .dz-brew{opacity:.5;transform:translateY(-2.5px)}
.dz.mina-zdziwienie .dz-oko{ry:10.4}
.dz.mina-zdziwienie .dz-usta{d:path("M47.4 52.6 A 2.6 3 0 1 0 52.6 52.6 A 2.6 3 0 1 0 47.4 52.6");
  fill:var(--dz-glab);stroke-width:0}

/* spokój: bez uśmiechu, łagodna linia — do miejsc rzeczowych */
.dz.mina-spokoj .dz-usta{d:path("M45.8 52.6 Q50 54.4 54.2 52.6")}
.dz.mina-spokoj .dz-policzek{opacity:.12}

/* sen: oczy w podkówkę odwróconą */
.dz.mina-sen .oko,.dz.mina-sen .dz-powieka{display:none}
.dz.mina-sen .dz-oko-luk.dol{display:block}
.dz.mina-sen .dz-usta{d:path("M46.5 52.5 Q50 55 53.5 52.5")}

/* ciekawość: jedna brew wyżej, uśmiech przekrzywiony */
.dz.mina-ciekawosc .dz-brew{opacity:.5}
.dz.mina-ciekawosc .dz-brew.l{transform:translateY(-3px)}
.dz.mina-ciekawosc .dz-usta{d:path("M45.5 52.8 Q50 56.4 54.5 51.4")}

/* Ozdobniki stanów (myśli, zzz, !, ?, konfetti) miały opacity:0, ale nadal
   zajmowały miejsce w układzie i rozpychały stronę w poziomie na wąskich
   ekranach. display:none usuwa je z layoutu; stany włączają je z powrotem. */
.dz .k1,.dz .k2,.dz .k3,.dz .z1,.dz .z2,.dz .wykrz,.dz .pytajnik,
.dz .kon1,.dz .kon2,.dz .kon3,.dz .kon4{display:none}
.dz.mysli .k1,.dz.mysli .k2,.dz.mysli .k3,
.dz.spi .z1,.dz.spi .z2,
.dz.zaskoczony .wykrz,
.dz.zdziwiony .pytajnik,
.dz.swietuje .kon1,.dz.swietuje .kon2,.dz.swietuje .kon3,.dz.swietuje .kon4{display:block}

/* ═══════════════ REKWIZYTY ═══════════════ */
.rek{display:none}
.dz.rek-ksiazka .rek-ksiazka,.dz.rek-olowek .rek-olowek,.dz.rek-kubek .rek-kubek,
.dz.rek-czapka .rek-czapka,.dz.rek-kartka .rek-kartka,
.dz.rek-lupa .rek-lupa,.dz.rek-dyplom .rek-dyplom{display:block}
/* z książką i kartką rączki chowamy — inaczej sterczą zza rekwizytu */
.dz.rek-ksiazka .reka,.dz.rek-kartka .reka,.dz.rek-dyplom .reka{display:none}
/* kropla przebijała przez czapkę */
.dz.rek-czapka .dz-kropla{display:none}

/* ═══════════════ USTAWIENIE ═══════════════
   Duszki nie mają stać w równym rzędzie na baczność. */
.dz.krzywo-l{transform:rotate(-9deg)}
.dz.krzywo-p{transform:rotate(8deg)}
.dz.krzywo-mocno{transform:rotate(-16deg)}

/* Wygląda zza krawędzi: kontener przycina, duszek wystaje tylko częścią.
   --wystaje mówi, jaka część zostaje widoczna. */
.dz-zza{position:absolute;overflow:hidden;pointer-events:none;z-index:0}
.dz-zza.z-lewej{left:0;--wystaje:62%}
.dz-zza.z-prawej{right:0;--wystaje:62%}
.dz-zza.z-lewej .dz{transform:translateX(calc(-100% + var(--wystaje))) rotate(-14deg)}
.dz-zza.z-prawej .dz{transform:translateX(calc(100% - var(--wystaje))) rotate(14deg)}
@media(max-width:900px){.dz-zza{display:none}}

/* Pauza poza ekranem (nadaje ją strona przez IntersectionObserver).
   Zatrzymuje wszystkie animacje duszka w bieżącej klatce. */
.dz.pauza,.dz.pauza *{animation-play-state:paused!important}
