/* Dekoracje sezonu Halloween — paleta „Dynia” (makieta „Halloween theme”).

   Sama paleta (kolory) żyje tam, gdzie każda inna: rampa L0 [data-palette-dark="dynia"]
   w tokens.css. Ten plik to WYŁĄCZNIE warstwa graficzna — ikony, ilustracje, animacje —
   i tylko w miejscach, które nie niosą danych (makieta: „siatka, filtry i formularze zostają
   takie same jak w każdej innej palecie”). Wszystkie teksty interfejsu bez zmian.

   Zakres: każda reguła wisi na :root[data-theme="dark"][data-palette-dark="dynia"], więc
   poza Dynią ten arkusz jest martwy. Poza sezonem atrybutu „dynia” nie da się mieć —
   skrypt w <head> App.razor zdejmuje go przy pierwszym renderze.

   Reduced motion: animacje stają (dynia nie kołysze się, twarz nie migocze), zostaje
   pierścień spinnera — makieta, sekcja „Spinner”. */

/* ─── Przelot nietoperza i konfetti (elementy tworzy js/season.js) ─────────── */
.season-flybat {
  position: fixed;
  left: 0;
  top: 0;
  width: 96px;
  height: 96px;
  color: #000000;
  pointer-events: none;
  z-index: 10000;
  /* Czarna sylwetka na czerni Onyxu jest niewidoczna — kształt rysuje dopiero poświata.
     Dwie warstwy: ostra 1 px daje obrys skrzydeł, miękka 6 px daje „dyniowe” światło. */
  filter: drop-shadow(0 0 1px rgba(242, 140, 40, 0.9)) drop-shadow(0 0 6px rgba(242, 140, 40, 0.5));
}

.season-flybat svg {
  display: block;
  width: 100%;
  height: 100%;
  transform-origin: 50% 55%;
  animation: season-flap 0.22s ease-in-out infinite alternate;
}

.season-flybat svg path {
  fill: currentColor;
  stroke: none;
}

@keyframes season-flap {
  from {
    transform: scaleY(1);
  }

  to {
    transform: scaleY(0.45);
  }
}

.season-candy {
  position: fixed;
  width: 14px;
  height: 14px;
  pointer-events: none;
  z-index: 10000;
}

.season-candy svg {
  display: block;
  width: 100%;
  height: 100%;
}

.season-ghost-anchor {
  position: fixed;
  pointer-events: none;
  visibility: hidden;
}

/* Reduced motion zamiast konfetti: krótki błysk przycisku. */
.season-flash {
  animation: season-flash 0.6s ease-out;
}

@keyframes season-flash {
  0% {
    box-shadow: 0 0 0 0 rgba(242, 140, 40, 0.7);
  }

  100% {
    box-shadow: 0 0 0 10px rgba(242, 140, 40, 0);
  }
}

/* ─── Grafiki sezonu ────────────────────────────────────────────────────────
   Jako data URI, żeby ozdoby dało się podpiąć z CSS (pseudo-elementy, maski) bez
   dokładania znaczników do komponentów, które niosą dane. Jednobarwne (dynia-ikona,
   duch, czaszka) idą przez mask-image + background-color z tokenów, więc
   biorą odcień palety; lampion, kafel nietoperzy i pajęczyny mają kolory Dyni wpisane
   — istnieją tylko w niej, a warstwa tła nie przyjmie maski.
   Namespace --season-* na :root niczego nie zmienia poza tym arkuszem. */
