/* ===========
   Kolory – motyw jasny i ciemny
   ===========

   Wszystkie barwy przechodzą przez zmienne, bo strona ma teraz dwa warianty.
   Przełącznikiem jest atrybut `data-bs-theme` na <html> – ten sam, którego
   używa Bootstrap 5.3, więc jedno ustawienie przestawia i komponenty
   Bootstrapa (`text-muted`, `bg-dark`, `card`, `alert`), i style własne.
   Wartość ustawia static/theme-init.js jeszcze przed pierwszym malowaniem,
   żeby nie było mignięcia jasnym tłem.
   =========== */
:root,
:root[data-bs-theme="light"] {
  --brand: #0d3b66;
  --brand-700: #0a274a;
  --brand-600: #11406f;
  --brand-soft: #e7f1ff;
  --gold: #e0b144;
  --gold-soft: #fde68a;

  /* Powierzchnie */
  --surface: #ffffff;
  --surface-soft: rgba(255,255,255,.92);
  --surface-raised: rgba(255,255,255,.96);
  --surface-sunken: #f8fafc;
  --surface-inset: #f1f5f9;

  /* Tło strony – ciepła kość słoniowa zamiast dawnego błękitu.
     Zimny gradient bił się ze złotem marki i cała strona wyglądała
     chłodno; teraz podstawa jest ciepła, a rysunek daje jej wachlarz
     promieni (patrz sekcja „Tło – promienie”). */
  --page-1: #fdfbf6;
  --page-2: #f6f2ea;
  --page-3: #edeff6;
  --page-glow-1: rgba(224,177,68,.20);
  --page-glow-2: rgba(255,203,140,.18);
  --spot-1: rgba(224,177,68,.22);
  --spot-2: rgba(255,183,140,.16);
  --spot-3: rgba(129,171,226,.14);

  /* Dwa strumienie z obrazu „Jezu ufam Tobie”: blady (woda) i czerwony (krew).
     `-dim` to poświata między włóknami, bez `-dim` – rozjaśniony rdzeń włókna.
     Alfa jest niska, bo to tło pod treścią, a nie ilustracja. */
  --beam-mercy: rgba(255,255,255,.95);
  --beam-mercy-dim: rgba(184,214,246,.28);
  --beam-blood: rgba(222,80,80,.30);
  --beam-blood-dim: rgba(224,126,126,.11);
  --ray-core: rgba(255,249,236,.9);
  --ray-opacity: .85;

  --section-glow: rgba(255,252,244,.6);
  --section-glow-strong: rgba(255,250,236,.85);

  --border-subtle: rgba(15,23,42,.08);
  --border-strong: rgba(15,23,42,.18);

  --text-main: #0f172a;
  --text-muted: #6b7280;
  --text-on-brand: #f9fafb;
  --text-reading: #1a202c;

  --card-tint: rgba(224,177,68,.26);
  --chip-border: rgba(13,59,102,.18);
  --chip-border-hover: rgba(13,59,102,.32);
  --brand-chip-text: #0a274a;
  --date-box-1: #eef2ff;
  --date-box-2: #e0f2fe;
  --date-box-text: #0f172a;
  --date-box-muted: #475569;
  --carousel-icon-filter: invert(15%) sepia(95%) saturate(693%) hue-rotate(180deg) brightness(92%) contrast(90%);

  --shadow-sm: 0 10px 30px rgba(15,23,42,.06);
  --shadow-md: 0 16px 40px rgba(15,23,42,.09);
  --shadow-lg: 0 22px 55px rgba(15,23,42,.14);

  --focus-ring: 0 0 0 .2rem rgba(224,177,68,.55);
}

/* Motyw ciemny.
   Zasada: kolor marki jaśnieje (granat na czarnym tle jest nieczytelny),
   złoto zostaje – to znak rozpoznawczy strony. Cienie zamiast czernieć
   robią się głębsze, bo na ciemnym tle sam cień nie buduje już planów;
   robi to jaśniejsza powierzchnia karty. */
:root[data-bs-theme="dark"] {
  --brand: #7cb0e8;
  --brand-700: #0b1f38;
  --brand-600: #17406b;
  --brand-soft: #16283f;
  --gold: #e0b144;
  --gold-soft: #6b5220;

  --surface: #131b26;
  --surface-soft: rgba(19,27,38,.92);
  --surface-raised: rgba(24,33,46,.96);
  --surface-sunken: #0f151e;
  --surface-inset: #1b2533;

  --page-1: #0a0e15;
  --page-2: #0e131c;
  --page-3: #141a25;
  --page-glow-1: rgba(224,177,68,.16);
  --page-glow-2: rgba(198,132,64,.14);
  --spot-1: rgba(224,177,68,.14);
  --spot-2: rgba(198,124,92,.10);
  --spot-3: rgba(59,130,246,.12);

  /* Na ciemnym tle strumienie muszą być dużo słabsze niż w motywie jasnym.
     Nie chodzi o samo tło, tylko o karty: mają 92% krycia, więc każdy
     procent jasności zza nich podnosi je z czerni w wyraźną szarość. */
  --beam-mercy: rgba(228,242,255,.30);
  --beam-mercy-dim: rgba(140,186,236,.10);
  --beam-blood: rgba(226,92,92,.26);
  --beam-blood-dim: rgba(196,86,86,.07);
  --ray-core: rgba(255,244,214,.30);
  --ray-opacity: .78;

  --section-glow: rgba(224,177,68,.07);
  --section-glow-strong: rgba(224,177,68,.12);

  --border-subtle: rgba(148,163,184,.16);
  --border-strong: rgba(148,163,184,.3);

  --text-main: #e6edf6;
  --text-muted: #9fb0c4;
  --text-on-brand: #f9fafb;
  --text-reading: #dfe7f1;

  --card-tint: rgba(224,177,68,.16);
  --chip-border: rgba(148,163,184,.28);
  --chip-border-hover: rgba(224,177,68,.5);
  --brand-chip-text: #cfe2f8;
  --date-box-1: #1b2b3f;
  --date-box-2: #17303f;
  --date-box-text: #e6edf6;
  --date-box-muted: #9fb0c4;
  /* Strzałki karuzeli to białe ikony Bootstrapa – na ciemnym przycisku mają
     zostać jasne, więc nie przyciemniamy ich filtrem. */
  --carousel-icon-filter: none;

  --shadow-sm: 0 10px 30px rgba(0,0,0,.45);
  --shadow-md: 0 16px 40px rgba(0,0,0,.5);
  --shadow-lg: 0 22px 55px rgba(0,0,0,.6);

  --focus-ring: 0 0 0 .2rem rgba(224,177,68,.6);
}

/* ===========
   Dostępność – widoczny fokus i przejście do treści
   =========== */

/* Link „przeskocz do treści” – widoczny dopiero po tabulacji. */
.skip-link {
  position: absolute;
  left: .5rem;
  top: -3rem;
  z-index: 1080;
  padding: .55rem 1rem;
  border-radius: 0 0 .6rem .6rem;
  background: var(--brand-700);
  color: #fff;
  font-weight: 600;
  text-decoration: none;
  transition: top .16s ease;
}

.skip-link:focus {
  top: 0;
  color: #fff;
}

/* Wspólny, wyraźny pierścień fokusu dla nawigacji klawiaturą.
   Wcześniej `.chip:focus { outline: 0 }` po prostu kasowało obrys. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
.chip:focus-visible,
.btn:focus-visible {
  outline: 2px solid transparent;
  outline-offset: 2px;
  box-shadow: var(--focus-ring);
}

/* Kotwica <main id="tresc" tabindex="-1"> nie powinna rysować obrysu po kliknięciu. */
.site-main:focus {
  outline: none;
}

/* ===========
   Tło strony – promienie w duchu obrazu „Jezu ufam Tobie”
   ===========

   Rysunek jest z obrazu: z jednego punktu tuż nad środkiem górnej krawędzi
   okna biją dwa snopy światła – blady w dół i w prawo, czerwony w dół
   i w lewo – a w środku każdego z nich płyną i migoczą włókna światła.

   Warstwy, od najgłębszej (kolejność wymusza ujemny z-index):
     1. tło <body>   – ciepły gradient, trafia na kanwę okna,
     2. body::after  – pływające plamy ciepłego światła,
     3. .bg-rays     – dwa strumienie: blady (woda) i czerwony (krew),
     4. body::before – oddychające halo w źródle obu strumieni.

   Wszystkie warstwy są `fixed`, więc źródło światła zostaje na miejscu
   przy przewijaniu, a nie ucieka razem z treścią.
   =========== */

html, body {
  min-height: 100%;
}

body {
  margin: 0;
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  color: var(--text-main);

  background:
    radial-gradient(circle at 0% 0%, var(--page-glow-1), transparent 60%),
    radial-gradient(circle at 100% 0%, var(--page-glow-2), transparent 65%),
    linear-gradient(180deg, var(--page-1) 0%, var(--page-2) 45%, var(--page-3) 100%);
  background-attachment: fixed;
  background-size: cover;
  position: relative;
}

