/* ============================================================================
   Norbsoft — wspólne style podstron bloga (/blog/*)
   ----------------------------------------------------------------------------
   Ten plik NIE pochodzi z Webflow i re-eksport go nie nadpisuje: eksport zapisuje
   wyłącznie własne pliki (css/, js/, fonts/, images/ i podstrony generowane
   w Webflow), a katalog blog/ jest w całości nasz.

   Podpinany w <head> każdej podstrony bloga, ZA arkuszami Webflow:
     <link href="/blog/blog.css?v=RRRR-MM-DD" rel="stylesheet" type="text/css">

   Ścieżka MUSI być root-absolutna — indeks jest serwowany pod /blog BEZ ukośnika
   (.htaccess: RewriteRule ^blog/?$ blog/index.html + DirectorySlash Off), więc
   ścieżka względna rozwiązałaby się do roota.

   Po każdej zmianie tego pliku podbij ?v= we wszystkich podstronach bloga
   (.htaccess nie ma ExpiresByType text/css, więc działa ExpiresDefault 7 dni)
   i przeczyść cache Cloudflare.

   Czego tu NIE MA: grafiki hero i jej proporcji — są per-artykuł i zostają
   w krótkim bloku <style> w <head> konkretnego wpisu.
   ============================================================================ */


/* --- Galerie zrzutów ekranów w treści --------------------------------------- */

.blog-screens { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; align-items: start; margin: 2rem 0 0.6rem; }
.blog-screens.cols-2 { grid-template-columns: repeat(2, 1fr); gap: 1.25rem; max-width: 92%; margin-left: auto; margin-right: auto; }
.blog-screens.solo { display: block; max-width: 320px; margin-left: auto; margin-right: auto; }  /* pojedynczy zrzut, wyśrodkowany */
.blog-screens.solo.wide { max-width: 100%; }  /* pojedynczy zrzut poziomy albo kompozycja kilku ekranów */
.blog-screens img, .rich-text .blog-screens img { width: 100%; height: auto; margin: 0; display: block; border-radius: 14px; box-shadow: 0 0.5rem 1.5rem rgba(0,0,0,0.10); }
.blog-screens-cap, .rich-text .blog-screens-cap { display: block; text-align: center; font-size: 0.8em; line-height: 1.4; opacity: 0.65; margin: 0 0 2.25rem; }


/* --- Byline (Redakcja / Recenzja / Aktualizacja) + blok „Artykuł w skrócie" -- */