:root {
  --season-jack: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 64 64%22%3E%3Cpath d=%22M32 18c-14 0-23 7.5-23 17.5S18 52 32 52s23-6.5 23-16.5S46 18 32 18z%22 fill=%22%23F28C28%22/%3E%3Cpath d=%22M32 18c-5 5-6.5 11-6.5 17s1.5 12 6.5 17M32 18c5 5 6.5 11 6.5 17s-1.5 12-6.5 17%22 fill=%22none%22 stroke=%22rgba(0,0,0,.18)%22 stroke-width=%222%22/%3E%3Cpath d=%22M32 18v-6c0-2 1.5-3.5 3.5-3.5%22 fill=%22none%22 stroke=%22%238BD15C%22 stroke-width=%223%22 stroke-linecap=%22round%22/%3E%3C/svg%3E");
  --season-face: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 64 64%22%3E%3Cpath d=%22M20 32l5-6 5 6zM34 32l5-6 5 6zM20 39c4 5 20 5 24 0l-3 1-2.5-2-2.5 2.5-4-2.5-4 2.5-2.5-2.5-2.5 2z%22 fill=%22%23E8C547%22/%3E%3C/svg%3E");
  --season-pumpkin: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%221.8%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M12 7.2c-5.2 0-8.5 2.9-8.5 6.6S6.8 20 12 20s8.5-2.5 8.5-6.2S17.2 7.2 12 7.2z%22/%3E%3Cpath d=%22M12 7.2c-2.1 2-2.6 4.4-2.6 6.4s.6 4.4 2.6 6.4%22/%3E%3Cpath d=%22M12 7.2c2.1 2 2.6 4.4 2.6 6.4s-.6 4.4-2.6 6.4%22/%3E%3Cpath d=%22M12 7.2V4.6c0-.9.7-1.6 1.6-1.6%22/%3E%3C/svg%3E");
  --season-ghost: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M9 10h.01%22/%3E%3Cpath d=%22M15 10h.01%22/%3E%3Cpath d=%22M12 2a8 8 0 0 0-8 8v12l3-3 2.5 2.5L12 19l2.5 2.5L17 19l3 3V10a8 8 0 0 0-8-8z%22/%3E%3C/svg%3E");
  --season-skull: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22black%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22m12.5 17-.5-1-.5 1h1z%22/%3E%3Cpath d=%22M15 22a1 1 0 0 0 1-1v-1a2 2 0 0 0 1.56-3.25 8 8 0 1 0-11.12 0A2 2 0 0 0 8 20v1a1 1 0 0 0 1 1z%22/%3E%3Ccircle cx=%2215%22 cy=%2212%22 r=%221%22/%3E%3Ccircle cx=%229%22 cy=%2212%22 r=%221%22/%3E%3C/svg%3E");
  --season-bats-tile: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 150 110%22 fill=%22%23666666%22 fill-opacity=%220.07%22%3E%3Cg transform=%22translate(14 12) rotate(-12) scale(1.1)%22%3E%3Cpath d=%22M12 8.5c-.9 0-1.4.9-1.4.9L9.2 8.2v2.1C7.3 9.3 4.7 8.8 2 9.8c1.6 1 2.1 2.6 2.1 4.2 1-1 2.6-1 3.6 0 .6-1.1 2.1-1.4 3 0 .5.8.9 1.6 1.3 2.6.4-1 .8-1.8 1.3-2.6.9-1.4 2.4-1.1 3 0 1-1 2.6-1 3.6 0 0-1.6.5-3.2 2.1-4.2-2.7-1-5.3-.5-7.2.5V8.2l-1.4 1.2s-.5-.9-1.4-.9z%22/%3E%3C/g%3E%3Cg transform=%22translate(92 48) rotate(10) scale(0.8)%22%3E%3Cpath d=%22M12 8.5c-.9 0-1.4.9-1.4.9L9.2 8.2v2.1C7.3 9.3 4.7 8.8 2 9.8c1.6 1 2.1 2.6 2.1 4.2 1-1 2.6-1 3.6 0 .6-1.1 2.1-1.4 3 0 .5.8.9 1.6 1.3 2.6.4-1 .8-1.8 1.3-2.6.9-1.4 2.4-1.1 3 0 1-1 2.6-1 3.6 0 0-1.6.5-3.2 2.1-4.2-2.7-1-5.3-.5-7.2.5V8.2l-1.4 1.2s-.5-.9-1.4-.9z%22/%3E%3C/g%3E%3Cg transform=%22translate(40 74) rotate(-4) scale(0.65)%22%3E%3Cpath d=%22M12 8.5c-.9 0-1.4.9-1.4.9L9.2 8.2v2.1C7.3 9.3 4.7 8.8 2 9.8c1.6 1 2.1 2.6 2.1 4.2 1-1 2.6-1 3.6 0 .6-1.1 2.1-1.4 3 0 .5.8.9 1.6 1.3 2.6.4-1 .8-1.8 1.3-2.6.9-1.4 2.4-1.1 3 0 1-1 2.6-1 3.6 0 0-1.6.5-3.2 2.1-4.2-2.7-1-5.3-.5-7.2.5V8.2l-1.4 1.2s-.5-.9-1.4-.9z%22/%3E%3C/g%3E%3Cg transform=%22translate(122 6) rotate(18) scale(0.55)%22%3E%3Cpath d=%22M12 8.5c-.9 0-1.4.9-1.4.9L9.2 8.2v2.1C7.3 9.3 4.7 8.8 2 9.8c1.6 1 2.1 2.6 2.1 4.2 1-1 2.6-1 3.6 0 .6-1.1 2.1-1.4 3 0 .5.8.9 1.6 1.3 2.6.4-1 .8-1.8 1.3-2.6.9-1.4 2.4-1.1 3 0 1-1 2.6-1 3.6 0 0-1.6.5-3.2 2.1-4.2-2.7-1-5.3-.5-7.2.5V8.2l-1.4 1.2s-.5-.9-1.4-.9z%22/%3E%3C/g%3E%3C/svg%3E");
  --season-web-ink: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 64 64%22 fill=%22none%22 stroke=%22%238E8E8E%22 stroke-opacity=%220.2%22 stroke-width=%221%22%3E%3Cpath d=%22M64 0L24 40M64 0L40 64M64 0L4 4M64 0L64 50%22/%3E%3Cpath d=%22M50 2c1 6 4 10 12 12M36 3c1 12 8 20 26 26M22 3c2 20 14 34 42 40%22/%3E%3C/svg%3E");
  --season-web-rail: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 64 64%22 fill=%22none%22 stroke=%22%238E8E8E%22 stroke-opacity=%220.22%22 stroke-width=%221%22%3E%3Cpath d=%22M64 0L24 40M64 0L40 64M64 0L4 4M64 0L64 50%22/%3E%3Cpath d=%22M50 2c1 6 4 10 12 12M36 3c1 12 8 20 26 26M22 3c2 20 14 34 42 40%22/%3E%3C/svg%3E");
  --season-web-ink-tl: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 64 64%22 fill=%22none%22 stroke=%22%238E8E8E%22 stroke-opacity=%220.2%22 stroke-width=%221%22%3E%3Cg transform=%22matrix(-1 0 0 1 64 0)%22%3E%3Cpath d=%22M64 0L24 40M64 0L40 64M64 0L4 4M64 0L64 50%22/%3E%3Cpath d=%22M50 2c1 6 4 10 12 12M36 3c1 12 8 20 26 26M22 3c2 20 14 34 42 40%22/%3E%3C/g%3E%3C/svg%3E");
  --season-web-rail-tl: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 64 64%22 fill=%22none%22 stroke=%22%238E8E8E%22 stroke-opacity=%220.22%22 stroke-width=%221%22%3E%3Cg transform=%22matrix(-1 0 0 1 64 0)%22%3E%3Cpath d=%22M64 0L24 40M64 0L40 64M64 0L4 4M64 0L64 50%22/%3E%3Cpath d=%22M50 2c1 6 4 10 12 12M36 3c1 12 8 20 26 26M22 3c2 20 14 34 42 40%22/%3E%3C/g%3E%3C/svg%3E");
  --season-web-ink-bl: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 64 64%22 fill=%22none%22 stroke=%22%238E8E8E%22 stroke-opacity=%220.2%22 stroke-width=%221%22%3E%3Cg transform=%22matrix(-1 0 0 -1 64 64)%22%3E%3Cpath d=%22M64 0L24 40M64 0L40 64M64 0L4 4M64 0L64 50%22/%3E%3Cpath d=%22M50 2c1 6 4 10 12 12M36 3c1 12 8 20 26 26M22 3c2 20 14 34 42 40%22/%3E%3C/g%3E%3C/svg%3E");
  --season-web-rail-bl: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 64 64%22 fill=%22none%22 stroke=%22%238E8E8E%22 stroke-opacity=%220.22%22 stroke-width=%221%22%3E%3Cg transform=%22matrix(-1 0 0 -1 64 64)%22%3E%3Cpath d=%22M64 0L24 40M64 0L40 64M64 0L4 4M64 0L64 50%22/%3E%3Cpath d=%22M50 2c1 6 4 10 12 12M36 3c1 12 8 20 26 26M22 3c2 20 14 34 42 40%22/%3E%3C/g%3E%3C/svg%3E");
  --season-web-ink-br: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 64 64%22 fill=%22none%22 stroke=%22%238E8E8E%22 stroke-opacity=%220.2%22 stroke-width=%221%22%3E%3Cg transform=%22matrix(1 0 0 -1 0 64)%22%3E%3Cpath d=%22M64 0L24 40M64 0L40 64M64 0L4 4M64 0L64 50%22/%3E%3Cpath d=%22M50 2c1 6 4 10 12 12M36 3c1 12 8 20 26 26M22 3c2 20 14 34 42 40%22/%3E%3C/g%3E%3C/svg%3E");
  --season-web-rail-br: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 64 64%22 fill=%22none%22 stroke=%22%238E8E8E%22 stroke-opacity=%220.22%22 stroke-width=%221%22%3E%3Cg transform=%22matrix(1 0 0 -1 0 64)%22%3E%3Cpath d=%22M64 0L24 40M64 0L40 64M64 0L4 4M64 0L64 50%22/%3E%3Cpath d=%22M50 2c1 6 4 10 12 12M36 3c1 12 8 20 26 26M22 3c2 20 14 34 42 40%22/%3E%3C/g%3E%3C/svg%3E");
}