/* Halo w źródle obu strumieni. Leży najwyżej ze wszystkich warstw tła, więc
   przykrywa miejsce, z którego światło wychodzi – tam włókna i tak zlewają
   się w plamę. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(46vmax 30vmax at 50% -5vmax,
                              var(--ray-core), transparent 72%);
  opacity: .8;
  animation: haloBreath 9s ease-in-out infinite;
  will-change: opacity, transform;
  z-index: -1;
}

/* dodatkowe „plamy” światła, lekko pływające */
body::after {
  content: "";
  position: fixed;
  inset: -15%;
  pointer-events: none;
  background:
    radial-gradient(circle at 20% 20%, var(--spot-1), transparent 60%),
    radial-gradient(circle at 80% 80%, var(--spot-2), transparent 55%),
    radial-gradient(circle at 10% 80%, var(--spot-3), transparent 60%);
  /* Bez `mix-blend-mode`: blend pełnoekranowej, przyklejonej warstwy każe
     kompozytorowi odczytywać tło pod nią przy każdej klatce przewijania.
     Plamy są na tyle rzadkie, że zwykłe krycie wygląda tak samo. */
  opacity: .55;
  animation: floatGlow 26s ease-in-out infinite alternate;
  will-change: transform;
  z-index: -3;
}

/* Kontener obu strumieni – <div class="bg-rays"> z base.html.
   Trzyma tylko wspólne krycie i przycięcie do okna; cały rysunek jest
   w dwóch dzieciach. */
.bg-rays {
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  overflow: hidden;
  contain: layout paint;
  opacity: var(--ray-opacity);
}

/* Pojedynczy strumień. Podział na dwa poziomy jest tu istotny:

     .bg-ray         – KSZTAŁT. Maska stożkowa wycina klin, w którym strumień
                       w ogóle istnieje. Klin stoi (kołysze się ledwie o stopień).
     .bg-ray::before – ŚWIATŁO. Włókna, które płyną wewnątrz tego klina
                       własnym tempem: obracają się, pulsują i migoczą.

   Gdyby kształt i światło siedziały na jednym elemencie, cały strumień
   machałby jak wskazówka. Tak wygląda to, o co chodzi na obrazie: snop
   światła stoi, a w środku coś się w nim mieni.

   Element wystaje 10vh poza okno, żeby kołysanie nie odsłoniło rogów –
   dlatego źródło światła wypada 10vh od jego górnej krawędzi, a nie w 0.
   Ten sam punkt powtarza się w każdym gradiencie i w `transform-origin`. */
.bg-ray {
  position: absolute;
  inset: -10vh;
  transform-origin: 50% 10vh;
  will-change: rotate;
}

.bg-ray::before {
  content: "";
  position: absolute;
  inset: 0;
  transform-origin: 50% 10vh;
  /* Rozmycie zamienia prążki w światło. W vh, żeby na dużym ekranie nie
     zrobiło się nieproporcjonalnie ostre. */
  filter: blur(0.5vh);
  will-change: opacity, rotate, scale;
  /* Wygaszanie z odległością od źródła. Maska jest kołowa i wyśrodkowana
     dokładnie w źródle, więc obrót włókien nic w niej nie zmienia –
     rusza nią tylko pulsowanie, i to jest właśnie ten „oddech” snopu. */
  -webkit-mask-image: radial-gradient(circle 128vh at 50% 10vh,
      transparent 0, transparent 3%, #000 15%,
      rgba(0,0,0,.92) 40%, rgba(0,0,0,.62) 66%,
      rgba(0,0,0,.28) 87%, transparent 100%);
          mask-image: radial-gradient(circle 128vh at 50% 10vh,
      transparent 0, transparent 3%, #000 15%,
      rgba(0,0,0,.92) 40%, rgba(0,0,0,.62) 66%,
      rgba(0,0,0,.28) 87%, transparent 100%);
}

/* Kąty liczone jak w `conic-gradient`: 0° w górę, rosną zgodnie z ruchem
   wskazówek. 180° to prosto w dół, więc klin 106–178° idzie w dół i w prawo,
   a 190–258° w dół i w lewo. Między nimi zostaje ok. 12° przerwy – na obrazie
   w tym miejscu stoi postać, a na stronie akurat tamtędy biegnie kolumna
   treści, więc nic pod nią nie świeci.

   Strona lewa/prawa jest z obrazu, nie z przypadku: blady strumień (woda)
   po prawej, czerwony (krew) po lewej. */

/* Blady strumień – woda. Rdzeń biały, w cieniu między włóknami chłodny błękit;
   stąd bierze się to zimne mienienie, które ma obraz. */