.blog-meta { font-size: 0.85em; opacity: 0.6; margin: 0 0 1.25rem; }
.blog-meta a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
.blog-tldr { border-left: 4px solid #ff6700; background: rgba(255,103,0,0.06); border-radius: 12px; padding: 1.1rem 1.4rem; margin: 0 0 1.9rem; }
.blog-tldr .blog-tldr-label { display: block; font-weight: 700; letter-spacing: 0.04em; margin: 0 0 0.4rem; }
.rich-text .blog-tldr p, .blog-tldr p { margin: 0; }


/* --- Tabele w treści artykułu -----------------------------------------------
   Konwersja markdown → HTML daje goły <table> bez klas, więc celujemy w elementy.
   border-collapse: separate (zamiast collapse z normalize.css) jest konieczne,
   żeby zadziałało zaokrąglenie rogów; bez wrappera overflow: hidden na <table>
   nie przycina, dlatego promień siedzi na rogowych komórkach.
   Język wizualny wzięty z komponentu .table_component (/archiwum-projektow):
   granatowy nagłówek i radius 1rem — ale separator wierszy jest widoczny
   (--neutral-200 zamiast --white, które ginie na jasnym tle) i doszła zebra.
   --------------------------------------------------------------------------- */

.rich-text table { width: 100%; margin: 1.6rem 0; font-size: 0.92em; line-height: 1.5; border-collapse: separate; border-spacing: 0; }
.rich-text th, .rich-text td { padding: 0.75rem 1rem; text-align: left; vertical-align: top; overflow-wrap: break-word; }
.rich-text thead th { background: var(--neutral-900, #0b0f26); color: var(--white, #fff); font-weight: 600; }
.rich-text tbody td { border-bottom: 1px solid var(--neutral-200, #dbddee); }
.rich-text tbody td:first-child { border-left: 1px solid var(--neutral-200, #dbddee); }
.rich-text tbody td:last-child { border-right: 1px solid var(--neutral-200, #dbddee); }
/* zebra na komórkach, NIE na <tr> — tło wiersza jest kwadratowe i wystawałoby poza zaokrąglony róg */
.rich-text tbody tr:nth-child(2n) td { background: var(--neutral-50, #f7f8ff); }
.rich-text thead tr:first-child th:first-child { border-top-left-radius: 1rem; }
.rich-text thead tr:first-child th:last-child { border-top-right-radius: 1rem; }
.rich-text tbody tr:last-child td:first-child { border-bottom-left-radius: 1rem; }
.rich-text tbody tr:last-child td:last-child { border-bottom-right-radius: 1rem; }
/* Tabele 5-kolumnowe z rozbudowaną treścią: przy padding 1rem sam poziomy padding zjada ~180 px
   (5 kolumn × 2 strony), więc minimalna szerokość tabeli wychodziła 756 px przy kolumnie 662 px
   i tabela wystawała w prawy margines. Ciaśniejszy padding + 0.86em mieszczą całość w kolumnie
   BEZ przewijania w poziomie (zmierzone na wpisie „brief na aplikację mobilną”: 756 → 662 px).
   Tabele 2–4-kolumnowe zostają nietknięte. Bez obsługi :has() = stan sprzed reguły, czyli
   tabela szersza od kolumny — degradacja łagodna, strona się nie rozpycha (patrz też @media 767). */
.rich-text table:has(thead th:nth-child(5)) { font-size: 0.86em; }
.rich-text table:has(thead th:nth-child(5)) th,
.rich-text table:has(thead th:nth-child(5)) td { padding-left: 0.55rem; padding-right: 0.55rem; hyphens: auto; }


/* --- Bloki do skopiowania: szkielet szablonu, prompt ------------------------
   Konwersja markdown daje goły <pre><code> bez klas (jak przy tabelach), więc
   celujemy w elementy. Bloki są DO SKOPIOWANIA przez czytelnika, nie do czytania
   po przekątnej: układ zachowany dosłownie (white-space: pre), a nadmiar treści
   przewija się w poziomie WEWNĄTRZ ramki — bez tego najdłuższe linie promptu
   (~75 znaków) rozpychałyby kolumnę tekstu na telefonie.
   font-size 0.72em to wartość ZMIERZONA, nie estetyczna: przy kolumnie 45rem najdłuższa
   linia bloku (88 znaków) mieści się wtedy bez przewijania w poziomie na każdej szerokości
   desktopu (font skaluje się w em razem z rem-owym `html { font-size: calc(... + vw) }`).
   Przy 0.75em blok szablonu wystawał o ~11 px. Na telefonie przewijanie zostaje — i tak ma.
   Bazowy <pre> z normalize.css ma tylko overflow: auto i monospace — reszta jest tu.
   --------------------------------------------------------------------------- */

.rich-text pre { margin: 1.6rem 0; padding: 1.1rem 1.25rem; background: var(--neutral-50, #f7f8ff); border: 1px solid var(--neutral-200, #dbddee); border-radius: 1rem; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.rich-text pre code { display: block; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; font-size: 0.72em; line-height: 1.55; white-space: pre; color: var(--neutral-800, #0f1433); }


/* --- Hero wpisu — część wspólna ---------------------------------------------
   aspect-ratio i background-image (grafika konkretnego wpisu) ustawia blok
   <style> w <head> podstrony — tam jest też ich wariant mobilny.
   --------------------------------------------------------------------------- */

.blog-hero { position: relative; display: flex; align-items: center; width: 100%; min-height: 400px; padding-top: 6rem; padding-bottom: 3rem; background-size: cover; background-position: center; background-origin: border-box; background-repeat: no-repeat; }
.blog-hero-inner { max-width: 56%; }
/* line-height MUSI zostawiać zapas na dolne wydłużenia (g, y, ę) — inaczej tło markera z kolejnej
   linii przycina je, gdy wyróżniona fraza zawija się na 2+ linie (patrz .hl-mark padding niżej) */
.blog-hero h1 { line-height: 1.4; }
.blog-hero .hl-mark { background-color: #ff6700; color: #fff; padding: 0.03em 0.24em; border-radius: 8px; -webkit-box-decoration-break: clone; box-decoration-break: clone; }
/* Offset kotwic pod przyklejoną nawigacją (77 px + zapas). Obowiązuje przy wejściu z adresem
   …/blog/<slug>#slug ORAZ przy kliknięciu w spisie treści, bo blog.js przewija przez
   scrollIntoView() — to jedno miejsce, w którym ten offset jest zdefiniowany. Programowy
   window.scroll() (tak przewija moduł „scroll" Webflow) scroll-margin-top IGNORUJE. */
#artykul, #zrodla, .blog-sec { scroll-margin-top: 7rem; }
/* blog.js ustawia sekcji tabindex="-1" i daje jej fokus (klawiatura kontynuuje od sekcji,
   nie od spisu) — obramowanie na kontenerze byłoby wtedy mylącym artefaktem; Webflow
   robi to samo regułą .wf-force-outline-none[tabindex="-1"]:focus */
#artykul:focus, #zrodla:focus, .blog-sec:focus { outline: none; }


/* --- Indeks /blog — siatka kart wpisów -------------------------------------- */

.blog-list { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.5rem; align-items: stretch; }
.blog-card { display: flex; flex-direction: column; background: #fff; border-radius: 14px; overflow: hidden; box-shadow: 0 0.4rem 1.2rem rgba(0,0,0,0.08); transition: transform 0.2s ease, box-shadow 0.2s ease; height: 100%; }
.blog-card:hover { transform: translateY(-4px); box-shadow: 0 0.9rem 2rem rgba(0,0,0,0.14); }
.blog-card-cover { width: 100%; height: auto; display: block; }
.blog-card-body { display: flex; flex-direction: column; gap: 0.45rem; padding: 1.1rem 1.2rem 1.3rem; flex: 1 1 auto; }
.blog-card-tag { font-size: 0.7em; letter-spacing: 0.07em; text-transform: uppercase; font-weight: 700; color: #ff6700; }
.blog-card h3 { margin: 0; line-height: 1.3; color: #0b0f26; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.blog-card-desc { opacity: 0.7; margin: 0; color: #0b0f26; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.blog-card-link { margin-top: auto; padding-top: 0.5rem; display: inline-flex; align-items: center; gap: 0.4rem; font-weight: 600; color: #ff6700; }


/* --- Sekcja „Źródła" na końcu wpisu -----------------------------------------
   Aparat źródeł ma być w pełni czytelny, ale nie konkurować z treścią. H2 zostaje
   w kodzie (semantyka i SEO bez zmian) — zmienia się wyłącznie jego waga wizualna:
   z nagłówka sekcji (2rem) na etykietę wersalikami.
   Wyciszenie kolorem, nie opacity jak w .blog-meta: --neutral-600 na białym daje
   7,5:1, czyli WCAG AAA nawet przy 0.85em (najdłuższa lista w blogu ma 34 pozycje).
   Bazowy h2 z components.css ma line-height 36px i margin-top 20px W PIKSELACH —
   oba trzeba nadpisać, inaczej etykieta odziedziczy interlinię nagłówka 32px.
   --------------------------------------------------------------------------- */

.blog-sources { margin-top: 2.75rem; padding-top: 1.25rem; border-top: 1px solid var(--neutral-200, #dbddee); }
.rich-text .blog-sources h2 { margin: 0 0 0.7rem; font-size: 0.8rem; line-height: 1.4; letter-spacing: 0.08em; text-transform: uppercase; color: var(--neutral-600, #4c527a); }
.rich-text .blog-sources ul { margin-bottom: 0; font-size: 0.85em; line-height: 1.55; color: var(--neutral-600, #4c527a); }
.rich-text .blog-sources li { margin-bottom: 0.4rem; }
.rich-text .blog-sources li:last-child { margin-bottom: 0; }
.rich-text .blog-sources a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }


/* --- Spis treści wpisu ------------------------------------------------------
   Jedyny komponent bloga pisany MOBILE-FIRST (stąd @media min-width niżej, wbrew
   reszcie pliku). Powód: stan bazowy to spis w normalnym przepływie nad tekstem,
   a klasa container-small na <nav> daje mu wtedy dokładnie to samo wyrównanie co
   kolumnie tekstu na KAŻDYM breakpoincie Webflow (4rem → 2.5rem @991 → 1.5rem @767).
   Odtwarzanie tych paddingów w blokach max-width byłoby duplikatem norbsoft.css.

   Od 1200 px lewy margines (min. (1200−720)/2 = 240 px) jest dość szeroki, żeby
   powiesić w nim sticky sidebar — kolumna tekstu zostaje wtedy nietknięta, dokładnie
   tam, gdzie była przed dodaniem spisu.

   Pigułki listy to klasy Webflow (.side-menu-links / .side-menu-link / .f-14) z /uslugi
   — razem z gotowym stanem aktywnym .side-menu-link.w--current (biała pigułka,
   pomarańczowa kropka), który Webflow nadaje SAM: moduł „links" w js/norbsoft.js
   podświetla link, gdy pionowy środek ekranu wypada w sekcji o tym id. Dlatego kotwice
   siedzą na <section class="blog-sec" id="…"> obejmującej cały blok H2, a nie na samym
   nagłówku: goły <h2 id> ma ~40 px wysokości, więc podświetlenie zapalałoby się
   na 40 px przewinięcia i gasło.

   Samo PRZEWIJANIE po kliknięciu obsługuje już blog.js, nie Webflow: moduł „scroll"
   szuka przyklejonej nawigacji selektorem, w który nasze <nav class="nav"> nie trafia,
   więc odejmował zero i cel lądował pod paskiem. Szczegóły w nagłówku blog.js.
   --------------------------------------------------------------------------- */

.blog-toc-box { margin-bottom: 1.5rem; }
.blog-toc .side-menu-links { margin-bottom: 0; }
.blog-toc-label { display: flex; align-items: center; gap: 0.4rem; cursor: pointer; list-style: none; margin: 0 0 0.2rem; padding: 0.8rem 0; font-size: 0.8rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--neutral-600, #4c527a); }
.blog-toc-label::-webkit-details-marker { display: none; }
/* strzałka rozwijania — na desktopie ukryta, bo spis jest tam zawsze otwarty */
.blog-toc-label::after { content: ""; width: 0.45rem; height: 0.45rem; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg); transition: transform 0.2s ease; }
.blog-toc-box[open] .blog-toc-label::after { transform: rotate(-135deg); }

@media screen and (min-width: 1200px) {
  .blog-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 45rem) minmax(0, 1fr); }
  /* :not(.blog-toc) jest KONIECZNE — <nav> spisu nosi obie klasy, a bez wyłączenia
     ta reguła (wyższa specyficzność niż .blog-toc) wrzuciłaby spis do kolumny tekstu */
  .blog-layout > .container-small:not(.blog-toc) { grid-column: 2; }
  /* align-self: start jest konieczne — grid item rozciągnięty na wysokość wiersza
     nie ma miejsca, w którym mógłby się przyklejać */
  .blog-layout > .blog-toc { grid-column: 1; grid-row: 1; justify-self: end; align-self: start; position: sticky; top: 4.5rem; width: min(18.5rem, calc(100% - 1.5rem)); max-width: none; margin: 0; padding: 0; max-height: calc(100vh - 6rem); overflow-y: auto; }
  /* na desktopie belka nie jest przełącznikiem, więc obszar dotyku jest zbędny */
  .blog-toc-label { cursor: default; margin: 0 0 0.6rem; padding: 0; }
  .blog-toc-label::after { display: none; }
}


/* --- Punkty załamania ------------------------------------------------------- */

@media screen and (max-width: 991px) {
  .blog-hero-inner { max-width: 78%; }
  .blog-list { grid-template-columns: repeat(2, 1fr); }
}

@media screen and (max-width: 767px) {
  .blog-hero { align-items: flex-start; min-height: clamp(380px, 86vw, 560px); padding-top: 6rem; padding-bottom: 2.5rem; background-position: center top; }
  .blog-hero-inner { max-width: 100%; }
  .blog-screens { grid-template-columns: repeat(2, 1fr); gap: 0.6rem; }
  .blog-screens.cols-2 { grid-template-columns: 1fr; max-width: 100%; }
  /* szerokie tabele przewijają się w poziomie zamiast rozpychać stronę */
  .rich-text table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  /* ciaśniejsze komórki odzyskują ~30 px szerokości — tyle wystarczy, by tabela 3-kolumnowa
     zmieściła się na 375 px bez przewijania (przy 1rem paddingu wystawała o ~26 px).
     hyphens: auto (strona ma lang="pl") dzieli długie wyrazy na sylabach tam, gdzie przeglądarka
     ma słownik. NIE używaj tu overflow-wrap: anywhere — owszem, dociska każdą tabelę do szerokości
     ekranu, ale łamie wyrazy w przypadkowym miejscu („Postrz|egaln|ość") i pozwala kolumnie
     z krótkimi etykietami zapaść się do kilku liter. Lepiej, żeby najciaśniejsze tabele
     3-kolumnowe przewinęły się o kilkadziesiąt pikseli z wyrazami w całości. */
  .rich-text th, .rich-text td { padding: 0.65rem 0.7rem; hyphens: auto; }
  /* min-width kolumny trzyma czytelną szerokość zamiast zgniatać tekst do jednego słowa w linii,
     ale TYLKO od 4 kolumn wzwyż: tabele 2- i 3-kolumnowe (13 z 14 w blogu) mieszczą się na telefonie
     i mają zawijać tekst, a nie przewijać się w bok. Bez obsługi :has() = brak min-width, czyli
     tabela się zgniata — degradacja łagodna, nic się nie psuje. */
  .rich-text table:has(thead th:nth-child(4)) th,
  .rich-text table:has(thead th:nth-child(4)) td { min-width: 8.5rem; }
}

@media screen and (max-width: 479px) {
  .blog-list { grid-template-columns: 1fr; }
}