/* ─── Znaczniki renderowane przez cały sezon — domyślnie niewidoczne ─────────
   Serwer nie zna palety przeglądarki, więc postacie awatarów, spinner-dynia i czip
   „do 2.11” są w DOM przez cały sezon; pokazuje je dopiero blok Dyni niżej. */
.season-av,
.season-spin,
.season-chip {
  display: none;
}

/* ─── Nagłówek: dynia przy logo + czip „do 2.11” ─────────────────────────── */
:root[data-theme="dark"][data-palette-dark="dynia"] .mt2__logo {
  position: relative;
}

:root[data-theme="dark"][data-palette-dark="dynia"] .mt2__logo::after {
  content: "";
  position: absolute;
  top: 50%;
  right: -21px;
  width: 15px;
  height: 15px;
  transform: translateY(-50%);
  background: var(--accent);
  -webkit-mask: var(--season-pumpkin) center / contain no-repeat;
  mask: var(--season-pumpkin) center / contain no-repeat;
  pointer-events: none;
}

:root[data-theme="dark"][data-palette-dark="dynia"] .season-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 24px;
  padding: 0 9px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-ink);
  font: 500 10.5px var(--font-mono);
  white-space: nowrap;
}

:root[data-theme="dark"][data-palette-dark="dynia"] .season-chip svg {
  width: 12px;
  height: 12px;
}

