/* Redesign GamesBoard 2026 - makiety 1a-1g. Paleta, układy i krój z makiety. */

/* Kroj serwisu (Titillium Web) deklarowany jest
   wylacznie w assets/css/fonts.css. Tu uzywamy go przez var(--gb-font),
   monospace przez var(--gb-mono). Kanon wag: 400 tekst, 600 wyroznienie,
   700 naglowki i przyciski. */
:root {
  /* ================= WYSOKOSC PASKA NAWIGACJI (GB-114) =================
     Pasek jest PRZYKLEJONY, wiec każde miejsce, które zakłada, że coś stoi
     u góry ekranu, musi znać jego wysokość. Wcześniej znało ją na cztery
     różne sposoby: 76, 96, 84 i 90 px, i żaden nie odpowiadał prawdzie
     (60 px treści + 1 px kreski). Skutkiem były kotwice chowające nagłówek
     pod paskiem i przyklejone panele nachodzące na siebie.

     JEDNO ŹRÓDŁO PRAWDY. Zmiana wysokości paska to zmiana jednej liczby tutaj.
       --gb-nav-h  realna wysokość paska
       --gb-stick  gdzie zaczyna się przyklejona zawartość (pasek + oddech)
     Kotwice załatwia `scroll-padding-top` na <html>, więc nie trzeba dopisywać
     `scroll-margin-top` do każdego nagłówka z osobna. */
  --gb-nav-h: 61px;
  --gb-stick: calc(var(--gb-nav-h) + 16px);

  --gb-bg: #0e1015;
  --gb-panel: #14161c;
  --gb-card: #1d2029;
  --gb-card2: #191c23;
  --gb-line: rgba(255, 255, 255, .07);
  --gb-line2: rgba(255, 255, 255, .14);
  --gb-accent: #ffc233;
  /* Jasniejszy stopien akcentu, wylacznie na hover akcentu (przycisk glowny,
     link w tresci, plakietka filtra, pastylka platformy). To NIE jest druga
     barwa znaczaca w rozumieniu kanonu, tylko podswietlenie tej samej - stad
     jeden token zamiast #ffd76a wpisanego w pieciu arkuszach. */
  --gb-accent-hi: #ffd76a;
  --gb-green: #3ddc84;
  --gb-red: #ff4d5a;
  --gb-blue: #4da3ff;
  --gb-violet: #a78bfa;

  /* ================= KANON BARW (GB-59, 2026-08-07) =================
     Powod: na jednym ekranie potrafilo siedziec szesc rodzin barw naraz
     (czerwony, zielony, niebieski, zolty, fiolet, cyjan). Kazda z osobna
     miala uzasadnienie, razem robily szum. Zasada trzech poziomow:

     1. AKCENT MARKI - var(--gb-accent). JEDEN kolor akcentu na widok.
        Interakcja i nawigacja: przyciski glowne, hover tytulu, kropka
        naglowka sekcji, aktywny filtr, wyrozniony napis w feedzie.

     2. BARWY ZNACZACE - tylko stan, ktorego nie da sie odczytac z tekstu
        w pol sekundy. Sa DWIE plus skala ocen:
          --gb-red   TRWA TERAZ / na zywo. Jedyny stan rysowany plakietka
                     WYPELNIONA - dzieki temu na liscie turniejow jest
                     dokladnie jeden glosny element i widac go od razu.
          --gb-green otwarte / dostepne / zaleta (zapisy otwarte, wolny stol,
                     plus w recenzji). Plakietka OBRYSOWANA, nie wypelniona.
          kolka ocen zostaja na wlasnej skali (zielony/zolty/pomaranczowy/
          czerwony wg wartosci) - to liczba, nie stan interfejsu.
        Stany, ktore nie wymagaja reakcji ("nadchodzi", "wkrotce", "bye",
        "pending"), ida w neutral - brak akcji to brak koloru.

     3. NEUTRALNE - cala reszta: --gb-dec, --gb-dec-soft, --gb-line,
        --gb-line2, --gb-muted, --gb-text2. Tu ida wszystkie dekoracje:
        paski zapelnienia, kreski pod okladka, obwodki kafli, ikony kafli
        gier, awatary, plakietki kategorii, znaczniki serwerow.

     WYCOFANE z roli dekoracyjnej: --gb-blue i --gb-violet (zostaja w
     palecie dla ewentualnych wykresow, ale NIE wracaja na plakietki,
     kropki sekcji ani obwodki), cyjan #22d3ee, drugi czerwony #ff7a84,
     pomaranczowy #ff8a3d.

     Zanim dolozysz kolor: jesli ta sama informacja jest juz w tekscie
     obok, kolor jest dekoracja i ma isc w --gb-dec. */
  /* .34 nie jest wartoscia z sufitu: pasek zapelnienia rysowany tym kolorem
     na torze var(--gb-panel) daje 3,11:1, czyli lapie prog 3:1 dla grafiki
     niosacej informacje. Przy .26 bylo 2,35:1 i pasek gubil sie w torze. */
  --gb-dec: rgba(255, 255, 255, .34);
  --gb-dec-soft: rgba(255, 255, 255, .07);

  /* ============ ZASADA OBRAMOWAN KONTENEROW (GB-60, 2026-08-07) ============
     ROZSTRZYGNIETO: ramka zostaje, i to na KAZDYM kontenerze z plaskim tlem.

     Sprawdzany byl wariant przeciwny (zero ramek, karty odcinane samym
     kontrastem tla). Pomiar go przekreslil:
       karta #1d2029 na tle strony #0e1015 ....... 1,17:1
       karta #1d2029 na panelu #14161c ........... 1,11:1
       karta ciemniejsza #191c23 na tle strony ... 1,12:1
     Prog dla granic elementow interfejsu to 3:1, wiec sam kontrast tla jest
     ponad dwa razy za slaby - na taniej matrycy TN albo przy podniesionej
     jasnosci karty po prostu znikaja. Dla porownania ramka .07 zlozona na
     karcie to rgb(45,48,56): 1,44:1 wzgledem tla strony i 1,23:1 wzgledem
     samej karty, czyli krawedz powstaje z DWOCH skokow jasnosci zamiast
     jednego i dlatego jest widoczna.

     Za ramka stoi tez zrodlo: makieta z Claude Design uzywa
     'border:1px solid rgba(255,255,255,.07)' 72 razy - to najczestsza
     deklaracja w calym pliku makiety.

     KANON:
     a) Kazdy kontener z plaskim tlem (--gb-card, --gb-card2, --gb-panel) ma
        'border: 1px solid var(--gb-line)'. Dotyczy kart, kafli, paneli
        bocznych, kafli serwerow, kart turniejow, paneli mega-menu, boksow
        reklamowych, stopki ORAZ hero - hero bylo jedyna sekcja bez ramki i
        wlasnie to robilo dwa jezyki wizualne na stronie glownej.
     b) Wyjatek dotyczy WYLACZNIE gniazda na obraz WEWNATRZ kontenera
        (.gb-card-media, .ggl-game-card-cover, .gb-mfeat-media, miniatura).
        Tam kadr wypelnia cala powierzchnie, krawedz daje samo zdjecie, a
        kreska 1 px czytalaby sie jak przeswit. Gniazdo siedzi w pudelku,
        ktore ramke ma - wiec kontener i tak jest obrysowany.
     c) Wiersze list wewnatrz kontenera (news, gry, ranking, feed) NIE
        dostaja wlasnej ramki - rozdziela je 'border-bottom: 1px solid
        var(--gb-line)'. Ramka nalezy do pudelka, nie do jego wierszy.
     d) Jedna wartosc dla wszystkich: var(--gb-line). var(--gb-line2) jest
        zarezerwowana dla hoveru i dla kontrolek (przycisk ghost, input,
        select, plakietka filtra). Zadnych wlasnych rgba .05/.08/.09/.12 ani
        nieprzezroczystych #2a2b31 - taka ramka nie skaluje sie z tlem pod
        spodem i rozjezdza sie przy kazdej zmianie palety.
     e) Wyroznienie kontenera robi TLO, nie grubsza kreska. Panel wazniejszy
        od sasiada dostaje jasniejsze tlo, nie var(--gb-line2).
     Zlamanie tej zasady widac natychmiast: dwa jezyki wizualne na jednym
     ekranie, dokladnie to zglaszal uzytkownik. */
  /* Cztery poziomy tekstu, każdy zmierzony na najjaśniejszym tle karty (#1d2029):
     text 15.8:1, text2 10.9:1, muted 6.0:1 - wszystkie ponad próg AA 4.5:1.
     dim 3.6:1 jest WYŁĄCZNIE dla elementów dekoracyjnych (separatory, ramki),
     nigdy dla treści - wcześniej #555c6e i #3f4552 l�
dowały w napisach
     i schodziły do 1,8-2,5:1, czyli poniżej jakiegokolwiek progu. */
  --gb-text: #ffffff;
  --gb-text2: #c6cbd6;
  --gb-muted: #97a0b2;
  --gb-dim: #6b7386;
  /* Makieta rysowana była na karcie 1320 px; na realnych ekranach zostaje sporo
     zapasu po bokach, więc kontener idzie na 1420 px (decyzja Mattiego 2026-08-06). */
  --gb-max: 1420px;

  /* ================= JEDEN SYSTEM HOVEROW (kanon 2026-08-06) =================
     Zasada: hover PODSWIETLA element, nie rusza go z miejsca.

     1. Tlo: powierzchnia idzie o jeden ton w gore.
        - tlo przezroczyste            -> background: var(--gb-hover)
        - tlo var(--gb-panel)          -> background: var(--gb-card)
        - tlo var(--gb-card)           -> background: var(--gb-hover-card)
        Kazdy z tych krokow to dokladnie ~4% bieli nalozone na tlo bazowe.
     2. Ramka: border-color -> var(--gb-line2) (w sekcjach kolorowych var(--gb-sec)).
     3. Tytul: color -> var(--gb-accent) albo var(--gb-sec, var(--gb-accent)).
     4. Czasy: .18s dla koloru/tla/ramki, .5s cubic-bezier(.22,.61,.36,1) dla zdjecia.

     ZAKAZANE na hoverze: transform: translateY/translateX (podnoszenie i przesuwanie
     kafli), box-shadow z poswiata, filter: drop-shadow, skalowanie calego kafla.

     DOZWOLONE wyjatki (prosba uzytkownika):
     - powiekszenie SAMEGO zdjecia wewnatrz kafla: transform: scale(1.06),
       transition .5s cubic-bezier(.22,.61,.36,1);
     - wysuwana strzalka w .gb-btn-arrow / .gb-link-arrow (::after, translateX).

     Wszystko, co tu dodane, musi byc zerowane w @media (prefers-reduced-motion: reduce). */
  --gb-hover: rgba(255, 255, 255, .04);
  --gb-hover-card: #22252f;
}

/* Cały serwis na kroju z makiety. Podnosimy specyficzności�
 nad stare reguły,
   które wpisywały 'gigabold' (Saira) i 'main' (Lexend) w nagłówki i treść. */
body.gb-redesign,
body.gb-redesign h1, body.gb-redesign h2, body.gb-redesign h3,
body.gb-redesign h4, body.gb-redesign h5, body.gb-redesign h6,
body.gb-redesign p, body.gb-redesign li, body.gb-redesign a,
body.gb-redesign span, body.gb-redesign button, body.gb-redesign input,
body.gb-redesign select, body.gb-redesign textarea,
body.gb-redesign .gb-sec-title, body.gb-redesign .gb-page-title,
body.gb-redesign .gb-hero-title, body.gb-redesign .gb-side-title,
body.gb-redesign .gb-rank-title, body.gb-redesign .gb-quick-title,
body.gb-redesign .gb-verdict-title, body.gb-redesign .gb-menu-item > a {
  font-family: var(--gb-font);
}

/* Wyj�
tek: liczniki, zegary i notacja zostaj�
 monospace. */
body.gb-redesign .wb-clock-time,
body.gb-redesign code, body.gb-redesign pre, body.gb-redesign kbd {
  font-family: var(--gb-mono);
}

body.gb-redesign {
  background: var(--gb-bg);
  color: var(--gb-text);
}

/* Stary nagłówek dokładał własn�
 kreskę pod <header>; nowy pasek ma swoj�
. */
body.gb-redesign .gb-header { border-bottom: none; }

/* Tło <html> zostawało w starej palecie (#1e222b) i prześwitywało na krawędziach
   oraz przy przewijaniu poza treść. Redesign jest globalny, więc i to jest globalne. */
html {
  background: var(--gb-bg);

  /* Kotwice zatrzymują się PONIŻEJ przyklejonego paska (GB-114). Bez tego
     kliknięcie w spis treści przewijało nagłówek dokładnie pod pasek i tekst
     zaczynał się od drugiego akapitu. Jedna reguła na dokument załatwia
     wszystkie kotwice naraz - `scroll-margin-top` przy każdym nagłówku
     z osobna rozjeżdżał się przy pierwszej zmianie wysokości paska. */
  scroll-padding-top: var(--gb-stick);
}

/* ================= SPROWADZENIE BARW WSTRZYKIWANYCH Z SZABLONOW (GB-59)
   Szablony PHP wpisuja kolory prosto w atrybut style: siatki sekcji podaja
   --gb-sec (#ff4d5a, #3ddc84, #a78bfa, #22d3ee, #ffc233), kafle gier koloruja
   ikone, awatary graczy maja wlasny kolor, kafle serwerow podaja --srv.
   Z tego robilo sie szesc rodzin barw na jednym ekranie.

   Deklaracja inline przegrywa tylko z !important, wiec tu jest on konieczny -
   to nie jest lenistwo, tylko jedyny sposob, zeby zrobic to z poziomu CSS bez
   ruszania szablonow (nad ktorymi rownolegle pracuje kto inny). Selektor
   [style*="..."] lapie kazdy punkt wstrzykniecia niezaleznie od pliku.
   Gdy kiedys szablony przestana podawac kolory, ten blok mozna skasowac. */

/* Sekcje: jeden kolor akcentu zamiast szesciu. */
body.gb-redesign [style*="--gb-sec"] { --gb-sec: var(--gb-accent) !important; }
/* Kropka przy naglowku sekcji to czysta dekoracja - nazwa sekcji stoi obok. */
body.gb-redesign .gb-sec-dot { background: var(--gb-accent) !important; }
/* Ikona kafla gry i awatar gracza: kolor nie kodowal niczego, czego nie ma w
   podpisie obok, wiec ida na neutralna powierzchnie. */
body.gb-redesign .gb-ptile-ic { background: var(--gb-dec-soft) !important; color: var(--gb-text2); }
body.gb-redesign .gb-top-av { background: var(--gb-dec) !important; }
/* Zastepnik okladki gry: inicjal w szarosci zamiast losowego koloru z palety. */
body.gb-redesign .gb-sg-letter { --sg: var(--gb-muted) !important; }
/* Znacznik gry na kaflu serwera (pasek po lewej i poswiata w rogu). */
body.gb-redesign .gb-scard, body.gb-redesign .gb-mserv { --srv: var(--gb-line2) !important; }
/* Ikona gry na liscie "Zaloz stol" (/graj/) - to samo co .gb-ptile-ic, tylko
   szablon nadaje jej goly class="ic" i wlasny kolor tla. */