.bg-ray--mercy {
  -webkit-mask-image: conic-gradient(from 0deg at 50% 10vh,
      transparent 106deg, rgba(0,0,0,.3) 118deg, #000 130deg,
      #000 154deg, rgba(0,0,0,.32) 166deg, transparent 178deg);
          mask-image: conic-gradient(from 0deg at 50% 10vh,
      transparent 106deg, rgba(0,0,0,.3) 118deg, #000 130deg,
      #000 154deg, rgba(0,0,0,.32) 166deg, transparent 178deg);
  animation: beamSway 70s ease-in-out infinite;
}

/* Dwa zestawy włókien o niewspółmiernych okresach (5.4° i 8.9°). Same w sobie
   są regularne, ale nałożone dudnią – jedne wpadają w drugie i gasną – więc
   snop nigdzie nie wygląda na tapetę w paski. Obrót przeciąga ten rysunek
   przez nieruchomy klin i to widać jako mienienie. */
.bg-ray--mercy::before {
  background:
    repeating-conic-gradient(from 0deg at 50% 10vh,
      var(--beam-mercy-dim) 0deg,
      var(--beam-mercy)     2.2deg,
      var(--beam-mercy-dim) 4.4deg,
      var(--beam-mercy-dim) 5.4deg),
    repeating-conic-gradient(from 3.5deg at 50% 10vh,
      transparent           0deg,
      var(--beam-mercy)     3.4deg,
      transparent           6.8deg,
      transparent           8.9deg);
  animation: rayDrift   41s ease-in-out infinite,
             rayPulse   13s ease-in-out infinite,
             rayFlicker  8.5s ease-in-out infinite;
}

/* Czerwony strumień – krew. Węższy i słabszy od bladego; na obrazie też jest
   drugoplanowy, a na jasnej stronie czerwień szybko robi się natrętna. */
.bg-ray--blood {
  -webkit-mask-image: conic-gradient(from 0deg at 50% 10vh,
      transparent 190deg, rgba(0,0,0,.32) 202deg, #000 214deg,
      #000 236deg, rgba(0,0,0,.3) 246deg, transparent 258deg);
          mask-image: conic-gradient(from 0deg at 50% 10vh,
      transparent 190deg, rgba(0,0,0,.32) 202deg, #000 214deg,
      #000 236deg, rgba(0,0,0,.3) 246deg, transparent 258deg);
  animation: beamSwayAlt 86s ease-in-out infinite;
}

.bg-ray--blood::before {
  background:
    repeating-conic-gradient(from 1.5deg at 50% 10vh,
      var(--beam-blood-dim) 0deg,
      var(--beam-blood)     2.6deg,
      var(--beam-blood-dim) 5.2deg,
      var(--beam-blood-dim) 6.3deg),
    repeating-conic-gradient(from 5deg at 50% 10vh,
      transparent           0deg,
      var(--beam-blood)     4.1deg,
      transparent           8.2deg,
      transparent          10.7deg);
  animation: rayDriftAlt 53s ease-in-out infinite,
             rayPulseAlt 17s ease-in-out infinite,
             rayFlicker   6.2s ease-in-out -2.4s infinite;
}

/* Kąty klinów są policzone pod ekran szerszy niż wyższy. W układzie pionowym
   snop rozłożony o 40° od pionu wychodzi bokiem okna jakieś 200 px pod
   nagłówkiem – i przez resztę ekranu widać już tylko przerwę między
   strumieniami, czyli nic. Na wąskim ekranie zbliżamy więc oba snopy do pionu
   i niemal je stykamy; wtedy schodzą przez całą wysokość i mieszczą się
   w wąskich marginesach obok kart, bo tylko tam tło jest w ogóle widoczne.

   Warunek jest na proporcje, nie na szerokość: decyduje to, czy okno jest
   wysokie, a nie ile ma pikseli. */
@media (max-aspect-ratio: 4/5) {
  .bg-ray--mercy {
    -webkit-mask-image: conic-gradient(from 0deg at 50% 10vh,
        transparent 146deg, rgba(0,0,0,.3) 156deg, #000 164deg,
        #000 175deg, rgba(0,0,0,.34) 179deg, transparent 182deg);
            mask-image: conic-gradient(from 0deg at 50% 10vh,
        transparent 146deg, rgba(0,0,0,.3) 156deg, #000 164deg,
        #000 175deg, rgba(0,0,0,.34) 179deg, transparent 182deg);
  }

  .bg-ray--blood {
    -webkit-mask-image: conic-gradient(from 0deg at 50% 10vh,
        transparent 178deg, rgba(0,0,0,.34) 181deg, #000 185deg,
        #000 196deg, rgba(0,0,0,.3) 204deg, transparent 214deg);
            mask-image: conic-gradient(from 0deg at 50% 10vh,
        transparent 178deg, rgba(0,0,0,.34) 181deg, #000 185deg,
        #000 196deg, rgba(0,0,0,.3) 204deg, transparent 214deg);
  }
}

/* `background-attachment: fixed` każe przeglądarce przemalować tło przy każdym
   przewinięciu – na telefonach daje to wyraźne szarpanie. Na małych ekranach
   tło przewija się więc razem z treścią, a strumienie zostają, tylko nieruchome.

   UWAGA: ten blok MUSI stać poniżej deklaracji `body`, `body::before`,
   `body::after`, `.bg-rays` i `.bg-ray`. Wcześniej był powyżej, a przy tej samej
   specyficzności wygrywa reguła późniejsza – więc wyłączenie animacji dla
   ::before i ::after nie działało i na telefonie chodziła pełnoekranowa
   animacja tła, czyli dokładnie to, czemu blok miał zapobiec. */
@media (max-width: 991.98px), (hover: none) {
  body {
    background-attachment: scroll;
  }

  body::before {
    animation: none;
    opacity: .5;
  }

  body::after {
    animation: none;
  }

  .bg-rays {
    opacity: calc(var(--ray-opacity) * .9);
  }

  /* Nieruchoma warstwa nie musi czekać w pamięci kompozytora – a to akurat
     te urządzenia, na których tej pamięci jest najmniej. */
  .bg-ray,
  .bg-ray::before {
    animation: none;
    will-change: auto;
  }
}

/* Kołysanie samego klina – ledwie stopień w każdą stronę i przez ponad minutę,
   więc czyta się jako oddech, a nie jako ruch. */
@keyframes beamSway {
  0%, 100% { rotate: -1.4deg; }
  50%      { rotate:  1.4deg; }
}

@keyframes beamSwayAlt {
  0%, 100% { rotate:  1.8deg; }
  50%      { rotate: -1.8deg; }
}

/* Wędrówka włókien w poprzek klina. Amplituda jest większa od podziałki
   włókien (5.4°), więc każde z nich przechodzi przez całą szerokość snopu –
   bez tego rysunek tylko by drgał w miejscu. */
@keyframes rayDrift {
  0%, 100% { rotate: -3.6deg; }
  50%      { rotate:  3.6deg; }
}

@keyframes rayDriftAlt {
  0%, 100% { rotate:  3deg; }
  50%      { rotate: -3deg; }
}

/* Pulsowanie wzdłuż snopu: włókna odjeżdżają od źródła i wracają. Skalujemy
   względem źródła, więc punkt wyjścia światła stoi w miejscu. */
@keyframes rayPulse {
  0%, 100% { scale: 1 1; }
  50%      { scale: 1.055 1.03; }
}

@keyframes rayPulseAlt {
  0%, 100% { scale: 1.045 1.025; }
  50%      { scale: 1 1; }
}

/* Migotanie: nierówne odstępy między klatkami, żeby światło „oddychało”
   jak płomień, a nie pulsowało metronomicznie. Oba strumienie mają inny
   okres, więc nigdy nie gasną i nie rozbłyskują razem. */
@keyframes rayFlicker {
  0%   { opacity: .64; }
  11%  { opacity: .90; }
  19%  { opacity: .72; }
  31%  { opacity: 1;   }
  43%  { opacity: .68; }
  54%  { opacity: .87; }
  67%  { opacity: .62; }
  78%  { opacity: .94; }
  89%  { opacity: .74; }
  100% { opacity: .64; }
}

/* oddech halo w źródle obu strumieni */
@keyframes haloBreath {
  0%, 100% { opacity: .55; transform: scale(1); }
  40%      { opacity: .95; transform: scale(1.06); }
  70%      { opacity: .72; transform: scale(1.02); }
}

/* =========
   Ellipsis for truncated snippets
   ========= */
.readmore-ellipsis {
  color: var(--brand);
  font-weight: 700;
  letter-spacing: 0.06em;
  padding-left: 0.15rem;
  text-shadow: 0 0 0 rgba(0,0,0,0); /* keep crisp */
}

/* Pływanie plam światła. Sam `transform` – dawne `filter: saturate()`
   w klatkach kazało przeglądarce przemalowywać warstwę co klatkę. */
@keyframes floatGlow {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  40%  { transform: translate3d(-4%, -2%, 0) scale(1.03); }
  70%  { transform: translate3d(3%, 5%, 0) scale(1.05); }
  100% { transform: translate3d(-2%, 3%, 0) scale(1.02); }
}

/* Szacunek dla osób wrażliwych na ruch.
   Poprzednia wersja wyciszała tylko tło i sekcje – w ruchu zostawały jeszcze
   halo i „iskrzenie” przypiętych kart, pulsowanie Ewangelii, wjazd kart oraz
   animacje ogłoszeń (animate-pulse / animate-float / animate-shake).
   Reguła poniżej wygasza wszystko, łącznie z płynnym przewijaniem. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }

  body { background-attachment: scroll; }
  body::before { opacity: .35; }
  body::after { opacity: .25; }
  section::before { opacity: .6; }

  /* Strumienie zostają – to rysunek tła, nie animacja – ale nieruchome
     i słabsze. Reguła `*` powyżej zatrzymuje je na pierwszej klatce. */
  .bg-rays { opacity: calc(var(--ray-opacity) * .75); }
  .bg-ray,
  .bg-ray::before { will-change: auto; }

  /* Elementy, które bez animacji startowej pozostałyby przezroczyste. */
  .gospel-conclusion,
  .carousel-item.active .gospel-card-animated,
  .carousel-item.active .welcome-card-animated,
  .carousel-item.active .liturgy-card {
    opacity: 1 !important;
    transform: none !important;
  }

  .pinned-card::before { opacity: .85; }
  .pinned-card::after { opacity: 0; }

  /* Hover nie powinien już przesuwać kart. */
  .card-announce:hover,
  .announcement-card:hover,
  .intention-week-link:hover,
  .office-hours-card-animated:hover,
  .announcement-masonry .pinned-card:hover,
  .announcement-masonry .pinned-card:focus-within {
    transform: none;
  }
}

/* ===========
   Layout
   =========== */

.site-main {
  position: relative;
  z-index: 1;
}

section {
  position: relative;
}

/* lekkie rozświetlenie każdej sekcji + delikatne „oddychanie” */
section::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 0%, var(--section-glow), transparent 70%);
  opacity: .7;
  pointer-events: none;
  z-index: -1;
  animation: sectionGlow 32s ease-in-out infinite alternate;
}

/* rozjaśnienie pierwszej sekcji pod headerem */
.site-hero + section::before {
  background: radial-gradient(circle at 50% -10%, var(--section-glow-strong), transparent 70%);
}

@keyframes sectionGlow {
  0% {
    opacity: .5;
    transform: translate3d(0, -6px, 0);
  }
  40% {
    opacity: .9;
    transform: translate3d(0, 4px, 0);
  }
  70% {
    opacity: .65;
    transform: translate3d(0, 0, 0);
  }
  100% {
    opacity: .85;
    transform: translate3d(0, 8px, 0);
  }
}

/* ===========
   Nawigacja
   =========== */

.navbar-elegant {
  background: linear-gradient(90deg, var(--brand-700), var(--brand-600));
  border-bottom: 1px solid rgba(224,177,68,.35);
  backdrop-filter: blur(12px);
}

.navbar-elegant .navbar-brand {
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #f9fafb;
}

.navbar-elegant .navbar-brand:hover {
  color: #ffffff;
}

.navbar-elegant .navbar-toggler {
  border-color: rgba(255,255,255,.4);
}

.navbar-elegant .navbar-toggler:focus {
  box-shadow: 0 0 0 .2rem rgba(224,177,68,.4);
}

.navbar-elegant .navbar-nav {
  gap: .4rem;
}

.navbar-elegant .nav-link {
  color: rgba(255,255,255,.9);
  padding: .45rem .95rem;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,.15);
  line-height: 1.2;
  transition: all .18s ease;
  font-size: .95rem;
}

.navbar-elegant .nav-link:hover,
.navbar-elegant .nav-link:focus {
  color: var(--brand-700);
  background: linear-gradient(180deg, #fde68a, #fbbf24);
  border-color: transparent;
  box-shadow: 0 0 0 .18rem rgba(224,177,68,.28);
  text-decoration: none;
}

.navbar-elegant .nav-link.active,
.navbar-elegant .nav-link[aria-current="page"] {
  color: var(--brand-700);
  background: linear-gradient(180deg, #fde68a, #fbbf24);
  border-color: transparent;
}

/* ===========
   Hero – zdjęcie jako tło całego headera
   =========== */

/* Zdjęcie hero było jednym plikiem JPEG 1600 px (264 kB) – 64% wagi strony
   głównej, i to na zdjęciu, które w ~96% zasłaniają gradienty poniżej.
   Teraz są dwa warianty WebP: 800 px (24 kB) na telefony i 1600 px (82 kB)
   od breakpointu lg. Oryginalny JPEG został tylko dla og:image, bo crawlery
   społecznościowe nie zawsze radzą sobie z WebP. */
.site-hero {
  padding: 2.5rem 0 2.75rem;
  background:
    /* mocniejsza „zasłona” pod tekstem po lewej */
    radial-gradient(circle at 15% 50%, rgba(15,23,42,.96), rgba(15,23,42,.85) 40%, transparent 70%),
    /* delikatne złoto i błękit */
    radial-gradient(circle at 0% 0%, rgba(224,177,68,.35), transparent 60%),
    radial-gradient(circle at 100% 0%, rgba(59,130,246,.35), transparent 60%),
    /* zdjęcie z kościoła */
    url("header-800.8c5aab69760c.webp");
  background-repeat: no-repeat;
  background-size: 110% 110%, 80% 80%, 80% 80%, cover;
  background-position: center, 0% 0%, 100% 0%, center;
  color: #f9fafb;
  border-bottom: 1px solid rgba(224,177,68,.4);
}

@media (min-width: 992px) {
  .site-hero {
    background-image:
      radial-gradient(circle at 15% 50%, rgba(15,23,42,.96), rgba(15,23,42,.85) 40%, transparent 70%),
      radial-gradient(circle at 0% 0%, rgba(224,177,68,.35), transparent 60%),
      radial-gradient(circle at 100% 0%, rgba(59,130,246,.35), transparent 60%),
      url("header-1600.08861492d119.webp");
  }
}

/* Na podstronach ten sam baner zajmował ok. 70% pierwszego ekranu telefonu,
   spychając właściwy tytuł strony poniżej zgięcia. Treść zostaje, znika tylko
   nadmiarowa przestrzeń. */
.site-hero--compact {
  padding: 1.25rem 0 1.5rem;
}

@media (max-width: 767.98px) {
  .site-hero--compact .container {
    padding-top: .5rem !important;
    padding-bottom: .5rem !important;
  }

  .site-hero--compact .display-6 {
    font-size: 1.5rem;
    margin-bottom: .5rem !important;
  }

  .site-hero--compact .lead {
    font-size: .95rem;
  }
}

.site-hero h1 {
  letter-spacing: .03em;
}

.text-hero-subtitle {
  color: rgba(241,245,249,.96);
}

.intention-card {
  background: radial-gradient(circle at 0 0, var(--card-tint), transparent 55%), var(--surface);
  border-radius: 1.2rem;
  border: 1px solid var(--border-subtle);
}

/* kartka z intencjami w headerze */

.hero-intentions {
  border-radius: 1.2rem;
  border: 1px solid var(--border-subtle);
  backdrop-filter: blur(14px);
  background: var(--surface-raised);
  box-shadow: var(--shadow-lg);
  max-width: 440px;
  margin-left: auto;
}

/* Nagłówek karty w hero jest teraz akapitem (patrz includes/header.html),
   więc celujemy w klasę, a nie w element. */
.hero-intentions-title {
  letter-spacing: .08em;
  font-weight: 700;
  color: var(--brand);
}

/* lista intencji – eleganckie wypunktowanie */
.hero-intentions ul {
  list-style: none;
  padding-left: 0;
  margin-bottom: 0;
}

.hero-intentions li {
  position: relative;
  padding-left: 1.1rem;
  font-size: .95rem;
  color: var(--text-main);
}

.hero-intentions li + li {
  margin-top: .15rem;
}

.hero-intentions li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .55em;
  width: .42rem;
  height: .42rem;
  border-radius: 999px;
  background: linear-gradient(180deg, #fde68a, #fbbf24);
  box-shadow: 0 0 0 1px rgba(15,23,42,.06);
}

/* złoty, bardziej „parafialny” przycisk */
.btn-intentions {
  background: linear-gradient(135deg, #fde68a, #fbbf24);
  color: #1f2937;
  border: none;
  font-weight: 600;
  padding-inline: 1.1rem;
  box-shadow: 0 6px 16px rgba(15,23,42,.18);
}

.btn-intentions:hover,
.btn-intentions:focus {
  background: linear-gradient(135deg, #facc15, #fbbf24);
  color: #111827;
  box-shadow: 0 8px 20px rgba(15,23,42,.25);
}

@media (max-width: 991.98px) {
  .hero-intentions {
    max-width: 100%;
    margin-left: 0;
    margin-top: 1.75rem;
  }
}

/* ===========
   Karty, ogłoszenia, treść
   =========== */

.card {
  border-radius: 1rem;
  border: 1px solid rgba(15,23,42,.04);
  background-color: var(--surface-soft);
  box-shadow: var(--shadow-sm);
}

.card-announce,
.announcement-card {
  border-radius: 1.1rem;
  border: 1px solid var(--border-strong);
  background: radial-gradient(circle at 0 0, var(--card-tint), transparent 65%), var(--surface);
  box-shadow: var(--shadow-md);
  position: relative;
  overflow: hidden;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}

.card-announce::before,
.announcement-card::before {
  content: "";
  position: absolute;
  inset: -40%;
  background: radial-gradient(circle at 0 0, rgba(224,177,68,.5), transparent 55%);
  opacity: 0;
  transform: translate3d(-12px, -12px, 0);
  transition: opacity .18s ease, transform .18s ease;
  pointer-events: none;
}

.card-announce:hover,
.announcement-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
  border-color: rgba(224,177,68,.6);
}

.card-announce:hover::before,
.announcement-card:hover::before {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

.badge-cat {
  background: var(--brand-600);
  color: #e5f0ff;
  font-weight: 500;
  border-radius: 999px;
  padding: .25rem .5rem;
}

/* linia meta pod tytułem ogłoszenia */
.announcement-meta {
  font-size: .85rem;
  color: var(--text-muted);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .25rem;
}

.announcement-meta .dot {
  width: .35rem;
  height: .35rem;
  border-radius: 999px;
  background: rgba(148,163,184,.9);
  display: inline-block;
}

/* Rich text */
.rich-content p {
  margin-bottom: .75rem;
}

.rich-content h2,
.rich-content h3 {
  margin-top: 1.25rem;
  margin-bottom: .5rem;
}

/* ===========
   Chips (kategorie)
   =========== */

.cat-chips {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}

.chip {
  display: inline-flex;
  align-items: center;
  padding: .35rem .9rem;
  border-radius: 999px;
  border: 1px solid var(--chip-border);
  background: var(--brand-soft);
  color: var(--brand-chip-text);
  text-decoration: none;
  font-weight: 500;
  line-height: 1.2;
  transition: all .16s ease;
  font-size: .9rem;
}

.chip:hover {
  background: var(--surface);
  border-color: var(--chip-border-hover);
  box-shadow: 0 1px 8px rgba(15,23,42,.08);
  text-decoration: none;
}

.chip.active {
  color: var(--brand-700);
  background: linear-gradient(180deg, #fde68a, #fbbf24);
  border-color: transparent;
  box-shadow: 0 1px 12px rgba(224,177,68,.4);
}

/* Wybrany filtr kategorii. Kolor kategorii jest wstawiany inline i wygrywał
   z `.chip.active`, przez co nie było widać, który filtr jest włączony.
   Zaznaczenie rysujemy więc obwódką, która nie koliduje z tłem. */
.chip-selected {
  font-weight: 700;
  box-shadow:
    0 0 0 2px var(--surface),
    0 0 0 4px var(--brand),
    0 2px 10px rgba(15,23,42,.2);
}

/* ===========
   Intencje / listy
   =========== */

.intention-week-link {
  border-radius: .9rem;
  border: 1px solid var(--border-subtle);
  background: var(--surface-soft);
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease, background .16s ease;
}

.intention-week-link:hover {
  transform: translateY(-2px);
  background: var(--surface);
  border-color: rgba(13,59,102,.32);
  box-shadow: 0 16px 32px rgba(15,23,42,.1);
}

.intention-day {
  border-radius: 1rem;
  background: var(--surface-raised);
  border: 1px solid var(--border-subtle);
  padding: 1.1rem 1.25rem;
  box-shadow: var(--shadow-sm);
}

.intention-day h2 {
  font-size: 1.05rem;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--brand);
}

.intention-day small {
  color: var(--text-muted);
}

.intention-day ul {
  margin-bottom: 0;
  padding-left: 1.1rem;
}

/* ===========
   Stopka
   =========== */

/* Usunięto reguły `.footer`, `.footer h6`, `.footer a` – element <footer>
   korzysta z klas Bootstrapa (bg-dark text-light), więc te style nigdy się
   nie stosowały. Zostają klasy faktycznie używane w szablonie. */

/* Sekcja powitalna na stronie głównej */
.home-welcome-section .card {
  border-radius: 1.25rem;
}

/* Czytelniejsze godziny kancelarii.
   Selektor celował w `.office-hours`, której nie ma w żadnym szablonie –
   karta ma klasę `.office-hours-card-animated`. */
.office-hours-card-animated dt {
  font-weight: 600;
}

.office-hours-card-animated dd {
  margin-bottom: .15rem;
}

/* Podpis – Alex Brush. Warianty Great Vibes i Parisienne zostały usunięte
   razem z ich krojami z Google Fonts: nie były używane w żadnym szablonie,
   a nadal pobierały się przy każdym wejściu na stronę. */
.signature-font-alex {
  font-family: "Alex Brush", "Segoe Script", "Bradley Hand", cursive;
  font-size: 1.6rem;
  letter-spacing: 0.02em;
}

/* Delikatne, ale czytelne opisy w stopce */
.footer-label {
  color: rgba(255, 255, 255, 0.75);
  font-size: 0.8rem;
}

.footer-copy {
  color: rgba(255, 255, 255, 0.6);
  font-size: 0.8rem;
}

/* Zajawki ogłoszeń na kartach */
.card-announce .rich-content {
  display: -webkit-box;
  -webkit-line-clamp: 6;      /* ~6 wierszy – dostosuj wg potrzeb */
  line-clamp: 6;              /* wersja standardowa, bez prefiksu */
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card-announce .rich-content p { margin-bottom: .5rem; }

/* =========================
   Przypięte ogłoszenia – połyskująca ramka
   ========================= */
.pinned-card {
  border-color: var(--gold);
  box-shadow:
    0 0 0 1px rgba(224,177,68,.7),
    0 0 18px rgba(224,177,68,.8),
    0 18px 45px rgba(15,23,42,.18);
  position: relative;
  overflow: hidden;
  transition:
    transform .34s cubic-bezier(.22,.61,.36,1),
    box-shadow .34s ease,
    filter .34s ease,
    border-color .34s ease;
  will-change: transform, box-shadow, filter;
}

.pinned-card .card-body {
  position: relative;
  z-index: 1;
  transition: transform .34s cubic-bezier(.22,.61,.36,1);
}

.pinned-card .card-body::before {
  content: "";
  position: absolute;
  inset: -70% -95%;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(
    110deg,
    rgba(255,255,255,0) 35%,
    rgba(255,255,255,.68) 50%,
    rgba(255,255,255,0) 66%
  );
  transform: translate3d(-45%, 0, 0) rotate(10deg);
}

.announcement-masonry .pinned-card:hover,
.announcement-masonry .pinned-card:focus-within {
  transform: translate3d(0, -8px, 0);
  border-color: var(--gold);
  filter: saturate(1.08) brightness(1.03);
  box-shadow:
    0 0 0 1px rgba(224,177,68,.9),
    0 0 34px rgba(224,177,68,.96),
    0 26px 58px rgba(15,23,42,.24);
}

.announcement-masonry .pinned-card:hover::after,
.announcement-masonry .pinned-card:focus-within::after {
  opacity: 0.82;
}

.announcement-masonry .pinned-card:hover .card-body,
.announcement-masonry .pinned-card:focus-within .card-body {
  transform: translate3d(0, -3px, 0);
}

.announcement-masonry .pinned-card:hover .card-body::before,
.announcement-masonry .pinned-card:focus-within .card-body::before {
  opacity: .62;
  animation: pinnedSheenSweep .9s cubic-bezier(.22,.61,.36,1) forwards;
}

.announcement-masonry .pinned-card:hover .badge-pinned,
.announcement-masonry .pinned-card:focus-within .badge-pinned {
  animation: pinHoverPulse .6s cubic-bezier(.22,.61,.36,1);
}

/* Nadpisujemy pseudo-element tylko dla przypiętych kart,
   żeby był cały czas widoczny i delikatnie "płynął" */
.pinned-card::before {
  content: "";
  position: absolute;
  inset: -45%;
  background: radial-gradient(circle at 0 0, rgba(224,177,68,.55), transparent 55%);
  opacity: 0.85;
  pointer-events: none;
  animation: pinnedHalo 4s ease-in-out infinite alternate;
}

/* Dodatkowy subtelny „błysk” na obwódce */
.pinned-card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 2px solid rgba(255,255,255,.7);
  mix-blend-mode: soft-light;
  opacity: 0;
  pointer-events: none;
  animation: pinnedSparkle 3s ease-in-out infinite;
}

@keyframes pinnedHalo {
  0% {
    transform: translate3d(-20px, -20px, 0);
    opacity: 0.6;
  }
  50% {
    transform: translate3d(0, 0, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(20px, 20px, 0);
    opacity: 0.6;
  }
}

@keyframes pinnedSparkle {
  0%, 100% {
    opacity: 0;
  }
  50% {
    opacity: 0.55;
  }
}

@keyframes pinHoverPulse {
  0% {
    transform: scale(1) rotate(0deg);
  }
  35% {
    transform: translate3d(-2px, -2px, 0) scale(1.1) rotate(8deg);
  }
  70% {
    transform: translate3d(1px, -1px, 0) scale(1.04) rotate(-6deg);
  }
  100% {
    transform: scale(1) rotate(0deg);
  }
}

@keyframes pinnedSheenSweep {
  0% {
    transform: translate3d(-55%, 0, 0) rotate(10deg);
  }
  100% {
    transform: translate3d(40%, 0, 0) rotate(10deg);
  }
}

/* Ładne podkreślenie nagłówków sekcji */
.section-heading-muted {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
}

.section-heading-muted::after {
  content: "";
  display: inline-block;
  height: 1px;
  width: 120px;
  background: linear-gradient(to right, var(--border-strong), transparent);
  opacity: .8;
}

/* Pinezka dla przypiętych ogłoszeń – większa i wyraźniejsza */
.badge-pinned {
  position: absolute;
  top: 0.4rem;
  right: 0.6rem;
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: radial-gradient(circle at 30% 20%, #ffffff, #fee2e2);
  box-shadow:
    0 0 0 2px rgba(248,250,252,1),
    0 0 0 1px rgba(248,113,113,.9),
    0 6px 14px rgba(15,23,42,.35);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  z-index: 3;
}

.badge-pinned-icon {
  width: 20px;
  height: 20px;
  /* kolory biorą się z gradientów w SVG,
     ale dodajemy lekkie podbicie kontrastu wizualnie */
  filter: drop-shadow(0 1px 1px rgba(0,0,0,.35));
}

/* Większy zapas na tytuł, bo pinezka jest większa */
.pinned-card .card-title {
  padding-right: 3.2rem;
}

.announcement-masonry {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1rem;
  align-items: stretch;
}

.announcement-masonry-item {
  display: flex;
  min-width: 0;
  margin: 0;
}

.announcement-masonry-item > .pinned-card {
  width: 100%;
}

.announcement-masonry-no-image {
  grid-template-columns: minmax(0, 1fr);
}

.announcement-masonry-with-image {
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 576px) {
  .announcement-masonry {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .announcement-masonry-no-image {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 992px) {
  .announcement-masonry {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .announcement-masonry-no-image {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 768px) {
  .announcement-masonry-with-image {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-flow: dense;
  }

  .announcement-masonry-with-image .announcement-masonry-item {
    grid-row: span 1;
  }

  /* Karty przypięte ze zdjęciem zajmują dwa rzędy tylko w wariancie ze zdjęciami. */
  .announcement-masonry-with-image .announcement-masonry-item-has-image {
    grid-row: span 2;
  }
}

@media (min-width: 1200px) {
  .announcement-masonry-with-image {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.announcement-image-figure {
  margin: 0;
}

.announcement-image-frame {
  width: 100%;
}

.announcement-lead-image {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 0.8rem;
  box-shadow: 0 10px 24px rgba(15, 23, 42, .12);
}

.announcement-image-caption {
  margin-top: .45rem;
  font-size: .86rem;
  color: var(--text-muted);
}

.pinned-card .announcement-image-figure {
  margin-bottom: .7rem;
}

.pinned-card-has-image .announcement-image-frame {
  display: block;
  overflow: hidden;
  border-radius: 0.85rem;
  background: var(--surface);
  transition: transform .34s cubic-bezier(.22,.61,.36,1), box-shadow .34s ease;
}

.pinned-card-has-image .announcement-lead-image {
  width: 100%;
  height: auto;
  border-radius: 0;
  box-shadow: none;
  transition: transform .46s cubic-bezier(.22,.61,.36,1);
}

.pinned-card-has-image .announcement-image-caption {
  line-height: 1.32;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.announcement-masonry .pinned-card:hover .announcement-image-frame,
.announcement-masonry .pinned-card:focus-within .announcement-image-frame {
  transform: translate3d(0, -2px, 0);
  box-shadow: 0 12px 26px rgba(15,23,42,.22);
}

.announcement-masonry .pinned-card:hover .announcement-lead-image,
.announcement-masonry .pinned-card:focus-within .announcement-lead-image {
  transform: scale(1.045);
}

.card-announce .card-text.rich-content img,
.card-announce .card-text.rich-content figure,
.card-announce .card-text.rich-content iframe,
.card-announce .card-text.rich-content video,
.card-announce .card-text.rich-content .richtext-image {
  display: none !important;
}

/* (Definicja .section-heading-muted jest wyżej – powtórzenie usunięte.) */

/* Lista ogłoszeń w układzie pionowym */
.announcement-list-vertical {
  margin-top: 0.75rem;
}

/* Prostokątne karty – widok "wierszowy" */
.announcement-row {
  border-radius: 1rem;
}

.announcement-row .card-body {
  padding: 1rem 1.25rem;
}

@media (min-width: 768px) {
  .announcement-row .card-body {
    padding: 1.1rem 1.5rem;
  }
}

/* Blok daty po lewej stronie prostokątnego ogłoszenia */
.announcement-date-box {
  min-width: 64px;
  padding: 0.4rem 0.35rem;
  border-radius: 0.9rem;
  background: linear-gradient(145deg, var(--date-box-1), var(--date-box-2));
  box-shadow: var(--shadow-sm);
  line-height: 1.1;
}

.announcement-date-box .day {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--date-box-text);
}

.announcement-date-box .month {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--date-box-muted);
}

.announcement-date-box .year {
  font-size: 0.65rem;
  /* Było #94a3b8 na jasnym tle kafelka – kontrast ok. 2:1, poniżej progu WCAG. */
  color: var(--date-box-muted);
}

/* Nagłówki miesięcy */
.month-heading {
  letter-spacing: .12em;
}

/* (Definicje .badge-pinned, .badge-pinned-icon oraz .pinned-card .card-title
   są wyżej – powtórzenia usunięte.) */

/* ===========
   Karuzela Powitalna
   =========== */

.custom-welcome-carousel .carousel-inner {
  border-radius: 1rem;
}

.custom-welcome-carousel .carousel-indicators {
  bottom: 0.5rem;
}

/* Sama kropka zostaje mała, ale pole dotyku ma 24x24 px – WCAG 2.5.8.
   Wcześniej cały przycisk miał 14x14 px razem z obwódką. */
.custom-welcome-carousel .carousel-indicators [data-bs-target] {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background-color: var(--brand);
  background-clip: content-box;
  padding: 6px;
  opacity: 0.3;
  border: 2px solid #fff;
  margin: 0 4px;
}

.custom-welcome-carousel .carousel-indicators .active {
  opacity: 1;
  background-color: var(--gold);
}

.custom-welcome-carousel .carousel-control-prev,
.custom-welcome-carousel .carousel-control-next {
  width: 40px;
  height: 40px;
  background: var(--surface-raised);
  border-radius: 50%;
  top: 50%;
  transform: translateY(-50%);
  color: var(--brand);
  border: 1px solid var(--border-subtle);
  opacity: 0;
  transition: all 0.3s ease;
  z-index: 10;
}

/* Strzałki były ukryte przez opacity: 0, ale nadal łapały fokus klawiatury –
   fokus wędrował na niewidzialny element (WCAG 2.4.7). Na ekranach dotykowych
   hover nie istnieje, więc tam pokazujemy je na stałe. */
.custom-welcome-carousel .carousel-control-prev:focus-visible,
.custom-welcome-carousel .carousel-control-next:focus-visible {
  opacity: 1;
}

@media (hover: none) {
  .custom-welcome-carousel .carousel-control-prev,
  .custom-welcome-carousel .carousel-control-next {
    opacity: .85;
  }
}

.custom-welcome-carousel:hover .carousel-control-prev,
.custom-welcome-carousel:hover .carousel-control-next {
  opacity: 1;
}

.custom-welcome-carousel .carousel-control-prev { left: -10px; }
.custom-welcome-carousel .carousel-control-next { right: -10px; }

.custom-welcome-carousel .carousel-control-prev-icon,
.custom-welcome-carousel .carousel-control-next-icon {
  filter: var(--carousel-icon-filter);
  width: 18px;
}

/* Animacja karty Ewangelii */
.gospel-card-animated {
  background: linear-gradient(135deg, var(--surface) 0%, var(--surface-raised) 100%) !important;
  border: 2px solid rgba(224, 177, 68, 0.3) !important;
  box-shadow: var(--shadow-sm) !important;
  border-radius: 1.25rem !important;
  overflow: hidden;
}

.gospel-card-animated .card-body {
  min-height: 0;
  height: 100%;
}

.gospel-card-animated::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 50%, rgba(224, 177, 68, 0.1), transparent 70%);
  opacity: 0;
  animation: gospelPulse 5s ease-in-out infinite alternate;
  pointer-events: none;
  z-index: 0;
}

@keyframes gospelPulse {
  0% { opacity: 0.2; transform: scale(0.98); }
  100% { opacity: 0.5; transform: scale(1.05); }
}

.gospel-text-main {
  font-family: "Georgia", "Times New Roman", Times, serif;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--text-reading);
  flex: 1 1 auto;
  min-height: 0;
  max-height: 450px;
  overflow-y: auto;
  padding-right: 0.75rem;
  scrollbar-width: thin;
  scrollbar-color: var(--brand) transparent;
}

@media (min-width: 992px) {
  .gospel-text-main {
    max-height: 800px;
  }
}

.gospel-text-main p:last-child {
  margin-bottom: 0;
}

.gospel-text-main::-webkit-scrollbar {
  width: 6px;
}

.gospel-text-main::-webkit-scrollbar-track {
  background: var(--surface-inset);
  border-radius: 10px;
}

.gospel-text-main::-webkit-scrollbar-thumb {
  background: var(--brand);
  border-radius: 10px;
}

.gospel-text-main::-webkit-scrollbar-thumb:hover {
  background: var(--brand);
}

.gospel-conclusion {
  display: block;
  margin-top: 1.5rem;
  font-weight: 700;
  color: var(--brand);
  font-style: italic;
  text-align: right;
  border-top: 1px solid rgba(133, 77, 14, 0.1);
  padding-top: 0.5rem;
  animation: conclusionFadeIn 1.5s ease-out both, conclusionPulse 3s ease-in-out infinite 2s;
}

@keyframes conclusionFadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes conclusionPulse {
  0% { opacity: 1; }
  50% { opacity: 0.7; }
  100% { opacity: 1; }
}

/* Animacja wejścia kart */
.carousel-item.active .gospel-card-animated,
.carousel-item.active .welcome-card-animated,
.carousel-item.active .liturgy-card {
  animation: cardSlideIn 0.7s cubic-bezier(0.23, 1, 0.32, 1) both;
}

@keyframes cardSlideIn {
  0% { opacity: 0; transform: translateY(15px); }
  100% { opacity: 1; transform: translateY(0); }
}

/* Usunięto `.custom-liturgy-carousel` – klasa nie występuje w żadnym szablonie
   (zakładki zastąpiły karuzelę). */

/* Nowy system zakładek liturgicznych */
.liturgy-nav-pills {
  margin-bottom: 0 !important;
  z-index: 2;
  position: relative;
  display: flex;
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  /* Pasek zakładek przewija się w poziomie, a `scrollbar-width: none`
     ukrywało jedyną informację o tym, że dalej są kolejne czytania.
     Zamiast chować suwak, pokazujemy go w wersji cienkiej – widać go tylko
     wtedy, gdy faktycznie jest co przewijać. */
  scrollbar-width: thin;
  scrollbar-color: rgba(148,163,184,.6) transparent;
  scroll-snap-type: x proximity;
  padding-bottom: 2px;
}

.liturgy-nav-pills .nav-item {
  scroll-snap-align: start;
}

.liturgy-nav-pills::-webkit-scrollbar { height: 4px; }
.liturgy-nav-pills::-webkit-scrollbar-track { background: transparent; }
.liturgy-nav-pills::-webkit-scrollbar-thumb {
  background: rgba(148,163,184,.6);
  border-radius: 10px;
}

.liturgy-nav-pills .nav-link {
  background: var(--surface-sunken);
  color: var(--text-muted);
  border: 1px solid var(--border-subtle);
  border-bottom: none;
  border-radius: 0.75rem 0.75rem 0 0;
  padding: 0.6rem 1.1rem;
  font-size: 0.75rem;
  font-weight: 700;
  transition: all 0.2s ease;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: -1px;
  white-space: nowrap;
}

.liturgy-nav-pills .nav-link:hover {
  background: var(--surface-inset);
  color: var(--brand);
}

.liturgy-nav-pills .nav-link.active {
  background: var(--surface) !important;
  color: var(--brand) !important;
  border-color: var(--border-subtle);
  border-bottom: 2px solid var(--surface) !important;
  z-index: 3;
  box-shadow: 0 -5px 15px rgba(0,0,0,0.04);
}

/* Animacja dla tab-pane */
.tab-pane.fade {
  transition: opacity 0.2s linear, transform 0.3s ease-out;
  transform: translateY(8px);
}

.tab-pane.fade.show {
  transform: translateY(0);
}

.liturgy-card {
  border-radius: 0 1rem 1rem 1rem !important;
  border: 1px solid var(--border-subtle) !important;
  /* Sztywne 450px na telefonie dawało wysoką, w połowie pustą kartę.
     Na małych ekranach karta dopasowuje się do treści. */
  min-height: 260px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.05) !important;
}

@media (min-width: 768px) {
  .liturgy-card {
    min-height: 450px;
  }
}

/* Usunięto `.reflection-card` – szablon nigdy nie renderuje rozważania
   (get_daily_liturgy zawsze zwraca `reflection: None`). */

.reading-card {
  background: var(--surface) !important;
  border-left: 4px solid var(--brand) !important;
}

.liturgy-text-small {
  font-family: "Georgia", serif;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--text-reading);
  max-height: 60vh;
  overflow-y: auto;
  padding-right: 0.5rem;
  scrollbar-width: thin;
  scrollbar-color: var(--brand) transparent;
}

.liturgy-text-small::-webkit-scrollbar {
  width: 4px;
}

.liturgy-text-small::-webkit-scrollbar-thumb {
  background: var(--brand);
  border-radius: 10px;
}

.office-hours-card-animated {
  border-radius: 1rem !important;
  border: 1px solid var(--border-subtle) !important;
  transition: all 0.3s ease;
}

.office-hours-card-animated:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 25px rgba(0,0,0,0.1) !important;
}

/* Usunięto `.carousel-controls-mini` oraz `.carousel-control-*-icon-dark` –
   żadna z tych klas nie występuje w szablonach. */

/* Nowe animacje dla ogłoszeń */
@keyframes pulse-subtle {
  0% { transform: scale(1); }
  50% { transform: scale(1.02); }
  100% { transform: scale(1); }
}

.animate-pulse {
  animation: pulse-subtle 2s infinite ease-in-out;
}

@keyframes float-subtle {
  0% { transform: translateY(0); }
  50% { transform: translateY(-5px); }
  100% { transform: translateY(0); }
}

.animate-float {
  animation: float-subtle 3s infinite ease-in-out;
}

/* Cykl 0.15s to ok. 7 drgnięć na sekundę – migotanie w tym zakresie jest
   męczące, a dla osób z nadwrażliwością przedsionkową lub padaczką
   światłoczułą wprost ryzykowne. Ten sam efekt „zwrócenia uwagi” osiągamy
   krótkim drgnięciem powtarzanym co kilka sekund. */
@keyframes shake-subtle {
  0%, 88%, 100% { transform: rotate(0); }
  91% { transform: rotate(0.6deg); }
  94% { transform: rotate(-0.6deg); }
  97% { transform: rotate(0.3deg); }
}

.animate-shake {
  animation: shake-subtle 4s infinite ease-in-out;
}

/* Po najechaniu wyłączamy animację ciągłą zamiast ją pauzować:
   `animation-play-state: paused` zatrzymywało kartę w losowej klatce
   (np. przechyloną albo powiększonej), co gryzło się z efektem hover. */
.announcement-card.animate-pulse:hover,
.announcement-card.animate-float:hover,
.announcement-card.animate-shake:hover,
.announcement-card.animate-pulse:focus-within,
.announcement-card.animate-float:focus-within,
.announcement-card.animate-shake:focus-within {
  animation: none;
}

/* Ulepszenia dla osadzonego PDF.
   Wysokość była wpisana w szablonie jako height:100vh; min-height:600px –
   na telefonie ramka z dokumentem była wyższa niż cały ekran i spychała
   resztę ogłoszenia poniżej widoku. Teraz skaluje się z rozmiarem okna. */
.pdf-embed-wrapper {
  background-color: var(--surface-inset);
  position: relative;
  height: 70vh;
  min-height: 320px;
  max-height: 1100px;
}

@media (min-width: 768px) {
  .pdf-embed-wrapper {
    height: 85vh;
    min-height: 520px;
  }
}

.pdf-embed-wrapper iframe {
  display: block;
  width: 100%;
  height: 100%;
}

/* Stylizacja paska nagłówka dla sekcji PDF wewnątrz karty */
.announcement-pdf-container h2 {
  color: var(--brand);
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* ===========
   Wydruk – ogłoszenia i intencje bywają drukowane i wieszane w gablocie
   =========== */
@media print {
  /* Ruchome tła i poświaty tylko zużywają toner. */
  body,
  body::before,
  body::after,
  section::before,
  .pinned-card::before,
  .pinned-card::after,
  .card-announce::before,
  .announcement-card::before {
    background: none !important;
    animation: none !important;
    box-shadow: none !important;
    content: none !important;
  }

  body {
    color: #000;
    background: #fff !important;
  }

  /* Elementy nawigacyjne nie niosą treści na papierze. */
  .navbar,
  .site-hero,
  .skip-link,
  .cat-chips,
  .pagination,
  .carousel-control-prev,
  .carousel-control-next,
  .carousel-indicators,
  .btn,
  footer {
    display: none !important;
  }

  .card,
  .card-announce,
  .announcement-card,
  .pinned-card,
  .liturgy-card,
  .intention-day {
    border: 1px solid #999 !important;
    box-shadow: none !important;
    background: #fff !important;
    break-inside: avoid;
  }

  /* Na ekranie zajawki są przycięte do 6 wierszy – na wydruku chcemy całość. */
  .card-announce .rich-content,
  .pinned-card-has-image .announcement-image-caption {
    display: block;
    -webkit-line-clamp: none;
    line-clamp: none;
    overflow: visible;
  }

  /* Panele z własnym przewijaniem muszą wydrukować pełną treść. */
  .gospel-text-main,
  .liturgy-text-small {
    max-height: none;
    overflow: visible;
  }

  /* Ukryte zakładki liturgii – na papierze pokazujemy wszystkie czytania. */
  .tab-content > .tab-pane {
    display: block !important;
    opacity: 1 !important;
    transform: none !important;
  }

  .carousel-item {
    display: block !important;
    opacity: 1 !important;
  }

  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: .85em;
    color: #444;
  }
}

/* ===========================================================================
   Treść ogłoszenia w układzie blokowym (StreamField)
   ===========================================================================
   Ogłoszenie nie jest już jednym polem tekstu sformatowanego, tylko listą
   bloków: akapit, tabela, zdjęcie, galeria, cytat, film, plik. Każdy z nich
   dostaje tu własny rytm pionowy i własne zasady szerokości.
   =========================================================================== */

.stream-content > * + * {
  margin-top: 1.35rem;
}

.stream-content > .stream-block--text + .stream-block--text {
  margin-top: .35rem;
}

/* --- Tabele --------------------------------------------------------------- */

.rich-table-scroll {
  overflow-x: auto;
  border-radius: .85rem;
  border: 1px solid var(--border-subtle);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  /* Delikatny cień „jest tu więcej w prawo”, gdy tabela nie mieści się
     w kolumnie tekstu – bez tego na telefonie nie widać, że da się przewinąć. */
  background-image:
    linear-gradient(to right, var(--surface) 30%, transparent),
    linear-gradient(to left, var(--surface) 30%, transparent),
    linear-gradient(to right, rgba(15,23,42,.14), transparent 12px),
    linear-gradient(to left, rgba(15,23,42,.14), transparent 12px);
  background-position: 0 0, 100% 0, 0 0, 100% 0;
  background-repeat: no-repeat;
  background-size: 40px 100%, 40px 100%, 14px 100%, 14px 100%;
  background-attachment: local, local, scroll, scroll;
}

.rich-table-scroll:focus-visible {
  outline: 2px solid transparent;
  box-shadow: var(--focus-ring);
}

.rich-table-scroll table {
  width: 100%;
  margin: 0;
  border-collapse: collapse;
  font-size: .95rem;
}

.rich-table-scroll caption {
  caption-side: top;
  padding: .85rem 1rem .35rem;
  font-weight: 600;
  color: var(--text-main);
  text-align: left;
}

.rich-table-scroll th,
.rich-table-scroll td {
  padding: .6rem .9rem;
  border-bottom: 1px solid var(--border-subtle);
  vertical-align: top;
  text-align: left;
}

.rich-table-scroll thead th,
.rich-table-scroll tbody th[scope="row"] {
  background: var(--surface-inset);
  font-weight: 700;
  color: var(--text-main);
}

.rich-table-scroll thead th {
  position: sticky;
  top: 0;
  z-index: 1;
}

.rich-table-scroll tbody tr:last-child th,
.rich-table-scroll tbody tr:last-child td {
  border-bottom: 0;
}

.rich-table-scroll tbody tr:nth-child(even) td {
  background: color-mix(in srgb, var(--surface-inset) 45%, transparent);
}

/* Klasy wyrównania nadaje edytor tabel (Handsontable). */
.rich-table-scroll .htCenter { text-align: center; }
.rich-table-scroll .htRight  { text-align: right; }
.rich-table-scroll .htJustify { text-align: justify; }

/* --- Zdjęcia i galeria ----------------------------------------------------- */

.stream-image--wide {
  /* Wyjście poza kolumnę tekstu, ale nigdy poza ekran. */
  width: min(100vw - 2rem, 1100px);
  max-width: none;
  margin-inline: calc(50% - min(50vw - 1rem, 550px));
}

@media (min-width: 768px) {
  .stream-image--left,
  .stream-image--right {
    max-width: 22rem;
    margin-block: .35rem;
  }

  .stream-image--left {
    float: left;
    margin-right: 1.5rem;
  }

  .stream-image--right {
    float: right;
    margin-left: 1.5rem;
  }
}

.stream-gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
  gap: .75rem;
}

@media (min-width: 768px) {
  .stream-gallery-grid {
    grid-template-columns: repeat(var(--gallery-columns, 3), minmax(0, 1fr));
  }
}

.stream-gallery-image {
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
  border-radius: .75rem;
  box-shadow: var(--shadow-sm);
  transition: transform .3s cubic-bezier(.22,.61,.36,1), box-shadow .3s ease;
}

.stream-gallery-item:hover .stream-gallery-image,
.stream-gallery-item:focus-within .stream-gallery-image {
  transform: scale(1.03);
  box-shadow: var(--shadow-md);
}

/* --- Cytat ---------------------------------------------------------------- */

.stream-quote {
  margin: 0;
  padding: 1.1rem 1.35rem 1.1rem 2.6rem;
  position: relative;
  border-radius: .9rem;
  border-left: 4px solid var(--gold);
  background: color-mix(in srgb, var(--gold) 10%, var(--surface));
  color: var(--text-main);
}

.stream-quote::before {
  content: "„";
  position: absolute;
  left: .7rem;
  top: .1rem;
  font-size: 2.6rem;
  line-height: 1;
  color: var(--gold);
  opacity: .75;
}

.stream-quote blockquote {
  margin: 0;
  font-size: 1.05rem;
  font-style: italic;
}

.stream-quote figcaption {
  margin-top: .6rem;
  font-size: .875rem;
  font-weight: 600;
  color: var(--text-muted);
}

.stream-quote figcaption::before {
  content: "— ";
}

/* Cytat wpisany wprost w edytorze tekstu (funkcja „blockquote”). */
.rich-content blockquote {
  margin: 0;
  padding-left: 1.1rem;
  border-left: 3px solid var(--gold);
  color: var(--text-main);
  font-style: italic;
}

.rich-content code {
  background: var(--surface-inset);
  border-radius: .3rem;
  padding: .1rem .35rem;
  font-size: .92em;
}

.rich-content hr {
  border: 0;
  border-top: 1px solid var(--border-strong);
  margin: 1.5rem 0;
  opacity: 1;
}

/* --- Plik do pobrania ------------------------------------------------------ */

.stream-document {
  display: flex;
  align-items: center;
  gap: .9rem;
  padding: .9rem 1.1rem;
  border-radius: .85rem;
  border: 1px solid var(--border-subtle);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  color: inherit;
  text-decoration: none;
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}

.stream-document:hover,
.stream-document:focus-visible {
  transform: translateY(-2px);
  border-color: var(--gold);
  box-shadow: var(--shadow-md);
  color: inherit;
}

.stream-document-icon {
  width: 2rem;
  height: 2rem;
  flex: 0 0 auto;
  color: var(--brand);
}

.stream-document-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.stream-document-title {
  font-weight: 600;
}

.stream-document-desc,
.stream-document-meta {
  font-size: .85rem;
  color: var(--text-muted);
}

/* --- Osadzony film --------------------------------------------------------- */

.stream-embed iframe,
.stream-embed video {
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  border: 0;
  border-radius: .85rem;
  box-shadow: var(--shadow-sm);
}

/* ===========================================================================
   Warstwa „nowoczesna”: przejścia między stronami, odsłanianie przy
   przewijaniu, pasek postępu czytania, powrót na górę, przełącznik motywu
   =========================================================================== */

/* Płynne przejście między podstronami (Chrome/Edge; reszta przeglądarek po
   prostu przechodzi jak dotąd). Wyłączone dla osób z ograniczonym ruchem. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }
}

html {
  scroll-behavior: smooth;
  /* Kotwice nie mogą chować się pod przyklejoną belką nawigacji. */
  scroll-padding-top: 5rem;
}

::selection {
  background: color-mix(in srgb, var(--gold) 55%, transparent);
  color: var(--text-main);
}

/* --- Przyklejona nawigacja -------------------------------------------------- */

.navbar-elegant {
  position: sticky;
  top: 0;
  z-index: 1030;
  transition: box-shadow .25s ease, padding .25s ease;
}

.navbar-elegant.is-stuck {
  box-shadow: 0 10px 28px rgba(2, 8, 20, .35);
  padding-block: .15rem;
}

/* --- Odsłanianie treści przy przewijaniu ------------------------------------
   Animujemy `opacity` i `translate` (osobną własność), a NIE `transform`.
   Gdyby animacja z `fill-mode: both` ustawiała `transform`, jej końcowa
   klatka nadpisałaby na stałe `transform: translateY(-3px)` z reguły :hover
   i karty przestałyby się unosić po najechaniu.
   ---------------------------------------------------------------------------- */

@keyframes parafiaReveal {
  from { opacity: 0; translate: 0 14px; }
  to   { opacity: 1; translate: none; }
}

@media (prefers-reduced-motion: no-preference) {
  /* Wariant bez JS-a: oś czasu animacji wyznacza pozycja elementu w oknie. */
  @supports (animation-timeline: view()) {
    .reveal {
      animation: parafiaReveal linear both;
      animation-timeline: view();
      animation-range: entry 2% cover 18%;
    }
  }

  /* Wariant dla przeglądarek bez scroll-driven animations – klasę `is-revealed`
     dokłada static/site.js przez IntersectionObserver. */
  @supports not (animation-timeline: view()) {
    .js .reveal {
      opacity: 0;
      translate: 0 14px;
      transition: opacity .5s ease, translate .5s cubic-bezier(.22,.61,.36,1);
    }

    .js .reveal.is-revealed {
      opacity: 1;
      translate: none;
    }
  }
}

/* --- Pasek postępu czytania ------------------------------------------------- */

.reading-progress {
  position: fixed;
  inset: 0 0 auto 0;
  height: 3px;
  z-index: 1040;
  background: linear-gradient(90deg, var(--gold), var(--brand));
  transform-origin: 0 50%;
  scale: 0 1;
  pointer-events: none;
}

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .reading-progress {
      animation: parafiaProgress linear both;
      animation-timeline: scroll(root block);
    }
  }
}

@keyframes parafiaProgress {
  from { scale: 0 1; }
  to   { scale: 1 1; }
}

/* Bez obsługi animacji sterowanych przewijaniem pasek byłby zawsze pusty –
   wtedy lepiej go w ogóle nie pokazywać. Skrypt zdejmuje `hidden` tylko wtedy,
   gdy przeglądarka umie go animować. */
.reading-progress[hidden] {
  display: none;
}

/* --- Powrót na górę --------------------------------------------------------- */

.to-top {
  position: fixed;
  right: max(1rem, env(safe-area-inset-right));
  bottom: max(1rem, env(safe-area-inset-bottom));
  z-index: 1035;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.9rem;
  height: 2.9rem;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--surface-raised);
  color: var(--brand);
  box-shadow: var(--shadow-md);
  cursor: pointer;
  opacity: 0;
  translate: 0 .75rem;
  pointer-events: none;
  transition: opacity .22s ease, translate .22s ease, background .18s ease;
}

.to-top.is-visible {
  opacity: 1;
  translate: none;
  pointer-events: auto;
}

.to-top:hover {
  background: linear-gradient(135deg, var(--gold-soft), var(--gold));
  color: #1f2937;
}

.to-top svg {
  width: 1.15rem;
  height: 1.15rem;
}

/* --- Przełącznik motywu ------------------------------------------------------ */

.theme-toggle {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .35rem .7rem;
  border-radius: 999px;
  border: 1px solid rgba(255,255,255,.25);
  background: rgba(255,255,255,.08);
  color: rgba(255,255,255,.92);
  font-size: .85rem;
  line-height: 1.2;
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease, color .18s ease;
}

.theme-toggle:hover,
.theme-toggle:focus-visible {
  background: linear-gradient(180deg, var(--gold-soft), #fbbf24);
  border-color: transparent;
  color: #0a274a;
}

.theme-toggle svg {
  width: 1.05rem;
  height: 1.05rem;
  flex: 0 0 auto;
}

/* Pokazujemy tylko ikonę pasującą do aktualnego ustawienia. */
.theme-toggle [data-theme-icon] { display: none; }
:root[data-theme-choice="light"] .theme-toggle [data-theme-icon="light"],
:root[data-theme-choice="dark"] .theme-toggle [data-theme-icon="dark"],
:root[data-theme-choice="auto"] .theme-toggle [data-theme-icon="auto"] { display: inline-block; }

/* Dopóki skrypt nie wystartuje, przycisk nie ma czego przełączać. */
.no-js .theme-toggle { display: none; }

@media (max-width: 991.98px) {
  .theme-toggle {
    width: 100%;
    justify-content: center;
    margin-top: .5rem;
  }
}

/* Osoby ograniczające ruch nie potrzebują animowanego paska ani wjazdów. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .reveal {
    opacity: 1 !important;
    translate: none !important;
  }

  .reading-progress { display: none; }
}

/* --- Wydruk ------------------------------------------------------------------ */

@media print {
  .to-top,
  .reading-progress,
  .theme-toggle {
    display: none !important;
  }

  .rich-table-scroll {
    overflow: visible;
    box-shadow: none !important;
    background-image: none !important;
  }

  .stream-image--wide {
    width: auto;
    margin-inline: 0;
  }
}

/* Nagłówki w zajawce na liście.
   Zajawka bierze pierwsze zdania treści, a te mogą zaczynać się od nagłówka
   drugiego poziomu. W karcie wielkości kilku wierszy taki nagłówek wchodził
   rozmiarem na tytuł samego ogłoszenia. */
.card-announce .rich-content :is(h2, h3, h4) {
  font-size: 1rem;
  font-weight: 600;
  margin-top: .5rem;
  margin-bottom: .25rem;
}

/* Zajawka nie potrzebuje też ozdobników bloku cytatu. */
.card-announce .rich-content blockquote {
  border-left-width: 2px;
  padding-left: .75rem;
  font-style: normal;
}