/* ─── Pajęczyny ───────────────────────────────────────────────────────────────
   Zawsze w ROGU i POD treścią — jako dodatkowa warstwa background-image hosta, nie
   pseudo-element: tło maluje się pod zawartością z definicji, więc pajęczyna nigdy nie
   zasłoni przycisku ani tekstu, i nie zależy od pozycjonowania hosta (.sidebar nie jest
   pozycjonowany, a position: relative przestawiłoby jego wysuwane menu). Kolor i krycie są
   w kaflu (#8E8E8E przy 20% / szyna 22%); cztery warianty rogu: --season-web-ink[-tl|-bl|-br].

   Gdzie (po przeglądzie: „dodaj w menu na dole i w wielu innych miejscach”): tylko
   powierzchnie-„chrome” bez danych albo rogi, w których kart nie zajmuje treść. Hosty, które
   mają tło ustawione SKRÓTEM z !important (pasek nagłówka w dark, stronicowanie siatki),
   dostają warstwę też z !important — skrót zeruje background-image, a przy dwóch !important
   wygrywa wyższa specyficzność, którą ten selektor ma. ⚠ Górnych rogów kart szczegółów
   zgłoszenia i ustawień NIE używamy: nagłówki kart (__card-head, .st-card__h) są
   nieprzezroczyste i przykryłyby pajęczynę — stąd dolne rogi. */