body.gb-redesign .gb-lobby-new-btn .ic { background: var(--gb-dec-soft) !important; color: var(--gb-text2); }

/* ------------------------------------------------------- artykuł i sidebar
   Layoutu artykułu nie ruszamy, wyrównujemy wył�
cznie paletę: articles.css
   został na starych kolorach (#e2e2e8, #FFCC32, #181b22), przez co treść wpisu
   odstawała tonem od reszty redesignu. Mapowanie stary -> makietowy. */
/* Stare main miało 1200 px, więc artykuły byłyby węższe niż nagłówek i stopka. */
body.gb-redesign .gb-main { background: transparent; max-width: var(--gb-max); }
body.gb-redesign .article-container { background: var(--gb-panel); }
body.gb-redesign .article-thumb { background: var(--gb-panel); }

body.gb-redesign .article-content,
body.gb-redesign .article-content p,
body.gb-redesign .article-content li,
body.gb-redesign .article-content strong,
body.gb-redesign .article-related-box { color: var(--gb-text2); }

body.gb-redesign .article-meta,
body.gb-redesign .article-author,
body.gb-redesign .article-categories,
body.gb-redesign .article-date { color: var(--gb-muted); }

body.gb-redesign .article-sidebar,
body.gb-redesign .sidebar-section,
body.gb-redesign .sidebar-partner { color: var(--gb-text2); }
/* Data wpisu siedziala na wlasnym #9aa3b5, czyli o wlos od --gb-muted obok.
   Po zejsciu na zmienna obie linie sa tym samym stopniem skali, wiec ida razem. */
body.gb-redesign .sidebar-latest-meta,
body.gb-redesign .sidebar-latest-date { color: var(--gb-muted); }
body.gb-redesign .sidebar-latest-thumb { background: var(--gb-card); }
body.gb-redesign .sidebar-latest-cat { background: var(--gb-accent); color: var(--gb-panel); }

body.gb-redesign .related-article { background: var(--gb-card); }
body.gb-redesign .related-article-date { color: var(--gb-muted); }
body.gb-redesign a.article-category { background: var(--gb-card); color: var(--gb-text2); }
body.gb-redesign a.article-category:hover { background: var(--gb-card2); color: var(--gb-accent); }

/* Stary żółty (#FFCC32) i jego hover (#ffe47a / #ffd857) w treści i sidebarze. */
body.gb-redesign .article-content a,
body.gb-redesign .article-sidebar a { color: var(--gb-accent); }
body.gb-redesign .article-content a:hover,
body.gb-redesign .article-sidebar a:hover,
body.gb-redesign .related-article a,
body.gb-redesign .related-article-info,
body.gb-redesign .article-container a:hover { color: var(--gb-accent-hi); }
body.gb-redesign .related-article-info { color: var(--gb-text2); }

/* Tła pod obrazkami (zanim się doczytaj�
) i pod avatarem. */
body.gb-redesign .article-content img,
body.gb-redesign .related-article-thumb,
body.gb-redesign img.avatar { background: var(--gb-panel); }

/* ------------------------------------------------- archiwa: kategoria, tag, autor
   Te szablony maj�
 własne arkusze (category.css, tag.css, author.css) w starej palecie. */
body.gb-redesign .category-article,
body.gb-redesign .tag-article,
body.gb-redesign .author-article,
body.gb-redesign .search-article { background: var(--gb-panel); }
body.gb-redesign .category-article-thumb,
body.gb-redesign .tag-article-thumb,
body.gb-redesign .author-article-thumb { background: var(--gb-card); }
body.gb-redesign .category-article-meta,
body.gb-redesign .category-article-author,
body.gb-redesign .category-article-date,
body.gb-redesign .tag-article-meta,
body.gb-redesign .author-article-meta { color: var(--gb-muted); }

/* --------------------------------------------------- biblioteka gier (plugin GGL)
   Plugin trzyma paletę w swoich zmiennych, więc wystarczy je przemapować -
   stany aktywne (chipy, oceny) same pójd�
 za nimi. */
body.gb-redesign {
  /* Most do zmiennych wtyczki. Wartosci sa przepisywane ze zmiennych motywu, nie
     powtarzane liczbowo - inaczej zmiana palety w :root omijalaby ten blok. */
  --ggl-bg-primary: var(--gb-panel);
  --ggl-bg-secondary: var(--gb-card2);
  --ggl-bg-card: var(--gb-card);
  --ggl-text-primary: var(--gb-text);
  --ggl-text-secondary: var(--gb-text2);
  --ggl-text-muted: var(--gb-muted);
  --ggl-accent-yellow: var(--gb-accent);
  --ggl-accent-red: var(--gb-red);
  --ggl-accent-green: var(--gb-green);
  /* Wtyczka biblioteki uzywa tej zmiennej w jednym miejscu (.ggl-badge--soon).
     "Wkrotce" to brak oceny, nie stan wymagajacy reakcji, wiec zmienna celuje
     w neutral - inaczej niebieski wracalby tylnymi drzwiami z wtyczki (GB-59). */
  --ggl-accent-blue: var(--gb-text2);
  --ggl-border: rgba(255, 255, 255, .07);
}

/* Rankingi maj�
 część kolorów wpisanych na sztywno, poza zmiennymi. */
body.gb-redesign .gbr-single-ranking,
body.gb-redesign .gbr-archive { background: transparent; }

body.gb-redesign .search-result { background: var(--gb-panel); }
body.gb-redesign .search-result-thumb { background: var(--gb-card); }
body.gb-redesign .search-result-excerpt { color: var(--gb-text2); }
body.gb-redesign .search-title,
body.gb-redesign .search-result-date { color: var(--gb-accent); }
body.gb-redesign .search-result-date { color: var(--gb-muted); }

/* Kafle kategorii w treści wpisu i pozostałe stare żółcienie w artykule. */
body.gb-redesign .article-container a[class*="category"] { background: var(--gb-card); }
body.gb-redesign .article-content strong,
body.gb-redesign .sidebar-section strong { color: var(--gb-text2); }
body.gb-redesign .article-container a { color: var(--gb-accent); }
body.gb-redesign .article-author a { background: var(--gb-card); color: var(--gb-text2); }
body.gb-redesign .article-author a:hover { color: var(--gb-accent); }

/* Chip filtrów w bibliotece gier ma tło wpisane na sztywno, poza zmiennymi. */
body.gb-redesign .ggl-chip { background: var(--gb-card); }
body.gb-redesign .ggl-chip.is-active { background: var(--gb-accent); color: var(--gb-panel); }

body.gb-redesign .page-numbers {
  background: var(--gb-card);
  color: var(--gb-text2);
  border-color: var(--gb-line);
}
body.gb-redesign a.page-numbers:hover { background: var(--gb-card2); color: var(--gb-accent); }
body.gb-redesign span.page-numbers.current,
body.gb-redesign .page-numbers.current {
  background: var(--gb-accent);
  color: var(--gb-panel);
}

/* ---------------------------------------------------------------- stopka (1a)
   Jeden w�
ski pasek: logo, zdanie o serwisie, linki dosunięte do prawej.
   Reguły starej stopki (.footer-info__*, .footer-tag, .footer-bottom) s�
 martwe,
   bo footer.php ich już nie renderuje. */
/* Stara reguła footer{} dokładała 30 px paddingu z góry i z dołu oraz marginesy,
   przez co w�
ski pasek z makiety puchł do ~170 px. */
.gb-footer {
  background: #101218;
  border-top: 1px solid var(--gb-line);
  margin: 40px 0 0;
  padding: 0;
  font-size: 13px;
  line-height: 1.5;
  /* stare footer{color:#fafafa} i footer a{color:#ddd} nadal celuj�
 w ten element */
  color: var(--gb-muted);
}
.gb-footer a { color: var(--gb-text2); }
/* GB-25: .gb-footer to flex-column (footer{display:flex} z main.css), więc pasek
   jest tu elementem flex z min-width:auto i nie schodził poniżej swojej szerokości
   min-content (1067 px). Przy oknie 1024 px rozpychało to całą stronę w poziomie.
   width:100% + min-width:0 przypina pasek do szerokości stopki, a tagline ma już
   ellipsis i to on oddaje miejsce. */