/* Popovery nagłówka i palet — prawy górny róg, 44 px. */
:root[data-theme="dark"][data-palette-dark="dynia"] :is(.pk-pop, .mt2sla__pop, .mt2work__pop, .mt2__menu) {
  background-image: var(--season-web-ink);
  background-position: top right;
  background-size: 44px 44px;
  background-repeat: no-repeat;
}

/* Dialogi — prawy górny 72 px + lustrzany lewy górny 48 px (makieta, „Pajęczyna”). */
:root[data-theme="dark"][data-palette-dark="dynia"] .esz-popup {
  background-image: var(--season-web-ink), var(--season-web-ink-tl);
  background-position: top right, top left;
  background-size: 72px 72px, 48px 48px;
  background-repeat: no-repeat;
}

/* Dialog iPopup to wyjątek: tokens.css stawia mu `background: var(--paper) !important`,
   więc tu pseudo-elementy: wrapper ma transform (centrowanie), więc jest i blokiem
   zawierającym, i kontekstem stosu — ::before/::after z z-index -1 malują się nad jego tłem,
   a pod treścią. */
:root[data-theme="dark"][data-palette-dark="dynia"] .popup .popup__wrapper {
  isolation: isolate;
}

:root[data-theme="dark"][data-palette-dark="dynia"] .popup .popup__wrapper::before,
:root[data-theme="dark"][data-palette-dark="dynia"] .popup .popup__wrapper::after {
  content: "";
  position: absolute;
  top: 0;
  z-index: -1;
  pointer-events: none;
}

:root[data-theme="dark"][data-palette-dark="dynia"] .popup .popup__wrapper::before {
  right: 0;
  width: 72px;
  height: 72px;
  background: var(--season-web-ink) top right / contain no-repeat;
}

:root[data-theme="dark"][data-palette-dark="dynia"] .popup .popup__wrapper::after {
  left: 0;
  width: 48px;
  height: 48px;
  background: var(--season-web-ink-tl) top left / contain no-repeat;
}

/* Menu po lewej — prawy górny (pierwsza, z makiety) + lewy dolny pod stopką z wersją.
   Sidebar ma height: 100%, więc „bottom” to dół menu także w trybie .expand (display: block). */
:root[data-theme="dark"][data-palette-dark="dynia"] .sidebar {
  background-image: var(--season-web-rail), var(--season-web-rail-bl);
  background-position: top right, bottom left;
  background-size: 44px 44px, 60px 60px;
  background-repeat: no-repeat;
}

/* Szyna modułów (ESZ / IT / OFE) — lewy dolny róg, mniejsza, bo szyna ma ~56 px. */
:root[data-theme="dark"][data-palette-dark="dynia"] .modrail {
  background-image: var(--season-web-rail-bl);
  background-position: bottom left;
  background-size: 40px 40px;
  background-repeat: no-repeat;
}

/* Pasek nagłówka — lewy górny róg, za logo i dynią. W dark tokens.css ustawia mu tło
   skrótem z !important, stąd !important tutaj. */
:root[data-theme="dark"][data-palette-dark="dynia"] .mt2 {
  background-image: var(--season-web-ink-tl) !important;
  background-position: top left !important;
  background-size: 44px 44px !important;
  background-repeat: no-repeat !important;
}

/* Pasek narzędzi siatki — prawy koniec, za ostatnimi przyciskami. */
:root[data-theme="dark"][data-palette-dark="dynia"] .zg-toolbar {
  background-image: var(--season-web-ink);
  background-position: top right;
  background-size: 38px 38px;
  background-repeat: no-repeat;
}

/* Stronicowanie pod siatką — lewy dolny róg. zg-grid.css daje kontenerom pagera
   `background: var(--paper-2) !important` i są ZAGNIEŻDŻONE, przy czym wewnętrzny nie wypełnia
   zewnętrznego — pajęczyna na każdym dawała dwie (zmierzone w harnessie). Wisi więc tylko na
   zewnętrznym .dxbl-grid-bottom-panel, a wewnętrzne kontenery są przezroczyste: mają ten sam
   kolor paper-2 co rodzic, więc wizualnie nic się nie zmienia, a pajęczyna nie jest przykryta. */
:root[data-theme="dark"][data-palette-dark="dynia"] .zg-grid .dxbl-grid-bottom-panel {
  background-image: var(--season-web-ink-bl) !important;
  background-position: bottom left !important;
  background-size: 40px 40px !important;
  background-repeat: no-repeat !important;
}

:root[data-theme="dark"][data-palette-dark="dynia"] .zg-grid .dxbl-grid-bottom-panel :is(.dxbl-grid-pager-container, .dxbl-pager-container) {
  background: transparent !important;
}

/* Karty szczegółów zgłoszenia — prawy dolny róg (górny zasłania nieprzezroczysty nagłówek).
   Bez .tc2__card (Konsultanci): jej ciało też jest nieprzezroczyste i pajęczyny nie byłoby widać. */
:root[data-theme="dark"][data-palette-dark="dynia"] :is(.tv2__card, .te2__card, .tf2__card, .ts2__card, .tm2__card, .tt2__card, .tpr__card) {
  background-image: var(--season-web-ink-br);
  background-position: bottom right;
  background-size: 56px 56px;
  background-repeat: no-repeat;
}

/* Kafle pulpitu — prawy górny róg (kafel nie ma nieprzezroczystego nagłówka). */
:root[data-theme="dark"][data-palette-dark="dynia"] .dashboard__item {
  background-image: var(--season-web-ink);
  background-position: top right;
  background-size: 52px 52px;
  background-repeat: no-repeat;
}

/* Nagłówek stron ustawień — prawy górny róg. */
:root[data-theme="dark"][data-palette-dark="dynia"] .st-hd {
  background-image: var(--season-web-ink);
  background-position: top right;
  background-size: 56px 56px;
  background-repeat: no-repeat;
}

/* ─── Awatary zastępcze — postać zamiast inicjałów (tylko bez zdjęcia) ───────
   Znacznik siedzi w warstwie inicjałów; zdjęcie, jeśli jest, leży nad nim.
   Pozycjonujemy TYLKO .logo (jest statyczne). .zg-avatar już jest relative, a
   .avatar-fallback (UserAvatarComponent) jest ABSOLUTE i wycentrowany pod zdjęciem —
   pierwsza wersja nadpisywała go na relative, warstwa wpadała w przepływ, przesuwała
   zdjęcie i wystawała spod niego pierścieniem (uwaga z przeglądu). */
:root[data-theme="dark"][data-palette-dark="dynia"] .logo:has(> .season-av) {
  position: relative;
}

/* Jest zdjęcie → postaci NIE rysujemy w ogóle (makieta: „prawdziwe zdjęcia zostają bez
   zmian”). Samo przykrycie nie wystarcza: w UserAvatarComponent zdjęcie ma margin-left 6px
   i stoi 3 px obok warstwy pod nim, więc kolorowa postać wystawała sierpem; w części widoków
   zdjęcie jest też mniejsze od warstwy (pierścień). Oba szablony same stawiają inline
   style="display:none" na <img>, któremu nie udało się wczytać — tylko wtedy postać wraca. */
:root[data-theme="dark"][data-palette-dark="dynia"] .halloween:has(> img.classic:not([style*="none"])) .season-av,
:root[data-theme="dark"][data-palette-dark="dynia"] .zg-avatar:has(> img:not([style*="none"])) > .season-av {
  display: none;
}

:root[data-theme="dark"][data-palette-dark="dynia"] .season-av {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.08);
  pointer-events: none;
}

/* .logo w UserAvatarComponent rysuje obrys 2 px — postać ma go przykryć, nie stać w nim. */
:root[data-theme="dark"][data-palette-dark="dynia"] .logo > .season-av {
  inset: -2px;
}