.gb-footer-inner {
  max-width: var(--gb-max); margin: 0 auto;
  width: 100%; min-width: 0; box-sizing: border-box;
  display: flex; align-items: center; gap: 20px;
  padding: 18px 24px;
}
.gb-footer-logo { display: flex; align-items: center; flex: none; }
.gb-footer-logo img { height: 22px; width: auto; display: block; }
.gb-footer-tagline {
  font-size: 13px; color: var(--gb-muted); font-weight: 600;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gb-footer-links {
  margin-left: auto; flex: none;
  display: flex; align-items: center; gap: 14px;
}
.gb-footer-menu {
  display: flex; align-items: center; gap: 14px;
  list-style: none; margin: 0; padding: 0;
}
/* inline-flex + line-height:1 na obu typach, bo <button> ma inną linię bazową
   niż <a> i "Ustawienia cookies" siadało niżej od reszty linków */
.gb-footer-links a,
.gb-footer-cookie {
  display: inline-flex; align-items: center; line-height: 1;
  font-size: 13px; font-weight: 400; letter-spacing: .4px;
  color: var(--gb-muted); text-decoration: none; text-transform: uppercase;
  background: none; border: none; padding: 0; margin: 0; cursor: pointer;
  font-family: inherit;
}
.gb-footer-menu li { display: inline-flex; align-items: center; line-height: 1; }
.gb-footer-links a:hover,
.gb-footer-cookie:hover { color: var(--gb-accent); }

@media (max-width: 900px) {
  .gb-footer-inner { flex-wrap: wrap; }
  /* flex:none z wersji desktopowej trzymało nawigację na szerokości max-content
     (563 px) i to ona rozpychała stronę na 360-390 px. Cały rząd na własnej
     linii + zawijanie w obu listach. */
  .gb-footer-links { margin-left: 0; flex: 1 1 100%; min-width: 0; flex-wrap: wrap; row-gap: 10px; }
  .gb-footer-menu { flex-wrap: wrap; row-gap: 10px; }
  .gb-footer-tagline { white-space: normal; }
}

@media (max-width: 600px) {
  .gb-footer-inner { padding: 16px 14px; row-gap: 14px; }
  .gb-footer-logo { flex: 1 1 100%; }
  .gb-footer-tagline { flex: 1 1 100%; }
  /* Linki stopki miały 13 px wysokości pola dotyku - za mało na palec. */
  .gb-footer-links a,
  .gb-footer-cookie { min-height: 40px; }
  .gb-footer-links { row-gap: 0; }
  .gb-footer-menu { row-gap: 0; }
}

/* Baner zgód używał starszego odcienia żółtego (#FFCC32) niż reszta redesignu. */
body.gb-redesign .cookie-banner {
  background: var(--gb-card); border: 1px solid var(--gb-line); color: var(--gb-text2);
}
body.gb-redesign .cookie-banner__content a { color: var(--gb-accent); }
body.gb-redesign .cookie-btn.primary { background: var(--gb-accent); color: var(--gb-panel); }
body.gb-redesign .cookie-btn.primary:hover { background: var(--gb-accent-hi); }
body.gb-redesign .cookie-btn.secondary {
  background: var(--gb-card); color: var(--gb-accent); border: 1px solid var(--gb-accent);
}
body.gb-redesign .cookie-btn.secondary:hover { background: var(--gb-card2); color: var(--gb-accent-hi); }

/* Widoki redesignu s�
 szersze niż stare 1200 px i tło bior�
 z <body>. */
body.gb-redesign-page .gb-main { max-width: none; background: transparent; }

/* PAS NAGŁÓWKA ZDEJMUJE OGRANICZENIE SAM.

   Klasa gb-redesign-page jest nadawana z listy tras w functions.php i ta lista
   z definicji jest niekompletna: nie ma na niej ani archiwów, ani widoków
   z wtyczek. Skutek był taki, że na /rankingi/ i /category/* pas nagłówka miał
   1420 px zamiast pełnej szerokości ekranu, czyli stał we wcięciu razem z kreską
   u dołu, a na /tryb/ czy /serwery/ szedł od krawędzi do krawędzi.

   Przy oknie 1440 px roznica wynosi 5 px i jest niewidoczna - dlatego przeszła
   przez pomiary. Widać ją dopiero powyżej 1500 px.

   Warunkiem jest obecnosc komponentu, nie nazwa trasy: strona z pasem nagłówka
   nie może miec ograniczonego kontenera, a każda nowa trasa dostanie to samo bez
   dopisywania jej do jakiejkolwiek listy. Szerokość treści pod pasem trzyma
   .gb-wrap, więc nic się nie rozjezdza. */
body.gb-redesign .gb-main:has(.gb-phead) { max-width: none; background: transparent; }

.gb-wrap { max-width: var(--gb-max); margin: 0 auto; padding: 0 24px; }

/* ==================================================================== nav */

/* PRZYKLEJONA NAWIGACJA (GB-114).

   `position: sticky` SIEDZI NA .gb-header, NIE NA .gb-nav-bar, i to nie jest
   szczegół stylistyczny. Element przyklejony trzyma się wyłącznie w obrębie
   swojego rodzica, a rodzicem paska jest .gb-header o wysokości dokładnie
   takiej jak pasek (61 px). Postawiony tam `sticky` nie miałby po czym jechać
   i odpłynąłby z pierwszym przewinięciem - bez żadnego błędu, po prostu nic
   by się nie kleiło. .gb-header leży wprost w <body>, więc dopiero on ma pod
   sobą całą wysokość strony.

   z-index 40 stawia nawigację NAD treścią, ale POD oknem wyboru na meczu (120)
   i przyciskiem powrotu do góry (9997): pasek nie ma prawa przykrywać okna,
   które czeka na decyzję gracza.

   Tło paska jest nieprzezroczyste celowo - przejeżdża nad treścią, więc
   półprzezroczyste pokazywałoby litery sunące pod napisami menu. */
body.gb-redesign > .gb-header {
  position: sticky;
  top: 0;
  z-index: 40;
}

.gb-nav-bar {
  background: var(--gb-panel);
  border-bottom: 1px solid var(--gb-line);

  /* Zostaje `relative`, bo mega-menu pozycjonuje się względem TEGO paska
     (rozciąga się pod całą jego szerokością). Przeniesienie tu `sticky`
     zabrałoby panelowi punkt odniesienia. */
  position: relative;
  z-index: 40;
}
.gb-nav-inner {
  max-width: var(--gb-max); margin: 0 auto;
  display: flex; align-items: center; gap: 18px;
  padding: 0 24px; height: 60px;
}
.gb-logo { display: flex; align-items: center; flex: none; }
.gb-logo img { height: 30px; width: auto; display: block; }

.gb-menu { display: flex; gap: 2px; align-items: center; }
/* UWAGA: bez position:relative. Mega-menu ma się rozci�
gać pod CAŁYM paskiem,
   więc jego punktem odniesienia jest .gb-nav-bar, a nie w�
ska pozycja menu. */
.gb-menu-item { position: static; }
.gb-menu-item > a {
  display: flex; align-items: center; gap: 5px;
  padding: 20px 11px;
  font-family: var(--gb-font);
  font-size: 14.5px; font-weight: 700; letter-spacing: .8px;
  color: var(--gb-text2); text-decoration: none;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
.gb-menu-item > a:hover { color: var(--gb-text); }
.gb-menu-item.is-active > a { color: var(--gb-accent); border-bottom-color: var(--gb-accent); }
/* Wage podajemy jawnie, bo strzalka dziedziczy 700 po pozycji menu,
   a przy 10,5 px z rozstrzeleniem robi sie z niej plama (prog 12 px). */
.gb-caret { font-size: 10.5px; font-weight: 600; opacity: .6; }
/* Biały na #ff4d5a daje 3,25:1, czyli poniżej progu AA dla drobnego tekstu.
   Ciemny napis na czerwonym to 5,6:1 i jest spójny z reszt�
 wypełnionych plakietek. */
.gb-live-badge {
  background: var(--gb-red); color: var(--gb-panel); font-weight: 600;
  font-size: 11.5px; padding: 1px 6px; border-radius: 8px; letter-spacing: .3px;
}

/* mega-menu: hover na desktopie, focus-within dla klawiatury.
   Rozci�
ga się na cał�
 szerokość paska; treść wyrównana do kontenera 1320 px. */
.gb-mega {
  position: absolute; top: 100%; left: 0; right: 0;
  display: none; gap: 28px;
  background: var(--gb-card2);
  border-bottom: 1px solid var(--gb-line);
  box-shadow: 0 28px 56px rgba(0, 0, 0, .55);
  padding: 22px max(24px, calc((100% - var(--gb-max)) / 2 + 24px));
  animation: gbMegaIn .16s ease both;
}
@keyframes gbMegaIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }

.gb-menu-item.has-mega:hover .gb-mega,
.gb-menu-item.has-mega:focus-within .gb-mega { display: grid; }
.gb-mega-rec { grid-template-columns: 1.1fr 1fr 1.1fr 300px; }
.gb-mega-tur { grid-template-columns: 1fr 1fr 280px; }
.gb-mega-graj { grid-template-columns: repeat(5, 1fr) 260px; gap: 14px; }
.gb-mega-serw { grid-template-columns: 1fr 1fr 1fr; gap: 14px; }

.gb-mega-title {
  font-size: 12px; font-weight: 600; letter-spacing: 1.2px;
  color: var(--gb-muted); margin-bottom: 8px;
}
/* Nagłówki kolumn mega-menu. Czerwień zostaje przy "TRWAJĄ TERAZ" / "NA ŻYWO",
   bo to ten sam stan pilny co plakietka LIVE w wierszach. Zieleń i niebieski
   przy "ZAPISY OTWARTE" i "NADCHODZĄ" schodzą do koloru bazowego nagłówka -
   stan jest w plakietce przy każdym wierszu, nagłówek go tylko powtarzał. */
.gb-mega-title.red { color: var(--gb-red); }
.gb-mega-title.green { color: var(--gb-muted); }
/* Wiersze mega-menu opisuje redesign-mega.css (.gb-mrow, .gb-mplain) - blok
   .gb-mega-row byl po poprzednim markupie i nie mial juz czego stylowac. */
.gb-mega-more {
  display: inline-block; margin-top: 8px;
  font-size: 13.5px; font-weight: 700; color: var(--gb-accent); text-decoration: none;
}
.gb-mega-empty { font-size: 14px; color: var(--gb-muted); line-height: 1.5; margin: 0 0 10px; }

.gb-mega-card {
  display: block; background: var(--gb-card);
  border: 1px solid var(--gb-line); border-radius: 8px;
  padding: 10px 12px; margin-bottom: 8px; text-decoration: none;
  transition: background .18s, border-color .18s;
}
.gb-mega-card:hover { background: var(--gb-hover-card); border-color: var(--gb-line2); }
.gb-mega-card .n { display: block; font-size: 14.5px; font-weight: 700; color: var(--gb-text); transition: color .18s; }
.gb-mega-card:hover .n { color: var(--gb-accent); }
.gb-mega-card .m { display: block; font-size: 13px; color: var(--gb-muted); font-weight: 600; margin-top: 3px; }

.gb-mega-feature a { text-decoration: none; display: block; }
.gb-mega-img {
  display: block; height: 110px; border-radius: 8px;
  background-size: cover; background-position: center;
}
.gb-mega-feature-title {
  display: block; font-size: 14.5px; font-weight: 700; color: var(--gb-text);
  margin-top: 8px; line-height: 1.4;
}

.gb-mega-tile {
  background: var(--gb-card); border: 1px solid var(--gb-line);
  border-radius: 10px; padding: 12px; text-align: center; text-decoration: none;
  display: block;
  transition: background .18s, border-color .18s;
}
.gb-mega-tile:hover { background: var(--gb-hover-card); border-color: var(--gb-line2); }
.gb-mega-tile .ic { display: block; font-size: 27px; }
.gb-mega-tile .n { display: block; font-size: 14px; font-weight: 700; color: var(--gb-text); margin-top: 4px; transition: color .18s; }
.gb-mega-tile:hover .n { color: var(--gb-accent); }
.gb-mega-tile .o { display: block; font-size: 12px; color: var(--gb-green); font-weight: 600; margin-top: 2px; }
.gb-mega-cta { display: flex; flex-direction: column; justify-content: center; gap: 8px; }

.gb-mega-server { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.gb-mega-server .n { font-size: 14.5px; font-weight: 700; color: var(--gb-text); }
.gb-mega-server .o { font-size: 12px; font-weight: 600; color: var(--gb-muted); white-space: nowrap; }
.gb-mega-server .o.on { color: var(--gb-green); }

/* Pole z adresem serwera. Kreskowana ramka wygl�
dała jak niedokończony placeholder,
   więc solidna ramka, wyraźny przycisk i potwierdzenie po skopiowaniu. */
.gb-copy {
  display: flex; gap: 10px; align-items: center; width: 100%;
  background: var(--gb-panel); border: 1px solid var(--gb-line);
  border-radius: 8px; padding: 9px 12px; margin-top: 8px; cursor: pointer;
  transition: border-color .18s, background .18s;
}
.gb-copy:hover { border-color: var(--gb-line2); background: var(--gb-card); }
.gb-copy .addr {
  flex: 1; min-width: 0; text-align: left;
  font-family: var(--gb-mono);
  font-size: 14px; color: var(--gb-accent);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gb-copy .ic {
  flex: none; font-size: 12px; font-weight: 600; letter-spacing: .6px;
  color: var(--gb-muted); text-transform: uppercase;
}
.gb-copy:hover .ic { color: var(--gb-text2); }
.gb-copy.is-copied { border-color: var(--gb-green); background: rgba(61, 220, 132, .06); }
.gb-copy.is-copied .ic { color: var(--gb-green); }

/* Wyszukiwarka: zamiast pola w pasku sama ikona otwieraj�
ca okno wyszukiwania. */
.gb-search-btn {
  margin-left: auto; flex: none;
  width: 36px; height: 36px; border-radius: 50%; padding: 0; cursor: pointer;
  display: grid; place-items: center;
  background: transparent; border: 1px solid transparent; color: var(--gb-muted);
  transition: color .18s, background .18s, border-color .18s;
}
.gb-search-btn svg { width: 19px; height: 19px; display: block; }
.gb-search-btn:hover { color: var(--gb-accent); background: var(--gb-hover); border-color: var(--gb-line2); }

/* Logowanie: normalny przycisk, nie atrapa pigułki użytkownika. */
.gb-login {
  display: flex; align-items: center; gap: 8px; flex: none;
  padding: 8px 16px; border-radius: 20px; text-decoration: none;
  border: 1px solid var(--gb-line2); color: var(--gb-text2);
  font-size: 13px; font-weight: 700; letter-spacing: .3px;
  transition: color .18s, border-color .18s, background .18s;
}
.gb-login svg { width: 17px; height: 17px; display: block; }
.gb-login:hover { color: var(--gb-accent); border-color: var(--gb-accent); background: var(--gb-hover); }
.gb-user {
  display: flex; align-items: center; gap: 10px; flex: none;
  background: var(--gb-card); border: 1px solid var(--gb-line);
  border-radius: 20px; padding: 5px 12px 5px 5px; text-decoration: none;
}
.gb-user-av {
  width: 28px; height: 28px; border-radius: 50%;
  background: linear-gradient(135deg, var(--gb-accent), var(--gb-red));
}
.gb-user-guest .gb-user-av { background: var(--gb-dim); }
.gb-user-nick { display: block; font-size: 14px; font-weight: 700; color: var(--gb-text); line-height: 1.1; }
.gb-user-elo { display: block; font-size: 12px; color: var(--gb-green); font-weight: 600; }
.gb-user-guest .gb-user-elo { color: var(--gb-muted); }

.gb-hamburger { display: none; background: none; border: none; cursor: pointer; padding: 8px; }
.gb-hamburger .bar { display: block; width: 22px; height: 2px; background: var(--gb-text2); margin: 4px 0; }

/* ================================================================ przyciski */

/* ------------------------------------------------------- system stanów hover
   Każdy przycisk ma reagować: kolor plus delikatne uniesienie, a przyciski
   prowadz�
ce dalej wysuwaj�
 strzałkę. */
.gb-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  text-align: center; text-decoration: none; cursor: pointer;
  font-size: 13.5px; font-weight: 700; letter-spacing: .4px;
  padding: 9px 18px; border-radius: 18px; border: 1px solid transparent;
  background: none; color: var(--gb-text2);
  transition: background .18s, color .18s, border-color .18s;
}
/* Strzałka wyjeżdża DOPIERO przy najechaniu, zza napisu: w spoczynku ma
   zerow�
 szerokość, więc przycisk nie rezerwuje na ni�
 miejsca. Bez glow i cieni. */
/* Jedna wysuwana strzalka dla przyciskow i linkow. Wczesniej ten sam
   siedmiodeklaracyjny blok stal osobno pod .gb-btn-arrow i .gb-link-arrow,
   a rozniły ich tylko dwa piksele marginesu na hoverze - i to jedyne,
   co zostalo osobno. */
.gb-btn-arrow::after,
.gb-link-arrow::after {
  content: '→';
  display: inline-block; overflow: hidden;
  max-width: 0; opacity: 0;
  transform: translateX(-6px);
  transition: max-width .22s ease, opacity .18s ease, transform .22s ease, margin-left .22s ease;
}
.gb-btn-arrow:hover::after,
.gb-btn-arrow:focus-visible::after,
.gb-link-arrow:hover::after,
.gb-link-arrow:focus-visible::after {
  max-width: 1.4em; opacity: 1; transform: translateX(0);
}
.gb-btn-arrow:hover::after,
.gb-btn-arrow:focus-visible::after {
  margin-left: 2px;
}

/* Ta sama zasada dla linków tekstowych typu "WSZYSTKIE", żeby cały serwis
   reagował jednakowo, a nie tylko część przycisków. Baza wyżej, tu zostaje
   jedyna różnica: link odsuwa strzałkę o piksel dalej niż przycisk. */
.gb-link-arrow:hover::after,
.gb-link-arrow:focus-visible::after {
  margin-left: 3px;
}
@media (prefers-reduced-motion: reduce) {
  .gb-btn-arrow::after, .gb-link-arrow::after { transition: none; }
}

.gb-btn-primary { background: var(--gb-accent); color: var(--gb-panel); }
.gb-btn-primary:hover { background: var(--gb-accent-hi); color: var(--gb-panel); }
.gb-btn-ghost { border-color: var(--gb-line2); color: var(--gb-text2); }
.gb-btn-ghost:hover { border-color: var(--gb-accent); color: var(--gb-accent); }
.gb-btn-outline { border-color: var(--gb-accent); color: var(--gb-accent); }
/* UWAGA: flex, nie block. `display:block` kasowało `inline-flex` z .gb-btn,
   przez co wysuwana strzałka przestawała być elementem flex i podskakiwała
   nad linię tekstu zamiast płynnie wyjeżdżać. */
.gb-btn-block { display: flex; width: 100%; }

/* ============================================================ nagłówki sekcji */

/* NAPISY RÓWNANE PO LINII PISMA, NIE PO ŚRODKU PUDEŁKA.
   W jednym wierszu stoją dwa różne rozmiary: tytuł sekcji 19,5 px i podpis
   13,5 px. Przy `align-items: center` wyśrodkowane są PUDEŁKA, a nie litery -
   a że przy line-height:1 pudełko ma wysokość liter, linia pisma mniejszego
   napisu wypada wtedy około 2 px wyżej niż tytułu. Oko czyta to jako napis
   wiszący w powietrzu, mimo że liczby się zgadzają.

   Kropka i kreska nie mają liter, więc do linii pisma równać ich nie ma jak -
   te dwa elementy zostają wyśrodkowane osobno. */
.gb-sec-head {
  display: flex; align-items: baseline; gap: 10px;
  margin: 28px 0 16px;
}
.gb-sec-dot {
  width: 8px; height: 8px; border-radius: 2px; flex: none;
  align-self: center;
}
/* Wszystkie napisy w nagłówku mają line-height:1, więc ich pudełka są wysokie
   dokładnie tyle co litery. Przy line-height:normal pudełka różniły się o kilka
   pikseli i link "WSZYSTKIE" siadał niżej niż tytuł sekcji. */
.gb-sec-title {
  font-family: var(--gb-font);
  font-size: 19.5px; font-weight: 700; letter-spacing: 1.5px; color: var(--gb-text);
  text-transform: uppercase; line-height: 1;
}
.gb-sec-note { font-size: 13.5px; font-weight: 700; line-height: 1; }
.gb-sec-pill {
  background: rgba(255, 77, 90, .15); color: var(--gb-red);
  font-size: 12px; font-weight: 600; padding: 3px 8px; border-radius: 10px;
}
.gb-sec-line { flex: 1; height: 1px; background: var(--gb-line); align-self: center; }
/* line-height: 1 jak w tytule sekcji - inaczej pudełko linku jest wyższe od
   liter i napis siada poniżej osi kreski. */
.gb-sec-more {
  font-size: 13.5px; font-weight: 700; color: var(--gb-muted);
  letter-spacing: .5px; text-decoration: none; white-space: nowrap;
  line-height: 1;
}
.gb-sec-more:hover { color: var(--gb-accent); }

/* ==================================================================== home */

.gb-home { display: grid; grid-template-columns: minmax(0, 1fr) 316px; gap: 24px; padding: 24px 0 40px; }
.gb-home-main { min-width: 0; }
.gb-home-side { display: flex; flex-direction: column; gap: 16px; }

/* ============================================================ hero (mokap v2)
   Po lewej lista kanałów z numeracją i paskiem odliczania, po prawej pełny kadr
   z powolnym najazdem. Z mokapu bierzemy kompozycję; paleta i krój zostają nasze. */

/* Hero MA ramkę - zgodnie z kanonem GB-60 opisanym przy zmiennych. Wcześniej
   jej tu nie było ("krecha 1 px czyta się jak prześwit między zdjęciem a
   krawędzią sekcji") i to była jedyna sekcja bez ramki na całej stronie
   głównej, czyli drugi język wizualny obok wszystkich pozostałych kontenerów.
   Dawny zarzut nie dotyczy tego układu: przy overflow:hidden i promieniu 12 px
   ramka leży POZA kadrem, nie na nim, a lewa kolumna z listą kanałów ma i tak
   płaskie tło panelu, więc bez ramki wisiała w powietrzu.
   box-sizing: border-box jest ustawione globalnie w main.css, więc ramka nie
   zmienia szerokości sekcji ani szerokości kolumn siatki. */
.gb-hero {
  display: grid;
  grid-template-columns: minmax(300px, 380px) minmax(0, 1fr);
  border: 1px solid var(--gb-line);
  border-radius: 12px;
  overflow: hidden;
  background: var(--gb-panel);
  min-height: 520px;
}

/* --------------------------------------------------------- lista kanałów */

.gb-hero-chan {
  display: flex; flex-direction: column; justify-content: center; gap: 4px;
  padding: 28px 22px;
  border-right: 1px solid var(--gb-line);
  background: linear-gradient(180deg, var(--gb-panel), var(--gb-card2));
}
.gb-hero-chan-kicker {
  font-size: 12px; font-weight: 600; letter-spacing: .22em; text-transform: uppercase;
  color: var(--gb-muted); margin-bottom: 14px; padding-left: 18px;
}

.gb-chan {
  display: flex; gap: 14px; align-items: baseline;
  text-align: left; cursor: pointer;
  padding: 14px 18px;
  background: transparent;
  border: none; border-left: 3px solid transparent;
  transition: background .18s ease, border-color .18s ease;
}
.gb-chan:hover { background: var(--gb-hover); }
.gb-chan.is-on { background: rgba(255, 255, 255, .05); border-left-color: var(--gb-accent); }

.gb-chan-body { min-width: 0; flex: 1; }
.gb-chan-title {
  display: block;
  font-size: 17px; font-weight: 700; line-height: 1.2; text-transform: uppercase;
  color: var(--gb-text2);
  /* dwie linie maksimum, żeby lista kanałów nie skakała przy długim tytule */
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
.gb-chan.is-on .gb-chan-title { color: var(--gb-text); }
.gb-chan-meta { display: block; font-size: 12.5px; color: var(--gb-muted); margin-top: 5px; }

/* pasek odliczania do następnego slajdu; rusza tylko na aktywnym kanale */
.gb-chan-bar {
  display: block; height: 2px; margin-top: 10px;
  background: rgba(255, 255, 255, .08); overflow: hidden;
}
.gb-chan-bar-fill {
  display: block; height: 100%; width: 100%;
  background: var(--gb-accent);
  transform-origin: left; transform: scaleX(0);
}
.gb-chan.is-on .gb-chan-bar-fill { animation: gbChanBar var(--gb-hero-delay, 7s) linear forwards; }
@keyframes gbChanBar { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* ---------------------------------------------------------------- kadr */

.gb-hero-stage { position: relative; overflow: hidden; min-height: 420px; }
.gb-hero-slide {
  position: absolute; inset: 0;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .6s ease, visibility .6s;
}
.gb-hero-slide.is-on { opacity: 1; visibility: visible; pointer-events: auto; }

.gb-hero-img {
  position: absolute; inset: 0;
  background-size: cover; background-position: center;
}
/* powolny najazd tylko na widocznym slajdzie */
.gb-hero-slide.is-on .gb-hero-img { animation: gbKen 18s ease-out both; }
@keyframes gbKen { from { transform: scale(1); } to { transform: scale(1.08); } }

/* Dwie warstwy: pionowe przyciemnienie pod tekstem i poziome od lewej krawędzi.
   Zdjęcie zostaje czytelne po prawej, tekst ma kontrast po lewej. */
.gb-hero-fade {
  position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(80deg, rgba(14, 16, 21, .93) 0%, rgba(14, 16, 21, .45) 42%, rgba(14, 16, 21, 0) 74%),
    linear-gradient(0deg, rgba(14, 16, 21, .95) 0%, rgba(14, 16, 21, 0) 52%);
}

/* Ocena: to samo kółko co na kartach, tylko większe. Jeden typ oceniarki
   w całym serwisie, żadnych osobnych kształtów per sekcja. */
.gb-hero-score {
  position: absolute; top: 24px; right: 24px;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  filter: drop-shadow(0 4px 18px rgba(0, 0, 0, .55));
}
.gb-hero-score-cap {
  font-size: 10px; font-weight: 600; letter-spacing: .18em; color: var(--gb-text2);
  text-shadow: 0 1px 8px rgba(0, 0, 0, .8);
}

/* ---------------------------------------------------------------- treść */

.gb-hero-text {
  position: absolute; left: clamp(20px, 3vw, 44px); right: 24px; bottom: 30px;
  max-width: 640px;
}
/* Zaokrąglenia jak w reszcie serwisu; mokap miał tu ostre kanty, ale wtedy
   plakietka i przycisk odstawały od wszystkich innych pigułek na stronie. */
.gb-hero-kicker {
  display: inline-block;
  font-size: 12.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .1em;
  padding: 5px 12px; border-radius: 4px;
  background: rgba(255, 194, 51, .16); color: var(--gb-accent);
}
/* Kicker hero trzyma jeden kolor. Fiolet dla sprzętu i czerwień dla gry
   dublowały napis, a czerwień dodatkowo kolidowała ze stanem "na żywo". */
.gb-kicker-sprzet,
.gb-kicker-gra { background: rgba(255, 194, 51, .16); color: var(--gb-accent); }

.gb-hero-title {
  margin: 12px 0 10px;
  font-size: clamp(28px, 3.2vw, 46px); font-weight: 700; line-height: 1.06;
  text-transform: uppercase;
  text-shadow: 0 2px 26px rgba(0, 0, 0, .6);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
.gb-hero-title a { color: var(--gb-text); text-decoration: none; }
.gb-hero-title a:hover { color: var(--gb-accent); }

.gb-hero-excerpt {
  margin: 0 0 18px;
  color: var(--gb-text2); font-size: 15.5px; line-height: 1.55; max-width: 520px;
  text-shadow: 0 1px 14px rgba(0, 0, 0, .6);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
.gb-hero-cta { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.gb-hero-meta { font-size: 13px; color: var(--gb-muted); }

/* Główne wezwanie hero. Kształt pigułki jak wszystkie przyciski w serwisie,
   tylko większy - mokapowy ścięty narożnik odstawał od reszty komponentów. */
.gb-cut-btn {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--gb-accent); color: var(--gb-panel);
  font-size: 15px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  padding: 12px 26px; text-decoration: none; border-radius: 22px;
  transition: background .18s ease;
}
.gb-cut-btn::after {
  content: '→'; display: inline-block; overflow: hidden;
  max-width: 0; opacity: 0; transform: translateX(-6px);
  transition: max-width .22s ease, opacity .18s ease, transform .22s ease;
}
.gb-cut-btn:hover { background: var(--gb-accent-hi); color: var(--gb-panel); }
.gb-cut-btn:hover::after { max-width: 1.4em; opacity: 1; transform: translateX(0); }

/* wjazd treści slajdu, schodkowo */
.gb-hero-slide.is-on .gb-hero-kicker { animation: gbUp .5s .08s ease-out both; }
.gb-hero-slide.is-on .gb-hero-title { animation: gbUp .5s .16s ease-out both; }
.gb-hero-slide.is-on .gb-hero-excerpt { animation: gbUp .5s .24s ease-out both; }
.gb-hero-slide.is-on .gb-hero-cta { animation: gbUp .5s .32s ease-out both; }
@keyframes gbUp { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .gb-hero-slide.is-on .gb-hero-img,
  .gb-hero-slide.is-on .gb-hero-kicker,
  .gb-hero-slide.is-on .gb-hero-title,
  .gb-hero-slide.is-on .gb-hero-excerpt,
  .gb-hero-slide.is-on .gb-hero-cta,
  .gb-chan.is-on .gb-chan-bar-fill { animation: none; }
  .gb-chan.is-on .gb-chan-bar-fill { transform: scaleX(1); }
}

@media (max-width: 1024px) {
  .gb-hero { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  .gb-hero-chan { order: 2; border-right: none; border-top: 1px solid var(--gb-line); padding: 18px 14px; }
  .gb-hero-chan-kicker { padding-left: 18px; }
  .gb-hero-stage { min-height: 380px; }
  .gb-hero-fade {
    background:
      linear-gradient(0deg, rgba(14, 16, 21, .96) 0%, rgba(14, 16, 21, .35) 55%, rgba(14, 16, 21, .1) 100%);
  }
}
@media (max-width: 640px) {
  .gb-hero-stage { min-height: 320px; }
  .gb-hero-text { left: 16px; right: 16px; bottom: 18px; }
  .gb-hero-score { width: 64px; height: 64px; top: 14px; right: 14px; }
  .gb-hero-score-in b { font-size: 23px; }
  .gb-chan-title { font-size: 15px; }
}
/* siatki kart */
.gb-grid { display: grid; gap: 14px; }
.gb-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.gb-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.gb-card {
  background: var(--gb-card); border: 1px solid var(--gb-line);
  border-radius: 10px; overflow: hidden;
  transition: border-color .18s, background .18s;
}
/* Hover na kaflu: powiększa się SAMO ZDJĘCIE, kafel stoi w miejscu.
   Plakietki i kółko oceny s�
 poza skalowan�
 warstw�
, więc nie pływaj�
. */
.gb-card:hover { border-color: var(--gb-line2); background: var(--gb-hover-card); }
/* Zoom okładki: jedyny ruch na hoverze. Skala startowa lekko podbita,
   bo skalowanie tła od 1.0 pokazywało skok na krawędziach kadru. */
.gb-card-img {
  position: absolute; inset: 0;
  background-size: cover; background-position: center;
  background-color: var(--gb-card2);
  transform: scale(1.01);
  transition: transform .5s cubic-bezier(.22, .61, .36, 1);
  will-change: transform;
}
.gb-card:hover .gb-card-img { transform: scale(1.06); }
/* Reduced motion zeruje CALY ruch z kanonu hoverow: zoom okladki i wysuwane
   strzalki. Podswietlenie (kolor, tlo, ramka) zostaje - to nie jest ruch. */
@media (prefers-reduced-motion: reduce) {
  .gb-card-img, .gb-card:hover .gb-card-img { transition: none; transform: none; }
  .gb-btn-arrow::after, .gb-btn-arrow:hover::after,
  .gb-link-arrow::after, .gb-link-arrow:hover::after,
  .gb-cut-btn::after, .gb-cut-btn:hover::after { transition: none; transform: none; }
}
/* Makieta rysowana była na kafelku ~300 px szerokości, gdzie 120 px wysokości dawało
   sensowny kadr. Przy kontenerze 1420 px kafel ma ~455 px i sztywne 120 px robiło
   z okładki w�
ski pasek, więc zamiast wysokości trzymamy proporcję 16:9. */
.gb-card-media {
  position: relative; display: block; overflow: hidden;
  aspect-ratio: 16 / 9; min-height: 120px;
  background: var(--gb-card2);
}
/* Kreska na styku okładki i treści kafla. Wcześniej brała kolor sekcji
   (--gb-sec) i przy czterech sekcjach dawała cztery różne 2 px paski na jednym
   ekranie - dekoracja, która nie niosła żadnej informacji ponad to, co i tak
   pisze w nagłówku sekcji. Teraz jest zwykłym separatorem z systemu linii. */
.gb-card-media::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: var(--gb-line);
}
.gb-card-badge {
  position: absolute; top: 8px; left: 8px;
  background: rgba(0, 0, 0, .55); font-size: 11.5px; font-weight: 600;
  letter-spacing: .8px; padding: 3px 7px; border-radius: 4px; color: var(--gb-accent);
}
/* Plakietka typu wpisu ma na sobie napisany typ wpisu, więc kolor był drugą
   kopią tej samej informacji - i to w czterech barwach naraz (czerwony, fiolet,
   niebieski, żółty). Jeden kolor dla wszystkich; rozróżnia napis. */
.gb-card-badge.gra,
.gb-card-badge.sprzet,
.gb-card-badge.recenzja { color: var(--gb-text2); }
.gb-card-score { position: absolute; bottom: 8px; right: 8px; }
.gb-card-body { padding: 12px 14px; }
.gb-card-title { font-size: 15px; font-weight: 700; line-height: 1.35; margin: 0; }
.gb-card-title a { color: var(--gb-text); text-decoration: none; }
.gb-card-title a:hover { color: var(--gb-accent); }
.gb-card-meta { font-size: 13.5px; color: var(--gb-muted); margin-top: 6px; font-weight: 600; }

/* turnieje */
.gb-tcard { padding: 14px 16px; }
.gb-tcard-top { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
/* Stan turnieju - hierarchia zamiast trzech równorzędnych kolorów (GB-59).
   Wcześniej "trwa", "zapisy otwarte" i "nadchodzi" krzyczały tak samo głośno
   w trzech barwach, przez co żaden nie wygrywał. Teraz:
     TRWA TERAZ  plakietka WYPEŁNIONA czerwienią - jedyna taka na widoku,
                 więc oko trafia w nią od razu, nawet na długiej liście;
     ZAPISY      plakietka OBRYSOWANA zielenią - widać, że coś można zrobić,
                 ale nie konkuruje z trwającym turniejem;
     NADCHODZI   plakietka OBRYSOWANA neutralnie - nie ma tu żadnej akcji,
                 więc nie ma i koloru.
   Wszystkie trzy mają ten sam kształt i rozmiar, więc różnicę niesie też
   sam napis, nie wyłącznie barwa (istotne przy daltonizmie). */
/* Plakietka jest pigulka poziomo (padding boczny), a pionowo trzyma sie
   wysokosci liter. Obrys idzie przez inset box-shadow, nie border: border
   doliczylby 2 px do wysokosci wiersza i cala karta turnieju uroslaby ze
   196 na 198 px. Tak wymiary kart zostaja co do piksela te same. */
.gb-tcard-status {
  display: inline-block;
  font-size: 12px; font-weight: 600; letter-spacing: 1px;
  padding: 0 8px; border-radius: 10px;
}
/* Ciemny napis na czerwieni daje 5,56:1; biel dałaby tylko 3,25:1. */
.gb-tcard-status.live { background: var(--gb-red); color: var(--gb-panel); }
/* Zieleń na tle karty to 9,12:1, więc plakietka obrysowana jest czytelna
   bez podkładu (podkład .15 zbijał czerwień do 4,18:1 - stąd przezroczyste). */
.gb-tcard-status.open { color: var(--gb-green); box-shadow: inset 0 0 0 1px rgba(61, 220, 132, .55); }
.gb-tcard-status.soon { color: var(--gb-muted); box-shadow: inset 0 0 0 1px var(--gb-line2); }
.gb-tcard-game { font-size: 12px; color: var(--gb-muted); font-weight: 600; text-transform: uppercase; }
.gb-tcard-title { font-size: 17px; font-weight: 700; color: var(--gb-text); margin: 8px 0 0; }
.gb-tcard-title a { color: var(--gb-text); text-decoration: none; }
.gb-tcard-title a:hover { color: var(--gb-accent); }
.gb-tcard-facts { display: flex; gap: 14px; margin-top: 10px; font-size: 13.5px; color: var(--gb-text2); font-weight: 600; flex-wrap: wrap; }
.gb-bar { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
/* track i fill to <span>-y, więc bez display:block wysokość i szerokość
   nie miały żadnego efektu i pasek był niewidoczny. */
.gb-bar-track {
  display: block; flex: 1; min-width: 0;
  height: 5px; background: var(--gb-panel); border-radius: 3px; overflow: hidden;
}
/* Pasek zapełnienia niesie informację DŁUGOŚCIĄ, nie barwą - a był malowany
   na zielono, czerwono albo niebiesko zależnie od stanu turnieju, czyli po raz
   trzeci powtarzał to, co pisze w plakietce i w liczbie obok. To były przy tym
   największe kolorowe plamy na liście. Zostaje neutralny.
   Jedyny wyjątek: .warn, czyli "zostało kilka miejsc" - to informacja, której
   nigdzie indziej nie ma, więc ma prawo do koloru. */
.gb-bar-fill { display: block; height: 100%; background: var(--gb-dec); border-radius: 3px; }
.gb-bar-fill.live,
.gb-bar-fill.soon { background: var(--gb-dec); }
.gb-bar-fill.warn { background: var(--gb-accent); }
.gb-bar-num { font-size: 12px; color: var(--gb-muted); font-weight: 600; white-space: nowrap; }
.gb-bar-num.is-bright { color: var(--gb-text2); }
.gb-tcard .gb-btn { margin-top: 12px; }

/* ------------------------------------------------- kafel gry (jeden komponent)
   Ten sam wygl�
d w mega-menu, na stronie głównej i w hubie /graj/.
   Wcześniej każde z tych miejsc miało własny układ ikony i liczby graczy. */
.gb-ptile {
  display: flex; flex-direction: column; gap: 12px;
  background: var(--gb-card); border: 1px solid var(--gb-line);
  border-radius: 12px; padding: 16px; text-decoration: none;
  transition: border-color .18s, background .18s;
}
.gb-ptile-compact { padding: 14px; }
.gb-ptile:hover,
a.gb-ptile:hover { border-color: var(--gb-line2); background: var(--gb-hover-card); }

.gb-ptile-head { display: flex; align-items: center; gap: 12px; min-width: 0; }
.gb-ptile-compact .gb-ptile-head { flex-direction: column; text-align: center; gap: 8px; }
.gb-ptile-ic {
  width: 46px; height: 46px; flex: none; border-radius: 12px;
  display: grid; place-items: center; font-size: 25px; color: var(--gb-panel); line-height: 1;
}
.gb-ptile-id { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.gb-ptile-name { font-size: 16px; font-weight: 700; color: var(--gb-text); }
.gb-ptile-online { font-size: 12.5px; color: var(--gb-green); font-weight: 700; }
.gb-ptile.is-soon .gb-ptile-online { color: var(--gb-muted); }
/* Przygaszamy samą ikonę, nie cały kafel: opacity na kontenerze ścinało kontrast
   napisu "silnik w budowie" do 3,55:1, a to zwykły <span>, nie natywny disabled,
   więc wyjątek WCAG dla elementów wyłączonych tu nie obowiązuje. */
.gb-ptile.is-soon .gb-ptile-ic { opacity: .55; }
.gb-btn.is-disabled {
  opacity: 1; cursor: default;
  color: var(--gb-muted); border-color: var(--gb-line);
}
.gb-ptile-desc { font-size: 13px; color: var(--gb-muted); font-weight: 600; line-height: 1.5; }
.gb-ptile-actions { display: flex; gap: 8px; margin-top: auto; }
.gb-ptile-actions .gb-btn { flex: 1; }
.gb-ptile-full { min-height: 214px; }
.gb-btn.is-disabled { opacity: .5; cursor: default; }

/* ----------------------------------------------------- feed zdarzeń z serwerów */
/* Pas serwerów przez cał�
 szerokość siatki strony głównej; feed siada w tej samej
   kolumnie co pasek boczny wyżej (316 px + 24 px odstępu), więc krawędzie się zgadzaj�
. */
.gb-servers-band { grid-column: 1 / -1; }
/* stretch, nie start: feed dociąga się do wysokości kolumny z kaflami, więc pod
   krótszą z nich nie zostaje pusty pas. Nadmiar wpisów feed chowa (ma overflow). */
.gb-servers { display: grid; grid-template-columns: minmax(0, 1fr) 316px; gap: 24px; align-items: stretch; }
.gb-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.gb-feed {
  background: var(--gb-card); border: 1px solid var(--gb-line);
  border-radius: 10px; overflow: hidden; display: flex; flex-direction: column;
}
.gb-feed-head {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 14px; background: var(--gb-card2); border-bottom: 1px solid var(--gb-line);
}
.gb-feed-title { font-size: 12px; font-weight: 600; letter-spacing: 1.2px; color: var(--gb-text); }
.gb-feed-spacer { flex: 1; }
.gb-feed-where { font-size: 11px; font-weight: 600; color: var(--gb-muted); }

/* Bez paska przewijania: lista ma stał�
 liczbę widocznych wierszy, a nowe
   zdarzenia wpychaj�
 najstarsze poza kadr. */
.gb-feed-list { list-style: none; margin: 0; padding: 0; overflow: hidden; }

/* Wjazd nowego zdarzenia: pojawia się z góry i podświetla na moment. */
@keyframes gbFeedIn {
  from { opacity: 0; transform: translateY(-10px); background: rgba(255, 194, 51, .1); }
  to   { opacity: 1; transform: none; background: transparent; }
}
.gb-feed-row.is-new { animation: gbFeedIn .45s cubic-bezier(.22, .61, .36, 1); }
@media (prefers-reduced-motion: reduce) { .gb-feed-row.is-new { animation: none; } }
/* Stała wysokość wiersza. Bez tego dłuższy wpis (3 linie) rozpychał listę
   i cała strona podskakiwała przy każdym nowym zdarzeniu. */
.gb-feed-row {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px; border-bottom: 1px solid var(--gb-line);
  height: 66px; box-sizing: border-box;
  transition: background .18s;
}
.gb-feed-row:last-child { border-bottom: none; }
.gb-feed-row:hover { background: var(--gb-hover); }
.gb-feed-ic {
  width: 26px; height: 26px; flex: none; border-radius: 7px;
  display: grid; place-items: center;
  background: rgba(255, 255, 255, .05); color: var(--gb-muted);
}
.gb-feed-ic svg { width: 15px; height: 15px; display: block; }
/* Rodzaj zdarzenia niesie IKONA (osobny rysunek na każdy typ) i treść wiersza.
   Kolor robił z tego drugi, równoległy kod - osiem typów w pięciu barwach,
   w kilkunastu wierszach jeden pod drugim. Ikony schodzą do neutralnych;
   czerwień zostaje tylko przy eliminacji, bo to jedyne zdarzenie, które ma
   wybić się z listy. */
.gb-feed-kill  .gb-feed-ic { color: var(--gb-red); background: rgba(255, 77, 90, .12); }
.gb-feed-bomb  .gb-feed-ic,
.gb-feed-raid  .gb-feed-ic,
.gb-feed-build .gb-feed-ic,
.gb-feed-trade .gb-feed-ic,
.gb-feed-boss  .gb-feed-ic,
.gb-feed-join  .gb-feed-ic,
.gb-feed-wipe  .gb-feed-ic { color: var(--gb-text2); background: rgba(255, 255, 255, .06); }

.gb-feed-body { flex: 1; min-width: 0; }
/* maksymalnie dwie linie treści zdarzenia, żeby wiersz nie urósł */
.gb-feed-line {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
  font-size: 13px; line-height: 1.4; color: var(--gb-text2);
}
.gb-feed-line .a { color: var(--gb-text); font-weight: 700; }
/* Drugi wyróżniony rzeczownik w wierszu: jeden kolor akcentu zamiast trzech
   (czerwony / fiolet / żółty zależnie od typu zdarzenia). */
.gb-feed-line .b { color: var(--gb-accent); font-weight: 700; }
.gb-feed-line .w { color: var(--gb-muted); }
.gb-feed-meta { display: block; font-size: 11px; color: var(--gb-muted); font-weight: 600; margin-top: 3px; }
.gb-feed-time {
  flex: none; font-size: 11px; font-weight: 600; color: var(--gb-muted);
  font-family: var(--gb-mono);
}

@media (max-width: 1100px) {
  .gb-servers { grid-template-columns: minmax(0, 1fr); }
  .gb-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 700px) {
  .gb-grid-2 { grid-template-columns: minmax(0, 1fr); }
}

/* serwery */
/* Tożsamość serwera niesie kolor gry, nie zrzut ekranu: pasek po lewej,
   delikatna poświata w rogu i literowy znacznik. Czytelność adresu zostaje. */
.gb-scard {
  padding: 16px 16px 16px 18px; display: flex; flex-direction: column; gap: 10px;
  position: relative; overflow: hidden;
  border-left: 3px solid var(--srv, var(--gb-line2));
}
/* Poświata w rogu kafla brała kolor gry (--srv) i przy czterech serwerach
   dawała cztery kolorowe plamy w jednym rzędzie. Zostaje sam rozjaśniony róg
   - kształt i głębia bez wnoszenia kolejnej barwy. */
.gb-scard::before {
  content: ''; position: absolute; top: -40%; right: -20%;
  width: 240px; height: 240px; border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, 1) 0%, transparent 68%);
  opacity: .06; pointer-events: none;
}
.gb-scard > * { position: relative; }
.gb-scard-map {
  font-size: 11.5px; font-weight: 600; color: var(--gb-accent);
  font-family: var(--gb-mono);
}
.gb-scard-top { display: flex; align-items: center; gap: 10px; }
/* Nazwa serwera trzyma się lewej krawędzi, status jest dosunięty do prawej. */
.gb-scard-name { flex: 1; min-width: 0; font-size: 16px; font-weight: 700; color: var(--gb-text); }
.gb-scard-status { font-size: 12px; font-weight: 600; color: var(--gb-green); white-space: nowrap; }
.gb-scard-desc { font-size: 13.5px; color: var(--gb-muted); font-weight: 600; }

/* ============================================================ kolumna boczna */

.gb-side-card { background: var(--gb-card); border: 1px solid var(--gb-line); border-radius: 12px; overflow: hidden; }
/* Jeden rząd: przy flex-wrap pigułki filtrów spadały pod tytuł i nagłówek rósł
   z 44 do 81 px, przez co panel wyglądał na rozjechany. */
.gb-side-head {
  display: flex; align-items: center; gap: 8px; flex-wrap: nowrap;
  padding: 10px 11px; border-bottom: 1px solid var(--gb-line);
  background: var(--gb-card2);
}
/* Po podbiciu skali napis "NEWSY LIVE" łamał się na dwie linie obok pigułek. */
.gb-side-title { white-space: nowrap; }
.gb-side-spacer { flex: 1 1 0; min-width: 0; }
/* Wspólna wysokość wiersza dla tytułu i pigułek: przy line-height:normal pudełko
   napisu było o 4 px niższe od pigułek i tekst siedział wyżej od nich. */
/* Węższa typografia tytułu: przy 14 px i świetle 1,2 px trzy pigułki filtrów
   nie mieściły się w 316-pikselowej kolumnie i "SPRZĘT" ucinała krawędź panelu. */
.gb-side-title {
  font-family: var(--gb-font);
  font-size: 13px; font-weight: 700; letter-spacing: .6px; color: var(--gb-text);
  line-height: 20px; align-self: center;
}
/* Kropka "na żywo" wg makiety: czerwony punkt przed nazwą panelu. */
.gb-live-dot {
  width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: var(--gb-red);
}
.gb-news-filters { display: flex; align-items: center; gap: 2px; flex: none; }
/* Wg makiety tylko aktywna pigułka ma tło; pozostałe są samym napisem, przez co
   rząd filtrów nie konkuruje wagą z nazwą panelu. */
.gb-pill {
  font-family: var(--gb-font); font-size: 11px; font-weight: 600;
  padding: 5px 8px; border-radius: 999px; border: none; cursor: pointer;
  line-height: 1; white-space: nowrap; letter-spacing: .2px;
  background: transparent; color: var(--gb-muted);
  transition: color .18s, background .18s;
}
.gb-pill:hover { color: var(--gb-text2); }
.gb-pill.is-on { background: var(--gb-accent); color: var(--gb-panel); }
/* Ciaśniej: po podbiciu skali typograficznej wiersze urosły i panel zrobił się
   dziurawy. Mniejszy padding, krótsza godzina, tytuł przycięty do trzech linii. */
.gb-news-row {
  display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px;
  border-bottom: 1px solid var(--gb-line); text-decoration: none;
  border-left: 2px solid transparent;
  transition: background .18s, border-color .18s;
}
/* Druga kolumna wiersza to zwykły <span> - bez min-width:0 długi tytuł
   rozpychałby wiersz zamiast się łamać. */
.gb-news-row > span:last-child { flex: 1 1 0; min-width: 0; }
.gb-news-row:hover { background: var(--gb-hover); border-left-color: var(--gb-accent); }
/* najnowszy wpis wyróżniony, ale reszta ma być tak samo czytelna */
.gb-news-row:first-of-type { border-left-color: var(--gb-red); background: rgba(255, 77, 90, .06); }
.gb-news-time {
  font-size: 12px; color: var(--gb-muted); font-weight: 600;
  min-width: 38px; line-height: 21px; letter-spacing: .2px;
  white-space: nowrap; flex: none;
}
/* Był tu drugi, jaśniejszy czerwony (#ff7a84) obok --gb-red - dwie czerwienie
   na jednym ekranie czytały się jak dwa różne stany. Jedna czerwień w serwisie. */
.gb-news-row:first-of-type .gb-news-time { color: var(--gb-red); }
/* display:block jest tu obowi�
zkowe: to <span>-y, więc bez tego autor i kategoria
   doklej�
 się do ostatniego wiersza tytułu zamiast stan�
ć w osobnej linii pod nim. */
.gb-news-title {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
  font-size: 14.5px; font-weight: 600; color: var(--gb-text); line-height: 21px;
  transition: color .18s;
}
/* Tytuly stoja na jednym stopniu skali, wiec najnowszy wpis wyrozniaja teraz
   waga 700, czerwona kreska i podklad wiersza - nie osobny odcien bieli. */
.gb-news-row:first-of-type .gb-news-title { font-weight: 700; color: var(--gb-text); }
.gb-news-row:hover .gb-news-title { color: var(--gb-accent); }
.gb-news-meta {
  display: block;
  font-size: 11.5px; color: var(--gb-muted); font-weight: 600; line-height: 15px; margin-top: 3px;
}
.gb-news-all {
  display: block; text-align: center; padding: 11px 12px;
  font-size: 13.5px; font-weight: 700; color: var(--gb-accent);
  letter-spacing: .5px; text-decoration: none;
}

/* Blok reklamowy dobiera cał�
 woln�
 wysokość kolumny bocznej, któr�
 inaczej
   zostawiałaby dłuższa kolumna treści. Sam baner zostaje przyklejony u góry,
   żeby był widoczny także przy przewijaniu obok długiej sekcji. */
.gb-ad { flex: 1; display: flex; flex-direction: column; min-height: 250px; }
.gb-ad-label { display: flex; justify-content: space-between; margin-bottom: 5px; }
.gb-ad-label span { font-size: 11px; font-weight: 600; letter-spacing: 1.5px; color: var(--gb-muted); }
.gb-ad-box {
  flex: 1; min-height: 250px; border-radius: 10px;
  border: 1px solid var(--gb-line); background: var(--gb-card2);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  position: sticky; top: var(--gb-stick);
}
.gb-ad-box b { font-size: 14px; font-weight: 700; color: var(--gb-muted); letter-spacing: 1px; }
.gb-ad-box span { font-size: 12px; font-weight: 600; color: var(--gb-muted); }

.gb-rank-card { padding: 14px; }
.gb-rank-title {
  font-family: var(--gb-font);
  font-size: 14px; font-weight: 700; letter-spacing: 1.2px; color: var(--gb-text); margin-bottom: 12px;
}
.gb-rank-row { display: flex; align-items: center; gap: 12px; }
.gb-rank-av { width: 44px; height: 44px; border-radius: 50%; background: linear-gradient(135deg, var(--gb-accent), var(--gb-red)); flex: none; }
.gb-rank-id { flex: 1; min-width: 0; }
.gb-rank-nick { font-size: 15px; font-weight: 700; color: var(--gb-text); }
.gb-rank-meta { font-size: 13px; color: var(--gb-muted); font-weight: 600; }
.gb-rank-elo { text-align: right; }
.gb-rank-elo b { display: block; font-size: 18px; font-weight: 700; color: var(--gb-green); }
.gb-rank-elo span { font-size: 12px; color: var(--gb-muted); font-weight: 600; }
.gb-rank-stats { display: flex; gap: 8px; margin-top: 12px; }
.gb-rank-stat { flex: 1; text-align: center; background: var(--gb-panel); border-radius: 8px; padding: 8px; }
.gb-rank-stat b { display: block; font-size: 16px; font-weight: 700; color: var(--gb-text); }
.gb-rank-stat span { font-size: 11.5px; color: var(--gb-muted); font-weight: 600; }

/* Panel "szybki start" siedział na fioletowym gradiencie z fioletową ramką i
   fioletowym tytułem - trzeci kolor akcentu w kolumnie bocznej, wyłącznie po
   to, żeby się wyróżnić. Wyróżnia go teraz to, co powinno: ramka mocniejsza
   niż w sąsiednich panelach i tytuł w akcencie serwisu. */
.gb-quick {
  background: var(--gb-card);
  border: 1px solid var(--gb-line); border-radius: 12px; padding: 14px;
}
.gb-quick-title {
  font-family: var(--gb-font);
  font-size: 14px; font-weight: 700; letter-spacing: 1.2px; color: var(--gb-accent); margin-bottom: 8px;
}
.gb-quick p { font-size: 14px; color: var(--gb-text2); line-height: 1.5; font-weight: 600; margin: 0 0 12px; }
/* Przycisk fioletowy (Discord, wątek meczu) zrównany z przyciskiem ghost -
   akcja drugorzędna nie potrzebuje własnej barwy. */
.gb-btn-violet { background: transparent; color: var(--gb-text2); border: 1px solid var(--gb-line2); }
.gb-btn-violet:hover { background: var(--gb-hover); color: var(--gb-accent); border-color: var(--gb-line2); }

/* ============================================================ kółko oceny */

.gb-ring { position: relative; display: inline-grid; place-items: center; }
.gb-ring svg { display: block; }
.gb-ring-val {
  position: absolute; font-family: var(--gb-font);
  font-weight: 700; color: var(--gb-text); line-height: 1;
}

/* ============================================================ lista turniejów */

.gb-page-head { padding: 28px 0 4px; }
.gb-page-title {
  font-family: var(--gb-font); font-size: 33.5px; letter-spacing: 1px;
  color: var(--gb-text); margin: 0; text-transform: uppercase;
}
.gb-page-lead { font-size: 15px; color: var(--gb-muted); font-weight: 600; margin: 6px 0 18px; }

.gb-filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 18px; }
.gb-filter {
  font-family: var(--gb-font); font-size: 14px; font-weight: 700; cursor: pointer;
  padding: 8px 14px; border-radius: 16px;
  background: var(--gb-card); border: 1px solid var(--gb-line2); color: var(--gb-text2);
}
.gb-filter.is-on { background: var(--gb-accent); border-color: var(--gb-accent); color: var(--gb-panel); }

.gb-demo-note {
  display: flex; gap: 10px; align-items: flex-start;
  background: rgba(255, 194, 51, .07); border: 1px solid rgba(255, 194, 51, .3);
  border-radius: 10px; padding: 12px 14px; margin: 0 0 20px;
  font-size: 14px; color: var(--gb-text2); line-height: 1.5;
}
.gb-demo-note b { color: var(--gb-accent); }

/* drabinka */
.gb-bracket { display: flex; gap: 18px; overflow-x: auto; padding-bottom: 8px; }
.gb-bracket-round { min-width: 240px; display: flex; flex-direction: column; gap: 12px; justify-content: space-around; }
.gb-bracket-name {
  font-size: 12px; font-weight: 600; letter-spacing: 1.2px; color: var(--gb-muted); margin-bottom: 4px;
}
.gb-match { background: var(--gb-card); border: 1px solid var(--gb-line); border-radius: 8px; overflow: hidden; }
.gb-match-row {
  display: flex; justify-content: space-between; gap: 10px;
  padding: 9px 12px; font-size: 14px; font-weight: 600; color: var(--gb-text2);
}
.gb-match-row + .gb-match-row { border-top: 1px solid var(--gb-line); }
.gb-match-row.win { color: var(--gb-text); font-weight: 700; }
.gb-match-row.win b { color: var(--gb-green); }
.gb-match-row.pending { color: var(--gb-muted); }

/* ============================================================ hub gier */

.gb-play { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 24px; padding: 24px 0 40px; }
.gb-quickmatch {
  background: var(--gb-card); border: 1px solid rgba(255, 194, 51, .3);
  border-radius: 12px; padding: 18px 20px;
  display: flex; align-items: center; gap: 18px; margin-bottom: 20px; flex-wrap: wrap;
}
.gb-quickmatch-ic {
  width: 52px; height: 52px; border-radius: 12px; background: var(--gb-accent);
  display: grid; place-items: center; font-size: 29px; flex: none;
}
.gb-quickmatch-txt { flex: 1; min-width: 180px; }
.gb-quickmatch-txt b { font-size: 18px; font-weight: 700; color: var(--gb-text); display: block; }
.gb-quickmatch-txt span { font-size: 14px; color: var(--gb-muted); font-weight: 600; }

.gb-gcard-media {
  height: 96px; background: var(--gb-card2);
  border-bottom: 1px solid var(--gb-line);
  display: grid; place-items: center; font-size: 42.5px;
}
.gb-gcard-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.gb-gcard-name { font-size: 16px; font-weight: 700; color: var(--gb-text); }
.gb-gcard-desc { font-size: 13px; color: var(--gb-muted); font-weight: 600; margin-top: 4px; }
.gb-gcard-actions { display: flex; gap: 6px; margin-top: 10px; }
.gb-gcard-actions .gb-btn { flex: 1; padding: 7px 8px; }

.gb-soon {
  background: var(--gb-card2); border: 1px solid var(--gb-line); border-radius: 12px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; min-height: 190px; text-align: center; padding: 16px;
}
.gb-soon b { font-size: 14px; color: var(--gb-muted); font-weight: 700; }
.gb-soon span { font-size: 13px; color: var(--gb-muted); font-weight: 600; }

.gb-top-row {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 0; border-bottom: 1px solid var(--gb-line);
}
.gb-top-row:last-child { border-bottom: none; }
.gb-top-place { font-size: 13.5px; font-weight: 700; width: 18px; color: var(--gb-text2); }
.gb-top-place.p1 { color: var(--gb-accent); }
.gb-top-av { width: 24px; height: 24px; border-radius: 50%; flex: none; }
.gb-top-nick { font-size: 14px; font-weight: 700; color: var(--gb-text); flex: 1; }
.gb-top-elo { font-size: 13.5px; font-weight: 700; color: var(--gb-green); }

/* Gracz, który jeszcze nie wszedł do tabeli. Bez numeru miejsca, bo żadnego
   nie ma - stoi tu informacja, ile partii brakuje. */
.gb-top-note {
  margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--gb-line);
  font-size: 12.5px; font-weight: 600; color: var(--gb-muted);
}

/* ============================================================ recenzja 1g */

.gb-verdict {
  background: var(--gb-card); border: 1px solid var(--gb-line);
  border-radius: 12px; padding: 20px 22px; margin: 0 0 24px;
  display: grid; grid-template-columns: 92px minmax(0, 1fr); gap: 22px; align-items: start;
}
.gb-verdict-score { text-align: center; }
.gb-verdict-label {
  font-size: 12px; font-weight: 600; letter-spacing: 1.2px;
  color: var(--gb-muted); margin-top: 8px;
}
.gb-verdict-body { min-width: 0; }
.gb-verdict-title {
  font-family: var(--gb-font); font-size: 16px; letter-spacing: 1px;
  color: var(--gb-muted); margin: 0 0 8px; text-transform: uppercase;
}
.gb-verdict-text { font-size: 16px; line-height: 1.6; color: var(--gb-text2); margin: 0 0 16px; }
.gb-pros-cons { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.gb-pc-title { font-size: 13.5px; font-weight: 700; letter-spacing: 1px; margin-bottom: 8px; }
.gb-pc-title.pro { color: var(--gb-green); }
.gb-pc-title.con { color: var(--gb-red); }
.gb-pc-list { list-style: none; margin: 0; padding: 0; }
.gb-pc-list li {
  position: relative; padding-left: 18px; margin-bottom: 6px;
  font-size: 14.5px; line-height: 1.45; color: var(--gb-text2);
}
.gb-pc-list li::before { position: absolute; left: 0; font-weight: 700; }
.gb-pc-list.pro li::before { content: '+'; color: var(--gb-green); }
.gb-pc-list.con li::before { content: '−'; color: var(--gb-red); }

/* ================================================================ responsive */

@media (max-width: 1200px) {
  .gb-menu-item > a { padding: 20px 8px; font-size: 14px; }
  .gb-search { display: none; }
}

@media (max-width: 1024px) {
  .gb-home, .gb-play { grid-template-columns: minmax(0, 1fr); }
  .gb-grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .gb-hero-body { grid-template-columns: minmax(0, 1fr); }
  .gb-hero-fade { background: linear-gradient(0deg, var(--gb-panel) 20%, rgba(20, 22, 28, .7) 70%, rgba(20, 22, 28, .3) 100%); }
  .gb-mega { display: none !important; }
}

@media (max-width: 1080px) {
  .gb-hamburger { display: block; margin-left: auto; }
  .gb-menu {
    display: none; position: absolute; top: 60px; left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--gb-card2); border-bottom: 1px solid var(--gb-line);
    box-shadow: 0 28px 56px rgba(0, 0, 0, .55); padding: 8px 0;
  }
  .gb-menu.is-open { display: flex; }
  .gb-menu-item > a { padding: 13px 20px; border-bottom: none; }
  .gb-menu-item.is-active > a { background: rgba(255, 194, 51, .08); }
  .gb-user { display: none; }
  .gb-grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
  .gb-wrap { padding: 0 14px; }
  .gb-nav-inner { padding: 0 14px; gap: 10px; }
  .gb-grid-3, .gb-grid-4 { grid-template-columns: minmax(0, 1fr); }
  .gb-hero-title { font-size: 27px; }
  .gb-hero-text { padding: 20px; }
  .gb-verdict { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .gb-pros-cons { grid-template-columns: minmax(0, 1fr); }
  .gb-page-title { font-size: 26px; }
}

/* Znak "+" w kaflu zapowiedzi jest czysto dekoracyjny (aria-hidden). */
.gb-soon-plus { font-size: 22px; color: var(--gb-dim); line-height: 1; }

/* ==================================================================== lobby
   Stoły otwarte teraz + panel filtrów po prawej. Kolor gry niesie zmienna
   --srv ustawiana na wierszu stołu. */
/* Odstęp od góry daje teraz pas nagłówka (gb_hero ma margines dolny), więc
   lobby zaczyna się od razu - własny padding-top dokładałby drugą dziurę. */
.gb-lobby { display: grid; grid-template-columns: minmax(0, 1fr) 316px; gap: 24px; padding: 0 0 40px; align-items: start; }
.gb-lobby-main { min-width: 0; }
/* Pierwszy nagłówek sekcji w kolumnie stoi tuż pod pasem: jego własny górny
   margines byłby doliczony do marginesu pasa. */
.gb-lobby-main > .gb-sec-head:first-child { margin-top: 0; }
.gb-lobby-side { display: flex; flex-direction: column; gap: 16px; }

.gb-tables { display: flex; flex-direction: column; gap: 8px; }
.gb-tables-info {
  padding: 22px 18px; text-align: center;
  background: var(--gb-card); border: 1px solid var(--gb-line); border-radius: 10px;
  color: var(--gb-muted); font-size: 13.5px;
}

.gb-table {
  display: grid; grid-template-columns: 130px 92px minmax(0, 1fr) auto;
  align-items: center; gap: 14px;
  padding: 13px 16px; text-decoration: none;
  background: var(--gb-card); border: 1px solid var(--gb-line);
  border-left: 3px solid var(--srv, var(--gb-muted)); border-radius: 10px;
  transition: border-color .18s, background .18s;
}
.gb-table:hover { background: var(--gb-hover-card); border-color: var(--gb-line2); border-left-color: var(--srv, var(--gb-accent)); }
.gb-table-game { font-size: 14.5px; font-weight: 700; color: var(--gb-text); }
.gb-table-code {
  font-family: var(--gb-mono);
  font-size: 13px; font-weight: 700; color: var(--srv, var(--gb-accent)); letter-spacing: 1px;
}
.gb-table-meta { font-size: 12.5px; color: var(--gb-muted); }
.gb-table-cta {
  font-size: 12px; font-weight: 600; letter-spacing: .4px; text-transform: uppercase;
  padding: 7px 15px; border-radius: 16px;
  border: 1px solid var(--gb-line2); color: var(--gb-text2); white-space: nowrap;
}
.gb-table-cta.is-free { background: var(--gb-accent); border-color: var(--gb-accent); color: var(--gb-panel); }

.gb-lobby-panel { padding: 16px; }
.gb-lobby-hint { font-size: 12.5px; color: var(--gb-muted); margin: 0 0 12px; line-height: 1.5; }
.gb-lobby-new { display: flex; flex-direction: column; gap: 8px; }
.gb-lobby-new-btn {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 12px; text-decoration: none;
  background: var(--gb-panel); border: 1px solid var(--gb-line); border-radius: 10px;
  transition: border-color .18s, background .18s;
}
.gb-lobby-new-btn:hover { border-color: var(--gb-line2); background: var(--gb-card); }
.gb-lobby-new-btn .ic {
  width: 34px; height: 34px; flex: none; border-radius: 9px;
  display: grid; place-items: center; font-size: 19px; color: var(--gb-panel); line-height: 1;
}
.gb-lobby-new-btn .n { font-size: 14px; font-weight: 700; color: var(--gb-text); }

.gb-lobby-fgroup { margin-top: 14px; }
.gb-lobby-fgroup:first-of-type { margin-top: 0; }
.gb-lobby-flabel {
  display: block; font-size: 11px; font-weight: 600; letter-spacing: 1px;
  color: var(--gb-muted); text-transform: uppercase; margin-bottom: 7px;
}
.gb-lobby-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.gb-lobby-code { display: flex; gap: 8px; }
.gb-lobby-code input {
  flex: 1; min-width: 0; padding: 8px 12px; border-radius: 8px;
  background: var(--gb-panel); border: 1px solid var(--gb-line2); color: var(--gb-text);
  font-family: var(--gb-mono);
  font-size: 13px; letter-spacing: 2px; text-transform: uppercase;
}
.gb-lobby-code input:focus { outline: none; border-color: var(--gb-accent); }

@media (max-width: 1080px) {
  .gb-lobby { grid-template-columns: minmax(0, 1fr); }
  .gb-table { grid-template-columns: 1fr auto; row-gap: 6px; }
  .gb-table-meta { grid-column: 1 / -1; }
}

/* ------------------------------------------- sekcja serwerów: jedna kolumna
   Trzy szerokie kafle jeden pod drugim mają łącznie tę samą wysokość co feed
   obok, więc znika i dziura po trzecim kaflu, i pusty pas pod siatką. */
.gb-srv-stack { grid-template-columns: minmax(0, 1fr); gap: 12px; align-content: start; }
.gb-srv-stack .gb-scard { min-height: 0; }

/* ============================================================================
   WIDOK MOBILNY: uklad i szerokosci (GB-25 i zgloszenia z 2026-08-07)
   Tylko geometria - zadnych regul :hover, te maja wlasna sekcje nizej.
   ========================================================================== */

/* sections.css (stary arkusz, ladowany razem z redesignem) trzyma w
   @media (max-width: 900px) regule `section { padding-left:10px; padding-right:10px }`.
   Trafia w KAZDY <section> redesignu, wiec karty z wlasnym paskiem naglowka
   dostawaly 11 px luzu (10 px paddingu + 1 px ramki) z obu stron i naglowek
   wygladal na wklejony w srodek karty zamiast siegac jej krawedzi.
   Karty z ramka i naglowkiem odzyskuja pelna szerokosc; .gb-rank-card zostaje
   z wlasnym paddingiem 14 px, bo jego tresc nie ma paska naglowka. */
@media (max-width: 900px) {
  body.gb-redesign section.gb-side-card:not(.gb-rank-card),
  body.gb-redesign section.gb-feed {
    padding-left: 0;
    padding-right: 0;
  }
}

@media (max-width: 640px) {
  /* Pasek nawigacji przy 360 px potrzebowal 426 px: logo 171 + hamburger 38 +
     lupa 36 + "Zaloguj sie" 123 + odstepy i padding. Logo schodzi o 4 px,
     a logowanie zostaje sama ikona - przy okazji rosnie do pola dotyku 40 px. */
  .gb-logo img { height: 26px; }
  .gb-login {
    position: relative;
    width: 40px; height: 40px; padding: 0;
    justify-content: center; border-radius: 50%;
  }
  /* Napis chowamy wizualnie, nie przez display:none - ikona jest aria-hidden,
     wiec bez tego tekstu link stracilby nazwe dostepna dla czytnika ekranu. */
  .gb-login > span {
    position: absolute; width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap;
  }
  .gb-hamburger {
    width: 40px; height: 40px; padding: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
  }
  .gb-search-btn { width: 40px; height: 40px; }

  /* Pola dotyku ponizej 40 px: pigulki filtrow i linki "wiecej" w naglowkach
     sekcji mialy 21-25 px wysokosci. Rosnie tylko obszar klikalny, nie typografia. */
  .gb-pill { min-height: 40px; min-width: 40px; display: inline-flex; align-items: center; justify-content: center; }
  .gb-sec-more { min-height: 40px; display: inline-flex; align-items: center; }
  .gb-logo, .gb-footer-logo { min-height: 40px; }
}

/* ============================================================================
   KANON HOVEROW: neutralizacja starych arkuszy
   main.css, sections.css, category.css, author.css i search.css sa ladowane
   razem z redesignem i wnosza wlasne hovery: podnoszenie kafla o 4 px, cienie
   i poswiate wokol przycisku. Ponizsze reguly gasza to w obrebie body.gb-redesign,
   zeby w calym serwisie zostal jeden system: podswietlenie zamiast ruchu.
   Selektor z #games-section jest potrzebny, bo regula w sections.css ma w sobie
   identyfikator i bez niego wygrywa ze zwyklym .gb-redesign.
   ========================================================================== */
body.gb-redesign #games-section .ggl-game-card:hover { transform: none; box-shadow: none; }
body.gb-redesign .search-result:hover,
body.gb-redesign .search-result:focus-within { transform: none; box-shadow: none; }
body.gb-redesign .category-article:hover,
body.gb-redesign .author-article:hover { box-shadow: none; }
body.gb-redesign .btn-more:hover,
body.gb-redesign .btn-more:focus { box-shadow: none; }
body.gb-redesign .featured-card:hover img,
body.gb-redesign .side-card:hover img,
body.gb-redesign .regular-card:hover img { box-shadow: none; transform: scale(1.06); }

/* ------------------------------------------------------------------ PREMIUM
   Odznaka przy nicku. Stoi wszędzie, gdzie pada nick, więc musi być cicha:
   to znacznik konta, a nie wyróżnienie w tabeli wyników. Stąd obrys zamiast
   wypełnienia i rozmiar liczony w `em`, żeby skalowała się razem z nickiem
   w rankingu, przy stole i w nagłówku profilu. */
.gb-premium-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border: 1px solid var(--gb-accent);
  border-radius: 999px;
  color: var(--gb-accent);
  font-size: .68em;
  font-weight: 700;
  letter-spacing: .08em;
  line-height: 1.5;
  vertical-align: middle;
  white-space: nowrap;
}
.gb-premium-badge.is-small { font-size: .6em; padding: 0 5px; margin-left: 5px; }

/* W wąskiej tabeli rankingu sam obrys wystarczy za napis: przy 360 px nick
   z dopiskiem PREMIUM łamał wiersz i rozjeżdżał kolumny. */
@media (max-width: 480px) {
  .gb-rank-nick .gb-premium-badge,
  .gb-top-nick .gb-premium-badge {
    width: 8px; height: 8px; padding: 0; border-radius: 50%;
    background: var(--gb-accent); border: none;
    overflow: hidden; text-indent: -99em;
  }
}

/* ------------------------------------------------------- STRONA /premium/
   Cztery okresy obok siebie porównuje się wzrokiem, więc karty muszą mieć
   równą wysokość i cenę w tym samym miejscu w każdej z nich. Stąd flex
   z rozpychaniem listy faktów, a nie zwykły blok. */
.gb-prem-state { display: flex; align-items: center; gap: 12px; margin-bottom: 22px; padding: 16px 18px; }
.gb-prem-state p { margin: 0; font-size: 14px; color: var(--gb-muted); }
.gb-prem-state b { color: var(--gb-text); }

/* Karty przywilejów mają własną wysokość, nie wyciągają się do najwyższej
   w rzędzie. Grupy różnią się liczbą pozycji (Wygląd ma jedną, Wygoda trzy),
   więc przy domyślnym `stretch` krótsza karta kończyła się pasem pustego tła
   na całą różnicę. */
.gb-prem-groups { align-items: start; }
.gb-prem-group { padding: 18px; }
.gb-prem-group-name {
  margin: 0 0 12px; font-size: 13px; font-weight: 700;
  letter-spacing: .1em; color: var(--gb-accent);
}
.gb-prem-list { list-style: none; margin: 0; padding: 0; }
.gb-prem-list li { padding: 9px 0; border-bottom: 1px solid var(--gb-line); }
.gb-prem-list li:last-child { border-bottom: none; }
.gb-prem-list b { display: block; font-size: 14.5px; color: var(--gb-text); }
.gb-prem-list span { display: block; margin-top: 3px; font-size: 13px; line-height: 1.5; color: var(--gb-muted); }

.gb-prem-fair {
  margin: 18px 0 0; padding: 14px 16px;
  border-left: 3px solid var(--gb-accent);
  background: rgba(255, 194, 51, .05);
  font-size: 13.5px; line-height: 1.6; color: var(--gb-muted);
}

/* Plakietka wystaje ponad krawędź karty, a .gb-card tnie wszystko przez
   `overflow: hidden` (potrzebne tam, gdzie w kaflu siedzi zdjęcie). Ta karta
   zdjęcia nie ma, więc przycinanie jej nie jest do niczego potrzebne i można
   je zdjąć punktowo. Siatka dostaje odstęp od góry na te wystające 9 px. */
.gb-prem-plans { margin-top: 14px; }

.gb-prem-plans .gb-prem-plan {
  display: flex; flex-direction: column; position: relative;
  overflow: visible;
  padding: 20px 18px; text-align: center;
}
.gb-prem-plan.is-best { border-color: var(--gb-accent); }
.gb-prem-tag {
  position: absolute; top: -9px; left: 50%; transform: translateX(-50%);
  padding: 3px 11px; border-radius: 999px;
  background: var(--gb-accent); color: #14161c;
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em; line-height: 1.2;
  white-space: nowrap;
}
.gb-prem-plan-name { margin: 0; font-size: 14px; font-weight: 600; color: var(--gb-muted); }
.gb-prem-price { margin: 10px 0 2px; font-size: 27px; font-weight: 700; color: var(--gb-text); line-height: 1.1; }
.gb-prem-permonth { font-size: 13px; font-weight: 600; color: var(--gb-accent); }

/* Lista faktów jako kolumna z jednym odstępem zamiast rytmu z line-height.
   Pierwsza pozycja niesie kwotę z ikoną monety (inline-flex), więc jej wiersz
   był wyższy od pozostałych i cała lista wyglądała na rozjechaną. */
.gb-prem-plan-facts {
  list-style: none; margin: 14px 0 0; padding: 14px 0 0;
  border-top: 1px solid var(--gb-line);
  display: flex; flex-direction: column; gap: 7px;
  font-size: 12.5px; line-height: 1.45; color: var(--gb-muted);
}
.gb-prem-plan-facts li {
  display: flex; align-items: center; justify-content: center;
  gap: 5px; min-height: 18px;
}

/* Przycisk przyklejony do dna karty. Plany mają różną liczbę wierszy (rabat
   pokazujemy tylko tam, gdzie jest), więc bez tego przyciski w rzędzie stały
   na trzech różnych wysokościach. */
.gb-prem-plan .gb-btn,
.gb-prem-plan .gb-prem-buy { margin-top: auto; }
.gb-prem-plan-facts + .gb-btn,
.gb-prem-plan-facts + form,
.gb-prem-plan-facts + .gb-prem-buy { margin-top: auto; padding-top: 14px; }

.gb-prem-note { margin: 0 0 14px; font-size: 13.5px; line-height: 1.6; color: var(--gb-muted); }
.gb-prem-soon { margin-top: 22px; padding: 16px 18px; }
.gb-prem-soon p { margin: 0 0 4px; font-size: 13.5px; line-height: 1.6; color: var(--gb-muted); }
.gb-prem-soon p:last-child { margin-bottom: 0; }
.gb-prem-soon b { color: var(--gb-text); }

.gb-hist-more { margin: 10px 0 0; font-size: 13px; color: var(--gb-muted); }

/* -------------------------------------------------------- SKLEPIK /sklep/ */
.gb-shop-msg { margin-bottom: 18px; padding: 14px 16px; border-left: 3px solid var(--gb-accent); }
.gb-shop-msg.is-error { border-left-color: #ff4c53; }
.gb-shop-msg p { margin: 0; font-size: 14px; color: var(--gb-text); }

.gb-shop-wallet {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 18px 0; padding: 14px 18px;
}
.gb-shop-wallet p { margin: 0; font-size: 14px; color: var(--gb-muted); }
.gb-shop-balance { font-size: 26px; font-weight: 700; color: var(--gb-accent); line-height: 1; }
.gb-shop-balance-label { font-size: 13px; font-weight: 600; color: var(--gb-muted); margin-right: auto; }

.gb-shop-link-note {
  margin: 0 0 14px; padding: 12px 14px;
  border: 1px dashed var(--gb-line); border-radius: 8px;
  font-size: 13px; line-height: 1.6; color: var(--gb-muted);
}
.gb-shop-link-note code { padding: 1px 6px; border-radius: 4px; background: rgba(255,255,255,.06); }

/* Karta pozycji: cena i przycisk zawsze na tej samej wysokości w całym rzędzie,
   bo inaczej porównanie czterech pozycji wymaga wodzenia wzrokiem po skosie. */
.gb-shop-item { display: flex; flex-direction: column; padding: 16px; }
.gb-shop-img { width: 100%; height: 132px; object-fit: contain; margin-bottom: 10px; }
.gb-shop-kind {
  align-self: flex-start; padding: 1px 8px; margin-bottom: 8px;
  border: 1px solid var(--gb-line); border-radius: 999px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .08em; color: var(--gb-muted);
}
.gb-shop-name { margin: 0 0 6px; font-size: 15.5px; line-height: 1.3; color: var(--gb-text); }
.gb-shop-desc { margin: 0 0 12px; font-size: 13px; line-height: 1.55; color: var(--gb-muted); }
.gb-shop-price {
  margin-top: auto; padding: 10px 0;
  font-size: 19px; font-weight: 700; color: var(--gb-accent);
}
.gb-shop-buy { margin: 0; }

/* Zakupy w profilu. */
.gb-buys { list-style: none; margin: 0; padding: 0; }
.gb-buys li {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 11px 0; border-bottom: 1px solid var(--gb-line);
  font-size: 13.5px; color: var(--gb-muted);
}
.gb-buys li:last-child { border-bottom: none; }
.gb-buys .n { flex: 1 1 200px; color: var(--gb-text); font-weight: 600; }
.gb-buys .s { padding: 1px 8px; border-radius: 999px; font-size: 11.5px; font-weight: 700; letter-spacing: .05em; }
.gb-buys .s.pending   { color: #ffc233; border: 1px solid #ffc233; }
.gb-buys .s.delivered { color: #5fffbc; border: 1px solid #5fffbc; }
.gb-buys .s.refunded  { color: var(--gb-muted); border: 1px solid var(--gb-line); }

/* --------------------------------------------------------- KWOTA W GBCOINS
   Moneta zamiast skrótu „kr.". Skrót trzeba przeczytać i rozszyfrować,
   a przy cenie na kaflu liczy się rozpoznanie w ćwierć sekundy. Ikona mówi
   „to nie są złotówki" bez ani jednego słowa. */
.gb-amount {
  display: inline-flex; align-items: center; gap: .38em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.gb-coin {
  width: 1em; height: 1em; flex: 0 0 auto;
  color: var(--gb-accent);
  /* Moneta siada na linii bazowej cyfr, nie na środku wiersza: inaczej
     przy dużym stopniu pisma odjeżdża w górę. */
  transform: translateY(-.03em);
}
.gb-amount-num { font-weight: inherit; }
.gb-amount.is-big { font-size: 26px; font-weight: 700; color: var(--gb-accent); }
.gb-amount.is-big .gb-coin { color: var(--gb-accent); }

/* Wewnątrz przycisku „brakuje X" moneta ma iść za kolorem napisu, a nie
   świecić na żółto na wyszarzonym tle. */
.gb-btn .gb-coin { color: currentColor; }

/* ================================================== NAGŁÓWEK PODSTRONY
   Jeden komponent dla całego serwisu (gb_hero).

   PAS PRZEZ CAŁĄ SZEROKOŚĆ, nie wcięta karta. Tło sięga obu krawędzi ekranu,
   treść trzyma się tej samej siatki co reszta strony, a całość kończy się
   wyraźną kreską odcinającą nagłówek od treści.

   Wcięta karta z zaokrągleniem (tak wyglądał ranking) zamykała nagłówek
   w prostokącie i robiła z niego kolejny kafel wśród kafli. Pas daje stronie
   górę i mówi, gdzie kończy się wstęp, a zaczyna treść. Kreska u dołu jest
   tym, co odcina, a nie ramka dookoła.

   Obrazek jest elementem <img>, nie tłem. Ranking używał background-image
   i musiał ratować się `background-clip: padding-box`, bo tło szło pod ramkę,
   a przyciemnienie kończyło się na padding-boksie i wzdłuż krawędzi biegł
   pasek surowego zdjęcia. Dziecko w kontenerze z `overflow:hidden` nie ma
   tego problemu, a przy okazji dostaje sterowanie wczytywaniem. */

/* NAZWA JEST CZĘŚCIĄ DZIAŁANIA. Komponent nazywał się `.gb-hero` i zderzał się
   z karuzelą strony głównej o tej samej nazwie: ta jest siatką dwukolumnową
   z `min-height:520px`, ramką i zaokrągleniem. Obie definicje mają identyczną
   specyficzność, więc karuzela narzucała nagłówkom podstron swoją wysokość,
   a treść wpadała do jej lewej kolumny szerokiej na 380 px. Powyżej 1024 px
   był rozjechany KAŻDY nagłówek redesignu; niżej naprawiała to przypadkiem
   reguła mobilna karuzeli. Nazwa `gb-phead` (page head) rozdziela te dwa byty
   i nie wolno jej scalić z powrotem. */

.gb-phead {
  position: relative;
  overflow: hidden;
  isolation: isolate;

  /* PAS STOI POZA .gb-wrap i to jest warunek, a nie preferencja.
     Pierwsza wersja wypychała się z kontenera ujemnymi marginesami
     (`margin-left: calc(50% - 50vw)`). Wynik zależał wtedy od szerokości
     rodzica: na jednej podstronie wychodziło równo, na drugiej treść
     nagłówka uciekała poza lewą krawędź ekranu. Szablon wstawia nagłówek
     przed kontenerem, a wyśrodkowanie robi .gb-wrap w środku pasa. */
  margin: 0 0 26px;

  /* Treść wyśrodkowana w pionie. Bez tego nagłówek działu bez zdania wstępu
     był o kilkadziesiąt pikseli niższy niż nagłówek z pełnym opisem
     i przejście między działami skakało.

     `min-height` obowiązuje TYLKO na wąskich ekranach. Poniżej 861 px kolumna
     boczna schodzi pod treść (reguła niżej), więc pas MUSI móc urosnąć -
     sztywna wysokość ucięłaby tam wszystko, co pod nią wpadnie. Stała
     wysokość jest w osobnej regule dla szerokich ekranów. */
  display: flex;
  align-items: center;
  min-height: 250px;

  border-bottom: 1px solid var(--gb-line);
  background: var(--gb-bg);
}

.gb-phead-art,
.gb-phead > .gb-net-art {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center right;
  z-index: -2;
}
/* Wgrane zdjęcie przygaszamy mocniej niż rysowany wzór: ma większy kontrast
   i tekst na nim przestaje być czytelny. */
.gb-phead-art { opacity: .46; }
.gb-phead > .gb-net-art { opacity: .6; }

/* Gradient poziomy, nie równomierne przyciemnienie: tekst siedzi po lewej
   i tam ma być prawie kryjący, a po prawej obrazek zostaje widoczny. Przy
   równomiernym przyciemnieniu kadr znikał, a po co go było wgrywać. */
.gb-phead.has-art::before {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(96deg,
    var(--gb-bg) 0%,
    rgba(14, 16, 21, .94) 38%,
    rgba(14, 16, 21, .7) 70%,
    rgba(14, 16, 21, .42) 100%);
}

/* Kreska w kolorze strony u dołu pasa. To ona odcina nagłówek od treści
   i wiąże go z resztą podstrony; sama ramka tego nie robiła. */
.gb-phead::after {
  content: "";
  position: absolute; inset: auto 0 0 0; height: 3px;
  background: var(--srv, var(--gb-accent));
  opacity: .9;
}

/* Kontener jest elementem siatki flex rodzica, więc bez width:100% skurczyłby
   się do treści i przestał trzymać środek strony. Odstępy pionowe równe
   z góry i z dołu, bo pas jest wyśrodkowany. */
/* Wyłącznie padding pionowy. Skrócony `padding: 28px 0 30px` zerował boczne
   24 px, które .gb-wrap daje wszystkim kontenerom serwisu, i tekst nagłówka
   przywierał do krawędzi ekranu zamiast trzymać wspólną siatkę. */
/* PAS MA DOKŁADNIE 250 PX I TO JEST WARUNEK, NIE PREFERENCJA (GB-115).

   Wcześniej stało tu samo `min-height`, więc pas rósł, gdy zdanie wstępne
   zawinęło się o wiersz dłużej: /premium/ i /sklep/ miały 270 px, a reszta
   serwisu 250. Nagłówki są zrównane co do piksela (GB-100) i na tym stoi
   efekt tła z GB-113, który przy zmiennej wysokości nie ma się do czego
   odnieść.

   Zaciśnięcie wysokości działa tylko razem z ograniczeniem liczby wierszy
   niżej. Sama stała wysokość plus `overflow: hidden` obcinałaby tekst
   w połowie litery zamiast go skrócić. */
@media (min-width: 861px) {
  .gb-phead { height: 250px; }
}

/* Odstępy zmniejszone z 28/30, żeby dwuwierszowe zdanie wstępne mieściło się
   w 250 px. Przy treści wyśrodkowanej w pionie symetryczny odstęp i tak nie
   jest widoczny - kupuje wyłącznie zapas wysokości. */
.gb-phead-in { width: 100%; padding-top: 18px; padding-bottom: 18px; }
.gb-phead.has-aside .gb-phead-in {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 290px;
  gap: 24px;
  align-items: center;
}

.gb-phead-main { min-width: 0; }
.gb-phead .gb-crumbs { margin-bottom: 12px; }

.gb-phead-top { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }

.gb-phead-cap {
  font-size: 11.5px; font-weight: 700; letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--srv, var(--gb-accent));
}

/* Tytuł i zdanie wstępne mają GÓRNY LIMIT WIERSZY, bo to jedyne dwa miejsca
   w pasie, które rosną od treści. Reszta (okruszki, nadtytuł, plakietki) ma
   wysokość stałą. Bez tych limitów stała wysokość pasa jest obietnicą bez
   pokrycia: wystarczy dłuższy opis kategorii wpisany w wp-adminie.

   Dwa wiersze, nie jeden: najdłuższa nazwa turnieju w bazie ma 45 znaków
   i przy 42 px zawija się na dwa, a ucięcie jej w połowie byłoby gorsze
   niż wyższy pas. Strona turnieju nie podaje zdania wstępnego, więc
   dwuwierszowy tytuł i dwuwierszowe zdanie nigdy nie spotykają się razem. */
.gb-phead-title {
  margin: 0 0 10px;
  font-size: clamp(26px, 4.2vw, 42px);
  line-height: 1.06; letter-spacing: -.02em;
  color: var(--gb-text);

  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

.gb-phead-lead {
  margin: 0 0 15px; max-width: 62ch;
  font-size: 15.5px; line-height: 1.55;
  color: var(--gb-text2);

  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

/* Fakty jako pary klucz-wartość w pigułkach. Kafel na każdy z nich zajmował
   sześć razy więcej miejsca, żeby powiedzieć to samo. */
.gb-phead-facts { display: flex; flex-wrap: wrap; gap: 8px 10px; }

.gb-phead-fact {
  display: inline-flex; align-items: baseline; gap: 7px;
  padding: 6px 12px;
  border: 1px solid var(--gb-line);
  border-radius: 999px;
  background: rgba(0, 0, 0, .3);
  text-decoration: none;
}
.gb-phead-fact .k {
  font-size: 10.5px; font-weight: 700; letter-spacing: .09em;
  text-transform: uppercase; color: var(--gb-muted);
}
.gb-phead-fact b { font-size: 13.5px; font-weight: 600; color: var(--gb-text); }
a.gb-phead-fact:hover { border-color: var(--srv, var(--gb-accent)); }

/* Kolumna boczna: to, co da się kliknąć. Tło półprzezroczyste, żeby obrazek
   pod spodem był dalej widoczny, ale panel czytelny. */
.gb-phead-side > * { margin: 0; }
.gb-phead-side .gb-thead-card,
.gb-phead-side .gb-card {
  background: rgba(14, 16, 21, .82);
  border: 1px solid var(--gb-line);
  border-radius: 10px;
  backdrop-filter: blur(3px);
}

@media (max-width: 860px) {
  .gb-phead.has-aside .gb-phead-in { grid-template-columns: 1fr; gap: 18px; }
}

/* ==================== PAS NAGŁÓWKA: SIATKA, FADE KADRÓW, POŚWIATA (GB-113)

   Wersja po odrzuceniu wycierania maską: przejście przez KRYCIE, bo ruch
   krawędzi czytał się jak przewijanie slajdów, a nie jak spokojna zmiana tła.

   Trzy warstwy, każda z jasną rolą:
     -3  poświata  mocno rozmyty kadr, źródło koloru dla całego pasa
     -2  kadr      zdjęcie, przenikane długim fade
     -1  siatka    stała, neutralna kratownica na wierzchu obrazu

   Siatka leży NAD kadrem, nie pod nim: pod spodem gubiła się na ciemnych
   zdjęciach i pas wyglądał raz z kratą, raz bez. */

.gb-phead { --gb-takt: 6s; }

.gb-phead-glow,
.gb-phead-slides,
.gb-phead-slide,
.gb-phead-grid {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.gb-phead-glow   { z-index: -3; overflow: hidden; }
.gb-phead-slides { z-index: -2; overflow: hidden; }

/* KADR. Długie przenikanie: obraz wchodzi i schodzi przez jedną trzecią swojego
   czasu, więc w każdej chwili widać mieszankę dwóch zdjęć, a nie przeskok.
   Powolne najeżdżanie sprawia, że kadr nigdy nie stoi martwo. */
.gb-phead-slide {
  background-size: cover;
  background-position: center top;
  opacity: 0;
  will-change: opacity, transform;
  animation: gb-phead-fade calc(var(--n) * var(--gb-takt)) ease-in-out infinite;
  animation-delay: calc(var(--i) * var(--gb-takt));
}

@keyframes gb-phead-fade {
  0%   { opacity: 0; transform: scale(1.12); }
  9%   { opacity: .85; }
  20%  { opacity: .85; }
  30%  { opacity: 0; transform: scale(1.03); }
  100% { opacity: 0; transform: scale(1.03); }
}

/* POŚWIATA: rozmyta kopia tego samego kadru. Daje pasowi barwę zdjęcia,
   dzięki czemu tło zmienia kolor razem z tematem wpisu. Wzorzec rozmycia
   z nagłówka strony gry (redesign-library.css). Wchodzi wcześniej i schodzi
   później niż ostry kadr, więc kolor pod spodem jest ciągły. */
.gb-phead-slide.is-glow {
  filter: blur(40px) brightness(.5) saturate(1.3);
  transform: scale(1.2);
  animation-name: gb-phead-glow;
}

@keyframes gb-phead-glow {
  0%   { opacity: 0; }
  6%   { opacity: 1; }
  24%  { opacity: 1; }
  34%  { opacity: 0; }
  100% { opacity: 0; }
}

/* SIATKA. Neutralna i stała - kolor działu niosą kafle i kreska pod pasem,
   nie krata. Barwa linii z var() dawała czerwoną klatkę w recenzjach i ledwo
   widoczną w aktualnościach, bo oko czyta te barwy z inną jasnością. */
.gb-phead-grid {
  z-index: -1;
  background-image:
    repeating-linear-gradient(0deg, rgba(255, 255, 255, .5) 0 1px, transparent 1px 52px),
    repeating-linear-gradient(90deg, rgba(255, 255, 255, .5) 0 1px, transparent 1px 52px);
  opacity: .07;

  /* Warstwa wystaje poza pas, bo obrócony prostokąt 1850 x 250 potrzebuje
     w pionie ponad 500 px. Ujemny inset zamiast skali: skala rozciągałaby
     też rozstaw linii. */
  inset: -70% -8%;
  transform: rotate(-8deg);
  transform-origin: center;
}

/* Gradient czytelności: mocny tam, gdzie leży tekst, ustępujący po prawej,
   żeby zdjęcie było widać. */
.gb-phead.has-slides::before {
  background: linear-gradient(96deg,
    var(--gb-bg) 0%,
    rgba(14, 16, 21, .93) 34%,
    rgba(14, 16, 21, .66) 68%,
    rgba(14, 16, 21, .4) 100%);
}

@media (prefers-reduced-motion: reduce) {
  .gb-phead-slide { animation: none; opacity: 0; transform: scale(1.03); }
  .gb-phead-slides .gb-phead-slide:first-child { opacity: .85; }
  .gb-phead-glow .gb-phead-slide:first-child { opacity: 1; }
}