/* 72%, nie 62% z makiety: glify są WYPEŁNIONYMI sylwetkami (SeasonGlyphs) i przy 26 px
   w siatce potrzebują masy, żeby dało się odróżnić nietoperza od pająka. */
:root[data-theme="dark"][data-palette-dark="dynia"] .season-av svg {
  width: 72%;
  height: 72%;
}

/* ─── Spinner: pierścień z akcentem wokół dyni, twarz migocze ─────────────── */
:root[data-theme="dark"][data-palette-dark="dynia"] svg.waiter {
  display: none;
}

:root[data-theme="dark"][data-palette-dark="dynia"] .season-spin {
  display: grid;
  place-items: center;
}

.season-spin__ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 3px solid var(--paper-3);
  border-top-color: var(--accent);
  animation: season-spin 0.9s linear infinite;
}

.season-jack {
  position: relative;
  width: 62%;
  height: 62%;
  background: var(--season-jack) center / contain no-repeat;
}

.season-jack i {
  position: absolute;
  inset: 0;
  background: var(--season-face) center / contain no-repeat;
  animation: season-flick 2.4s infinite;
}

/* Rozmiar kontekstowy (w treści, 25 px): sama dynia kołysze się ±14°, bez pierścienia. */
.season-spin.context .season-spin__ring,
.season-spin.context .season-jack i {
  display: none;
}

.season-spin.context .season-jack {
  width: 100%;
  height: 100%;
  background: var(--accent);
  -webkit-mask: var(--season-pumpkin) center / contain no-repeat;
  mask: var(--season-pumpkin) center / contain no-repeat;
  animation: season-wob 1.1s ease-in-out infinite;
}

/* Spinner w przycisku (IButton): kręcące się kółko → kołysząca się dynia. */
:root[data-theme="dark"][data-palette-dark="dynia"] .button__loader {
  width: 18px;
  height: 18px;
  border: 0;
  border-radius: 0;
  background: currentColor;
  -webkit-mask: var(--season-pumpkin) center / contain no-repeat;
  mask: var(--season-pumpkin) center / contain no-repeat;
  animation: season-wob 1.1s ease-in-out infinite;
}

@keyframes season-spin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes season-wob {
  0%,
  100% {
    transform: rotate(-14deg);
  }

  50% {
    transform: rotate(14deg);
  }
}

@keyframes season-flick {
  0%,
  100% {
    opacity: 1;
  }

  42% {
    opacity: 0.85;
  }

  45% {
    opacity: 0.45;
  }

  48% {
    opacity: 0.95;
  }

  70% {
    opacity: 0.75;
  }
}

/* ─── Widok zgłoszenia: duży lampion w tle prawego dolnego rogu ───────────────
   Po przeglądzie (2026-10-16): „po wejściu w zgłoszenie na dole po prawej jest dużo miejsca —
   wstaw tam w tle dynię z animacji, może być duża”. Ten sam lampion co w spinnerze i pustych
   stanach (dynia + twarz), przypięty do prawego dolnego rogu OKNA (position: fixed), więc
   stoi w pustym miejscu przy każdej długości zgłoszenia i nie jedzie z przewijaniem.

   Kolejność malowania bez nowego kontekstu stosu — celowo: w .ops-content renderuje się
   modal „AI Redaguj” (AiRewritePopup, fixed, z-index 1200); `isolation` na .ops-content
   uwięziłby go pod paskiem nagłówka. Zamiast tego lampion to ::before (PIERWSZY w kolejności,
   pozycjonowany, z-index auto), a .ops-columns dostaje samo position: relative — jako
   pozycjonowany i późniejszy w drzewie maluje się NAD lampionem, czyli karty zawsze go
   przykrywają. .ops-section ma już position: relative, więc uchwyty przeciągania (absolute)
   liczą się od sekcji jak dotąd. Jeden pseudo-element = migocze cały lampion (krycie),
   nie sama twarz — warstwy tła nie dają się animować osobno. */
:root[data-theme="dark"][data-palette-dark="dynia"] .ops-content .ops-columns {
  position: relative;
}

:root[data-theme="dark"][data-palette-dark="dynia"] .ops-content::before {
  content: "";
  position: fixed;
  right: 40px;
  bottom: 32px;
  width: 280px;
  height: 280px;
  /* Ilustracja rastrowa (images/season-jack.png, 560 px = 2× dla HiDPI), nie wektorowy lampion
     z data URI — po przeglądzie (2026-10-16) tło ma pełną, cieniowaną dynię. Wektor zostaje
     w spinnerze i pustych stanach, gdzie jest mały. Plik pobiera się dopiero, gdy ta reguła
     zadziała (Dynia + widok zgłoszenia). */
  background: url("/images/season-jack.png") center / contain no-repeat;
  opacity: 0.3;
  pointer-events: none;
  animation: season-jack-glow 2.4s infinite;
}

@keyframes season-jack-glow {
  0%,
  100% {
    opacity: 0.3;
  }

  42% {
    opacity: 0.26;
  }

  45% {
    opacity: 0.14;
  }

  48% {
    opacity: 0.29;
  }

  70% {
    opacity: 0.23;
  }
}

/* Na telefonie i w wąskim oknie pustego rogu nie ma — lampion siedziałby na treści. */
@media (max-width: 1200px) {
  :root[data-theme="dark"][data-palette-dark="dynia"] .ops-content::before {
    display: none;
  }
}

:root[data-theme="dark"][data-palette-dark="dynia"] .page--phone .ops-content::before {
  display: none;
}

/* ─── Puste stany: lampion zamiast ikony w kółku ───────────────────────────── */
:root[data-theme="dark"][data-palette-dark="dynia"] .st-empty__ic {
  position: relative;
  border-color: transparent;
  background: var(--season-jack) center / contain no-repeat;
}

:root[data-theme="dark"][data-palette-dark="dynia"] .st-empty__ic svg {
  display: none;
}

:root[data-theme="dark"][data-palette-dark="dynia"] .st-empty__ic::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--season-face) center / contain no-repeat;
  animation: season-flick 2.4s infinite;
}

/* ─── Toasty: duch przy informacji, czaszka przy błędzie ─────────────────────
   Teksty bez zmian; podmieniamy tylko glif w kółku tonu (kolor = --tone-ink). */
:root[data-theme="dark"][data-palette-dark="dynia"] :is(.esz-toast--info, .esz-toast--error) .esz-toast__icon svg {
  display: none;
}

:root[data-theme="dark"][data-palette-dark="dynia"] :is(.esz-toast--info, .esz-toast--error) .esz-toast__icon::after {
  content: "";
  width: 16px;
  height: 16px;
  background: currentColor;
  -webkit-mask: var(--season-ghost) center / contain no-repeat;
  mask: var(--season-ghost) center / contain no-repeat;
}

:root[data-theme="dark"][data-palette-dark="dynia"] .esz-toast--error .esz-toast__icon::after {
  -webkit-mask-image: var(--season-skull);
  mask-image: var(--season-skull);
}

/* ─── Tło siatki: nietoperze w pustym miejscu pod ostatnim wierszem ──────────
   Kafel 150 × 110 z czterema nietoperzami, ink-faint przy 7% (wpisane w kafel — istnieje
   tylko w Dyni). Leży na tle przewijanego obszaru siatki, więc wiersze z danymi (z własnym
   tłem) go przykrywają, a widać go tylko w pustym miejscu. */
:root[data-theme="dark"][data-palette-dark="dynia"] .tickets .dxbl-scroll-viewer {
  background-image: var(--season-bats-tile);
  background-size: 150px 110px;
  background-repeat: repeat;
}

/* ─── Reduced motion ──────────────────────────────────────────────────────────
   Pierścień zostaje (to informacja „trwa ładowanie”), dynia i migotanie stoją. */
@media (prefers-reduced-motion: reduce) {
  .season-jack i,
  .season-spin.context .season-jack,
  :root[data-theme="dark"][data-palette-dark="dynia"] .ops-content::before,
  :root[data-theme="dark"][data-palette-dark="dynia"] .button__loader,
  :root[data-theme="dark"][data-palette-dark="dynia"] .st-empty__ic::after {
    animation: none;
  }
}
