/* Fonty self-hosted — wygenerowane przez scripts/build-assets.js */
@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-display: swap;
  font-weight: 400 700;
  src: url("/build/fonts/hanken-grotesk-latin-wght-normal.e9201eddf1.woff2") format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

@font-face {
  font-family: 'Hanken Grotesk';
  font-style: normal;
  font-display: swap;
  font-weight: 400 700;
  src: url("/build/fonts/hanken-grotesk-latin-ext-wght-normal.cffaf78847.woff2") format('woff2');
  unicode-range: U+0104-0107, U+0118-0119, U+0141-0144, U+015A-015B, U+0179-017C;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-display: swap;
  font-weight: 400 700;
  src: url("/build/fonts/inter-latin-wght-normal.3100e775e8.woff2") format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-display: swap;
  font-weight: 400 700;
  src: url("/build/fonts/inter-latin-ext-wght-normal.31e49834ef.woff2") format('woff2');
  unicode-range: U+0104-0107, U+0118-0119, U+0141-0144, U+015A-015B, U+0179-017C;
}

/* ============================================================================
   ROD Suchynia — arkusz stylów aplikacji
   ----------------------------------------------------------------------------
   Port design/Main.dc.html. Wygląd bez zmian; jedyna różnica strukturalna to
   zamiana atrybutów style="…" na klasy modyfikatorów — inline style łamią
   politykę CSP (style-src 'self'), a ta jest wymogiem planu.

   Ikony: zamiast fontu Material Symbols (~300 KB) używamy sprite'u SVG
   wstawianego w stronę; klasa .icon odpowiada dawnemu .material-symbols-outlined,
   a modyfikatory .icon--NN dawnym atrybutom font-size.

   Odwołania do plików zapisane jako {{ asset:NAZWA }} podmienia
   scripts/build-assets.js na ścieżki z hashem treści.
   ========================================================================== */

/* ── Tokeny designu ───────────────────────────────────────────────────────── */

:root {
  --color-surface: #f8f9ff;
  --color-surface-container-lowest: #ffffff;
  --color-surface-container-low: #eff4ff;
  --color-surface-container: #e6eeff;
  --color-surface-variant: #d5e3fd;
  --color-on-surface: #0d1c2f;
  --color-on-surface-variant: #414847;
  --color-outline-variant: #c0c8c6;
  --color-primary: #143b37;
  --color-on-primary: #ffffff;
  --color-primary-container: #2d524e;
  --color-on-primary-container: #9dc4be;
  --color-secondary: #136c3e;
  --color-on-secondary: #ffffff;
  --color-secondary-container: #a1f5b9;
  --color-on-secondary-container: #1c7243;
  --color-tertiary: #4e2c20;
  --color-tertiary-container: #684235;
  --color-on-tertiary-container: #e4b09f;
  --color-error-container: #ffdad6;
  --color-on-error-container: #93000a;
  --color-background: #f8f9ff;
  --color-surface-cream: #fdfcfb;
  --color-border-subtle: #e2e8f0;
  --shadow-sm: 0 4px 20px rgba(13, 28, 47, 0.06);
  --shadow-md: 0 10px 30px rgba(13, 28, 47, 0.14);
  /* Minimalny cel dotykowy z prototype/DESIGN.md — demografia seniorów. */
  --touch-target: 48px;
}

/* ── Reset i podstawy ─────────────────────────────────────────────────────── */

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 18px;
  color: var(--color-on-surface);
  background: var(--color-background);
}

a {
  color: var(--color-secondary);
}

a:hover {
  color: var(--color-primary);
}

button {
  font-family: inherit;
}

/* Widoczny pierścień fokusu — wymóg dostępności z DESIGN.md (3 px, kolor primary). */
:where(a, button, input, textarea, select, [tabindex]):focus-visible {
  outline: 3px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: 4px;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Ikony (sprite SVG) ───────────────────────────────────────────────────── */

.icon {
  width: 24px;
  height: 24px;
  display: inline-block;
  fill: currentColor;
  flex-shrink: 0;
  vertical-align: middle;
}

.icon--14 { width: 14px; height: 14px; }
.icon--16 { width: 16px; height: 16px; }
.icon--18 { width: 18px; height: 18px; }
.icon--20 { width: 20px; height: 20px; }
.icon--22 { width: 22px; height: 22px; }
.icon--28 { width: 28px; height: 28px; }
.icon--36 { width: 36px; height: 36px; }
.icon--44 { width: 44px; height: 44px; }
.icon--56 { width: 56px; height: 56px; }
.icon--64 { width: 64px; height: 64px; }

/* Kontener z definicjami <symbol> — obecny w DOM, niewidoczny dla oka i czytnika. */
.icon-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* ── Szkielet strony i tło ────────────────────────────────────────────────── */

.app-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.app-shell main {
  flex: 1 0 auto;
  width: 100%;
}

.page-bg {
  position: fixed;
  inset: 0;
  z-index: -2;
  background-image: url("/build/hero-bg.ef9bf64dcb.jpg");
  background-image: image-set(
    url("/build/hero-bg.3719680d80.avif") type("image/avif"),
    url("/build/hero-bg.192ebd831e.webp") type("image/webp"),
    url("/build/hero-bg.ef9bf64dcb.jpg") type("image/jpeg")
  );
  background-size: cover;
  background-position: center 45%;
  transform: scale(1.1);
  filter: blur(4px) saturate(0.9) brightness(1.15);
}

.page-fog {
  position: fixed;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    180deg,
    var(--color-background) 0%,
    rgba(248, 249, 255, 0.78) 10%,
    rgba(248, 249, 255, 0.62) 35%,
    rgba(248, 249, 255, 0.62) 65%,
    rgba(248, 249, 255, 0.82) 88%,
    var(--color-background) 100%
  );
}

/* Link „przejdź do treści” — widoczny dopiero po ustawieniu na nim fokusu. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--color-primary);
  color: #fff;
  /* 14 px zamiast 12 px domyka cel dotykowy do 48 px; odnośnik i tak jest
     widoczny wyłącznie po sfokusowaniu klawiaturą. */
  padding: 14px 20px;
  border-radius: 0 0 8px 0;
  font-weight: 600;
  text-decoration: none;
}

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

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Cele dotykowe odnośników tekstowych ──────────────────────────────────── */

/*
   prototype/DESIGN.md wymaga celów dotykowych 48 px (demografia seniorów).
   Przyciski i pola formularzy mają to wprost przez min-height, ale odnośniki
   tekstowe z canvasu są niższe — ich wysokość wynika z typografii, nie z pola
   klikania: nawigacja 27 px, „Czytaj więcej” 25 px, stopka 24 px, logo 32 px,
   „Powrót do wiadomości” 20 px, lista ostatnich wiadomości 22 px, telefon
   do zarządu 21 px. Ten ostatni jest tu najważniejszy: to odnośnik `tel:`,
   w który działkowiec celuje palcem na telefonie.

   Powiększenie samych pudełek zmieniłoby układ względem wzoru (pigułka
   aktywnej pozycji nawigacji, odstępy w stopce), dlatego rozszerzamy wyłącznie
   **pole trafienia** pseudoelementem: wygląd co do piksela ten sam, a palec
   i mysz dostają pełne 48 px. Rozsunięcie poziome (4 px) jest mniejsze niż
   najmniejszy odstęp między sąsiednimi odnośnikami, więc pola się nie nakładają
   — sprawdzone pomiarem w przeglądarce (docs/SESJE.md, sesja 7).

   Odnośniki wewnątrz akapitu (.article-content) celowo tu nie występują:
   obejmuje je wyjątek WCAG 2.5.8 dla linków w zdaniu, a rozsunięcie ich pól
   nachodziłoby na sąsiednie wiersze tekstu.
*/
.nav-btn,
.brand,
.news-more,
.back-link,
.related-link,
.footer-links a,
.footer-links button {
  position: relative;
}

.nav-btn::after,
.brand::after,
.news-more::after,
.back-link::after,
.related-link::after,
.footer-links a::after,
.footer-links button::after {
  content: '';
  position: absolute;
  /* Wysokość wprost z tokenu, wyśrodkowana względem tekstu — dzięki temu pole
     ma równo 48 px niezależnie od tego, ile mierzy sam odnośnik (21–32 px),
     i nie trzeba dobierać ujemnego marginesu osobno dla każdego przypadku. */
  top: 50%;
  transform: translateY(-50%);
  height: var(--touch-target);
  min-width: var(--touch-target);
  /* Rozsunięcie w poziomie mniejsze niż najmniejszy odstęp między sąsiednimi
     odnośnikami (stopka: 24 px), więc pola trafienia się nie nakładają. */
  left: -4px;
  right: -4px;
}

/* ── Nagłówek i nawigacja ─────────────────────────────────────────────────── */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--color-surface);
  box-shadow: var(--shadow-sm);
}

.header-inner {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 80px;
  padding: 0 16px;
  gap: 16px;
}

@media (min-width: 768px) {
  .header-inner { padding: 0 40px; }
}

/* Siatka zamiast flexa: ikona i nazwa stoją w pierwszym wierszu, dopisek
   z miejscowością w drugim, pod samą nazwą — dzięki temu ikona zostaje
   wyśrodkowana względem nazwy, a nie całego dwuwierszowego bloku. */
.brand {
  display: grid;
  grid-template-columns: auto auto;
  align-items: center;
  column-gap: 8px;
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
  text-decoration: none;
}

.brand-icon {
  color: var(--color-primary);
}

.brand-title {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 24px;
  font-weight: 700;
  line-height: 32px;
  color: var(--color-primary);
}

.brand-locality {
  grid-column: 2;
  justify-self: center;
  /* Podciągnięcie pod nazwę: jej wiersz ma 8 px światła ponad wysokość pisma. */
  margin-top: -4px;
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 14px;
  font-weight: 400;
  line-height: 16px;
  color: var(--color-primary);
}

@media (min-width: 768px) {
  .brand-title { font-size: 32px; line-height: 40px; }
  .brand-locality { font-size: 17px; line-height: 20px; margin-top: -6px; }
}

/* Próg przełączenia na nawigację poziomą: 1200 px, nie 768 px jak w canvasie.
   Siedem pozycji (w tym „Dla działkowców” i „Walne zebrania”), marka
   i odstępy 20 px (canvas ma 32 px, ale przy nich menu jest za szerokie na
   nagłówek) zajmują ~1160 px, a przewijany pasek okna zabiera kolejne 15 px —
   1200 px zostawia ~40 px odstępu między marką a menu (zmierzone; przy 1160 px
   nagłówka odstęp spada do 16 px, poniżej etykiety łamią się do dwóch linii).
   Canvas (sześć pozycji, marka i przycisk „Kontakt”) przy 768 px
   wypycha nagłówek poza ekran i strona przewija się w poziomie (wada
   wzoru, nie portu). Poniżej progu działa menu rozwijane — komponent z tego
   samego canvasu. Pozostałe punkty łamania (768/640/1024) bez zmian. */
.nav-desktop {
  display: none;
  align-items: center;
  gap: 20px;
}

@media (min-width: 1200px) {
  .nav-desktop { display: flex; }
}

.nav-btn {
  background: none;
  border: none;
  cursor: pointer;
  font-family: 'Inter', sans-serif;
  font-size: 16px;
  text-decoration: none;
  color: var(--color-on-surface-variant);
  font-weight: 500;
  /* W canvasie nawigacja to <button>, tutaj <a>. Domyślne wewnętrzne odstępy
     przycisku (1px 6px) zapisujemy wprost, żeby szerokość pozycji — a przez to
     położenie całego bloku nawigacji — została dokładnie taka jak we wzorze. */
  padding: 1px 6px 6px;
}

.nav-btn:hover {
  color: var(--color-primary);
}

/* Dawniej activeNavStyle w design canvas. */
.nav-btn--active,
.nav-btn--active:hover {
  color: var(--color-secondary);
  font-weight: 700;
  border-bottom: 2px solid var(--color-secondary);
  padding: 1px 6px 4px;
}

.btn-pill-primary {
  background: var(--color-primary);
  color: #fff;
  padding: 12px 24px;
  border-radius: 9999px;
  font-family: 'Inter', sans-serif;
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0.01em;
  border: none;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: background 0.2s, transform 0.1s;
  /* Cel dotykowy 48 px — DESIGN.md, „Touch Targets”. */
  min-height: var(--touch-target);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}

.btn-pill-primary:hover {
  background: var(--color-primary-container);
  color: #fff;
}

.btn-pill-primary:active {
  transform: scale(0.97);
}

.mobile-menu-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  color: var(--color-primary);
  padding: 10px;
  cursor: pointer;
  border-radius: 9999px;
  min-width: var(--touch-target);
  min-height: var(--touch-target);
}

@media (min-width: 1200px) {
  .mobile-menu-btn { display: none; }
}

.mobile-menu {
  background: var(--color-surface-container);
  border-top: 1px solid var(--color-border-subtle);
  box-shadow: var(--shadow-md);
  position: absolute;
  width: 100%;
  left: 0;
}

@media (min-width: 1200px) {
  .mobile-menu { display: none; }
}

/* Menu jest zwinięte, dopóki nie przełączy go public/js/nav.js. */
.mobile-menu[hidden] {
  display: none;
}

.mobile-menu-inner {
  display: flex;
  flex-direction: column;
  padding: 8px 16px 16px;
}

.mobile-nav-btn {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  border-bottom: 1px solid var(--color-border-subtle);
  padding: 14px 0;
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 22px;
  line-height: 28px;
  cursor: pointer;
  text-decoration: none;
  color: var(--color-on-surface-variant);
  font-weight: 500;
}

.mobile-nav-btn--active {
  color: var(--color-secondary);
  font-weight: 700;
}

/* Zapasowa nawigacja mobilna dla przeglądarek z wyłączonym JavaScriptem —
   ten sam wygląd co menu rozwijane, ale w normalnym przepływie dokumentu. */
.mobile-nav-fallback {
  display: flex;
  flex-direction: column;
  background: var(--color-surface-container);
  border-top: 1px solid var(--color-border-subtle);
  padding: 8px 16px 16px;
}

@media (min-width: 1200px) {
  .mobile-nav-fallback { display: none; }
}

/* ── Sekcje i typografia stron ────────────────────────────────────────────── */

.section {
  max-width: 1200px;
  margin: 0 auto;
  padding: 48px 16px;
}

@media (min-width: 768px) {
  .section { padding: 64px 40px; }
}

.page-title {
  font-family: 'Hanken Grotesk', sans-serif;
  font-weight: 700;
  letter-spacing: -0.02em;
  font-size: 32px;
  line-height: 40px;
  color: var(--color-primary);
  margin: 0 0 16px;
}

@media (min-width: 768px) {
  .page-title { font-size: 48px; line-height: 56px; }
}

.page-desc {
  font-size: 18px;
  line-height: 28px;
  color: var(--color-on-surface-variant);
  margin: 0;
  max-width: 640px;
}

.page-head {
  margin-bottom: 48px;
}

/* Nagłówek strony z panelem obok (kontakt). Od 1200 px ta sama siatka trzech
   kolumn co .board-layout, więc panel stoi dokładnie nad trzecią kartą. */
.page-head--split {
  display: grid;
  gap: 24px;
}

@media (min-width: 1200px) {
  .page-head--split {
    grid-template-columns: repeat(3, 1fr);
    gap: 32px;
    align-items: end;
  }
  .page-head--split > :first-child { grid-column: span 2; }
  /* Panel jest wyższy od tytułu z opisem — podciągnięty w górny odstęp sekcji
     (64 px) nie odsuwa kart w dół względem pozostałych stron. */
  .page-head--split > .address-card { margin-top: -56px; }
}

/* ── Wiadomości: kafle ────────────────────────────────────────────────────── */

.news-grid {
  display: grid;
  grid-template-columns: repeat(1, minmax(0, 1fr));
  gap: 24px;
}

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

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

.news-card {
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-border-subtle);
  border-radius: 12px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: var(--shadow-sm);
  transition: box-shadow 0.25s;
}

.news-card:hover {
  box-shadow: var(--shadow-md);
}

.news-banner {
  height: 120px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.news-banner .icon {
  color: #fff;
}

/* Gradienty kategorii — dawniej NEWS_CATEGORIES[x].banner. */
.news-banner--wazne,
.article-banner--wazne {
  background: linear-gradient(135deg, var(--color-primary), var(--color-primary-container));
}

.news-banner--spolecznosc,
.article-banner--spolecznosc {
  background: linear-gradient(135deg, var(--color-secondary), var(--color-primary));
}

.news-banner--porzadkowe,
.article-banner--porzadkowe {
  background: linear-gradient(135deg, var(--color-tertiary-container), var(--color-tertiary));
}

/* „Informacje dla działkowców” i „Walne zebrania” nie mają kategorii — jeden wspólny gradient dla wpisów bez zdjęcia. */
.news-banner--info,
.article-banner--info {
  background: linear-gradient(135deg, var(--color-primary-container), var(--color-secondary));
}

/* Wariant ze zdjęciem: wypełnia banner przez object-fit zamiast gradientu +
   ikony (docs/PLAN.md, „Zdjęcie w bannerze wiadomości”). */
.news-banner--photo,
.article-banner--photo {
  overflow: hidden;
}

.news-banner-img,
.article-banner-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Nakładka pod pigułką tagu — bez niej etykieta ginie na jasnym zdjęciu. */
.news-banner--photo::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.35), transparent 55%);
  z-index: 1;
}

.news-banner--photo .news-tag {
  z-index: 2;
}

.article-banner--photo {
  height: 280px;
}

@media (min-width: 768px) {
  .article-banner--photo { height: 360px; }
}

.news-tag {
  position: absolute;
  top: 12px;
  right: 12px;
  font-size: 12px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 9999px;
  display: flex;
  align-items: center;
  gap: 4px;
}

/* Barwy pigułek kategorii — dawniej NEWS_CATEGORIES[x].tagBg/tagColor. */
.news-tag--wazne {
  background: var(--color-secondary-container);
  color: var(--color-on-secondary-container);
}

.news-tag--spolecznosc {
  background: var(--color-surface-variant);
  color: var(--color-on-surface-variant);
}

.news-tag--porzadkowe {
  background: var(--color-tertiary-container);
  color: var(--color-on-tertiary-container);
}

/* Wariant w treści artykułu: pigułka płynie z tekstem zamiast leżeć na bannerze. */
.news-tag--inline {
  position: static;
  display: inline-flex;
}

.news-body {
  padding: 24px;
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: 12px;
}

.news-date {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--color-on-surface-variant);
  font-size: 13px;
  margin: 0;
}

.news-title {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 22px;
  line-height: 28px;
  font-weight: 600;
  color: var(--color-primary);
  margin: 0;
}

.news-desc {
  color: var(--color-on-surface-variant);
  font-size: 18px;
  line-height: 28px;
  margin: 0;
  flex: 1;
}

.news-more {
  align-self: flex-start;
  background: none;
  border: none;
  color: var(--color-secondary);
  font-weight: 600;
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
  padding: 4px 0;
  text-decoration: none;
}

.news-more:hover {
  color: var(--color-primary);
}

/* ── Paginacja ────────────────────────────────────────────────────────────── */

.pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 48px;
}

.page-nav-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: 2px solid var(--color-primary);
  color: var(--color-primary);
  padding: 10px 20px;
  border-radius: 8px;
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
  text-decoration: none;
  min-height: var(--touch-target);
}

.page-nav-btn:hover {
  background: var(--color-primary);
  color: #fff;
}

/* Dawniej prevBtnStyle/nextBtnStyle. */
.page-nav-btn--disabled,
.page-nav-btn--disabled:hover {
  /* 0.55 zamiast 0.4 z canvasu (audyt dostępności, sesja 7). Nieaktywny
     element interfejsu jest zwolniony z wymogu kontrastu (WCAG 2.1, 1.4.3),
     ale przy 0.4 napis „Poprzednia” praktycznie znikał — a serwis czytają
     seniorzy. 0.55 zostawia czytelny ślad, wyraźnie odróżnialny od przycisku
     aktywnego, który ma pełne wypełnienie i obramowanie. */
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: none;
  background: none;
  color: var(--color-primary);
}

.page-info {
  font-weight: 600;
  color: var(--color-on-surface-variant);
  font-size: 14px;
  min-width: 110px;
  text-align: center;
}

/* ── Artykuł ──────────────────────────────────────────────────────────────── */

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: none;
  color: var(--color-primary);
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
  padding: 0;
  margin-bottom: 24px;
  text-decoration: none;
}

.back-link:hover {
  color: var(--color-secondary);
}

.article-card {
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-border-subtle);
  border-radius: 12px;
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  max-width: 800px;
}

.article-banner {
  height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.article-banner .icon {
  color: #fff;
}

.article-body {
  padding: 32px;
}

@media (min-width: 768px) {
  .article-body { padding: 48px; }
}

.article-title {
  font-family: 'Hanken Grotesk', sans-serif;
  font-weight: 700;
  letter-spacing: -0.02em;
  font-size: 32px;
  line-height: 40px;
  color: var(--color-primary);
  margin: 16px 0 12px;
}

@media (min-width: 768px) {
  .article-title { font-size: 48px; line-height: 56px; }
}

.article-meta {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--color-on-surface-variant);
  font-size: 14px;
  margin: 0 0 32px;
}

.article-content p {
  color: var(--color-on-surface-variant);
  font-size: 18px;
  line-height: 28px;
  margin: 0 0 20px;
}

.article-content h2,
.article-content h3 {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 22px;
  line-height: 28px;
  font-weight: 600;
  color: var(--color-primary);
  margin: 32px 0 12px;
}

.article-content ul,
.article-content ol {
  margin: 0 0 20px;
  padding-left: 24px;
  color: var(--color-on-surface-variant);
  font-size: 18px;
  line-height: 28px;
}

.article-content li {
  margin-bottom: 8px;
}

.article-content li strong {
  color: var(--color-on-surface);
}

/* Blockquote wchodzi do whitelisty sanityzacji dopiero z edytorem Trix (sesja 5) — canvas go nie miał. */
.article-content blockquote {
  margin: 0 0 20px;
  padding: 4px 20px;
  border-left: 3px solid var(--color-secondary);
  color: var(--color-on-surface-variant);
  font-style: italic;
  font-size: 18px;
  line-height: 28px;
}

/* Załączniki z edytora Trix: obraz w treści i plik do pobrania — jedyne
   <figure>, jakie buduje src/lib/sanitize.js. Atrybuty width/height na <img>
   rezerwują miejsce przed załadowaniem, `height: auto` zachowuje proporcje. */
.article-content figure {
  margin: 0 0 24px;
}

.article-figure img {
  display: block;
  max-width: 100%;
  height: auto;
  border-radius: 8px;
}

.article-figure figcaption {
  margin-top: 8px;
  color: var(--color-on-surface-variant);
  font-size: 14px;
  line-height: 20px;
}

/* Samodzielny odnośnik, nie link w zdaniu — obowiązuje pełny cel dotykowy. */
.article-attachment a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: var(--touch-target);
  padding: 12px 16px;
  border: 1px solid var(--color-outline-variant);
  border-radius: 8px;
  background: var(--color-surface-container-low);
  color: var(--color-primary);
  font-size: 16px;
  line-height: 24px;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.article-attachment span {
  flex-shrink: 0;
  color: var(--color-on-surface-variant);
  font-size: 14px;
  font-weight: 400;
}

.article-contact {
  background: var(--color-surface-variant);
  border-radius: 8px;
  padding: 20px 24px;
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--color-on-surface);
  font-weight: 500;
}

.article-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 48px;
  align-items: start;
}

@media (min-width: 1024px) {
  .article-layout { grid-template-columns: 2fr 1fr; }
}

.article-aside {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

/* ── Karta kontaktu i lista powiązanych ───────────────────────────────────── */

.contact-card {
  background: var(--color-primary-container);
  color: var(--color-on-primary-container);
  padding: 32px;
  border-radius: 12px;
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.contact-card-head {
  display: flex;
  align-items: center;
  gap: 12px;
}

.contact-card-icon {
  background: rgba(255, 255, 255, 0.14);
  width: 40px;
  height: 40px;
  border-radius: 9999px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: #fff;
}

.contact-card-head h2 {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 20px;
  line-height: 26px;
  font-weight: 700;
  margin: 0;
  color: #fff;
}

.contact-card-desc {
  margin: 0;
  font-size: 15px;
  line-height: 22px;
  /* Bez opacity: 0.85 z canvasu (audyt dostępności, sesja 7). Sam kolor
     --color-on-primary-container na --color-primary-container daje 4.56:1,
     czyli ledwie ponad próg AA — przygaszenie go do 85 % zbijało kontrast do
     ~3.6:1 i było jedynym realnym błędem kontrastu w serwisie. Różnica
     w wyglądzie jest ledwie zauważalna, w czytelności — nie. */
}

.contact-card-row {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 15px;
  font-weight: 500;
}

.contact-card-btn {
  margin-top: 6px;
  width: 100%;
  background: var(--color-secondary);
  color: #fff;
  border: none;
  padding: 14px 20px;
  border-radius: 8px;
  font-weight: 600;
  font-size: 15px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  cursor: pointer;
  transition: background 0.2s;
  text-decoration: none;
  min-height: var(--touch-target);
}

.contact-card-btn:hover {
  background: var(--color-primary);
  color: #fff;
}

.related-card {
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-border-subtle);
  border-radius: 12px;
  box-shadow: var(--shadow-sm);
  padding: 28px;
}

.related-card h2 {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 20px;
  line-height: 26px;
  font-weight: 700;
  color: var(--color-primary);
  margin: 0 0 16px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--color-border-subtle);
}

.related-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.related-item {
  padding: 14px 0;
  border-bottom: 1px solid var(--color-border-subtle);
}

.related-item:first-child {
  padding-top: 0;
}

.related-item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.related-link {
  background: none;
  border: none;
  padding: 0;
  text-align: left;
  cursor: pointer;
  font-family: 'Hanken Grotesk', sans-serif;
  font-weight: 600;
  font-size: 15px;
  line-height: 22px;
  color: var(--color-primary);
  display: block;
  text-decoration: none;
}

.related-link:hover {
  color: var(--color-secondary);
}

.related-date {
  margin: 4px 0 0;
  font-size: 13px;
  color: var(--color-on-surface-variant);
}

/* ── Opłaty ───────────────────────────────────────────────────────────────── */

.fee-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 48px;
}

.fee-footer {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.fee-note {
  margin: 0;
  font-size: 18px;
  line-height: 27px;
  color: var(--color-on-surface-variant);
}

@media (min-width: 1024px) {
  .fee-layout { grid-template-columns: 2fr 1fr; }
}

.fee-card {
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-border-subtle);
  border-radius: 12px;
  box-shadow: var(--shadow-sm);
  overflow-x: auto;
}

table.fee-table {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
  /* Szerokości kolumn stałe (patrz niżej) — bez tego jeden długi termin
     rozciąga całą kolumnę „Termin płatności” kosztem stawki. */
  table-layout: fixed;
}

.fee-table thead tr {
  background: var(--color-surface-variant);
}

.fee-table th {
  padding: 16px;
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0.01em;
  border-bottom: 1px solid var(--color-outline-variant);
}

.fee-table th:nth-child(1) { width: 40%; }
.fee-table th:nth-child(2) { width: 35%; }
.fee-table th:nth-child(3) { width: 25%; }

.fee-table td {
  padding: 16px;
  border-bottom: 1px solid var(--color-outline-variant);
}

.fee-table tr:last-child td {
  border-bottom: none;
}

/* Naprzemienne tło wierszy — dawniej style="background:…" na drugim wierszu. */
.fee-table tbody tr:nth-child(even) {
  background: var(--color-surface-container-low);
}

/* Poniżej 768 px tabela przechodzi w układ kart: etykieta kolumny wchodzi
   z atrybutu data-label, nagłówek tabeli zostaje tylko dla czytników ekranu.
   Wymóg prototype/DESIGN.md („Fee Tables” → „Data Card format” na mobile) —
   canvas przewijał tabelę w poziomie, co przy 18 px tekstu jest nie do użycia. */
@media (max-width: 767px) {
  .fee-card { overflow-x: visible; }

  .fee-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .fee-table,
  .fee-table tbody,
  .fee-table tr,
  .fee-table td {
    display: block;
    width: 100%;
  }

  .fee-table tbody tr {
    padding: 8px 0;
    border-bottom: 1px solid var(--color-outline-variant);
  }

  .fee-table tbody tr:last-child {
    border-bottom: none;
  }

  .fee-table td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 8px 16px;
    border-bottom: none;
    text-align: right;
  }

  .fee-table td::before {
    content: attr(data-label);
    flex: none;
    font-size: 14px;
    font-weight: 600;
    color: var(--color-on-surface-variant);
    text-align: left;
  }
}

.fee-label {
  font-weight: 600;
  color: var(--color-primary);
}

.fee-name-wrap {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.fee-desc {
  font-size: 13px;
  font-weight: 400;
  color: var(--color-on-surface-variant);
}

.fee-due {
  color: var(--color-on-surface-variant);
}

/* Lata poprzednie — natywne <details>, bez JS. Strzałka rysowana w CSS
   (obramowanie obrócone o 45°), bo sprite ikon zawiera tylko użyte symbole. */
.fee-archive {
  display: flex;
  flex-direction: column;
  gap: 16px;
  /* Na desktopie .fee-layout ma kolumny 2fr/1fr (tabela + karta z kontem).
     Bez tego auto-placement wrzuca archiwum do wąskiej prawej kolumny —
     wymuszona lewa kolumna daje szerokość równą głównej tabeli. */
  grid-column: 1;
}

.fee-archive h2 {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 24px;
  line-height: 32px;
  font-weight: 700;
  margin: 0;
  color: var(--color-primary);
}

.fee-year > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: var(--touch-target);
  padding: 8px 16px;
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-border-subtle);
  border-radius: 12px;
  box-shadow: var(--shadow-sm);
  font-weight: 600;
  color: var(--color-primary);
  cursor: pointer;
  list-style: none;
}

.fee-year > summary::-webkit-details-marker {
  display: none;
}

.fee-year > summary::after {
  content: '';
  flex: none;
  width: 10px;
  height: 10px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform 0.15s;
}

.fee-year[open] > summary {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

.fee-year[open] > summary::after {
  transform: rotate(-135deg);
}

.fee-year > .fee-card {
  border-top: none;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

.bank-card {
  background: var(--color-primary-container);
  color: var(--color-on-primary-container);
  padding: 32px;
  border-radius: 12px;
  box-shadow: var(--shadow-md);
  /* Bez tego karta rozciąga się przez grid do wysokości tabeli opłat (align-items:
     stretch, domyślne dla grida) — wysokość ma dopasować się do własnej treści. */
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.bank-head {
  display: flex;
  align-items: center;
  gap: 12px;
}

.bank-head .icon {
  color: var(--color-secondary-container);
}

.bank-head h2 {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 24px;
  line-height: 32px;
  font-weight: 700;
  margin: 0;
  color: #fff;
}

.bank-label {
  font-size: 14px;
  font-weight: 600;
  opacity: 0.8;
  margin: 0 0 6px;
}

.bank-value {
  font-family: monospace;
  font-size: 20px;
  font-weight: 700;
  background: rgba(255, 255, 255, 0.12);
  padding: 12px;
  border-radius: 8px;
  letter-spacing: 0.02em;
  /* IBAN ma spacje między grupami cyfr — zawijanie ma trafiać tylko tam,
     nigdy w środku grupy (stąd brak word-break: break-all). */
  color: #fff;
  margin: 0;
}

.bank-title-box {
  background: rgba(255, 255, 255, 0.12);
  padding: 12px;
  border-radius: 8px;
  border-left: 4px solid var(--color-secondary-container);
}

.bank-title-box p {
  margin: 0;
  font-weight: 500;
  color: #fff;
}

.bank-hint {
  font-size: 14px;
  line-height: 20px;
  opacity: 0.9;
  margin: 12px 0 0;
}

/* ── Dokumenty ────────────────────────────────────────────────────────────── */

.doc-grid {
  display: grid;
  grid-template-columns: repeat(1, minmax(0, 1fr));
  gap: 24px;
}

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

@media (min-width: 1024px) {
  .doc-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

.doc-card {
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-border-subtle);
  border-radius: 12px;
  box-shadow: var(--shadow-sm);
  padding: 24px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 16px;
  transition: box-shadow 0.2s;
}

.doc-card:hover {
  box-shadow: var(--shadow-md);
}

.doc-icon {
  width: 80px;
  height: 80px;
  border-radius: 9999px;
  background: var(--color-surface-container);
  color: var(--color-primary);
  display: flex;
  align-items: center;
  justify-content: center;
}

.doc-title {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 22px;
  line-height: 28px;
  font-weight: 600;
  margin: 0;
  color: var(--color-on-surface);
}

.doc-desc {
  font-size: 14px;
  line-height: 20px;
  color: var(--color-on-surface-variant);
  margin: 0;
  flex: 1;
}

.doc-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 2px solid var(--color-primary);
  color: var(--color-primary);
  background: none;
  padding: 10px 16px;
  border-radius: 8px;
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
  text-decoration: none;
  min-height: var(--touch-target);
}

/* Dokument bez wgranego pliku: ten sam kształt, ale nie udaje odnośnika. */
.doc-btn--soon,
.doc-btn--soon:hover {
  border-color: var(--color-outline-variant);
  color: var(--color-on-surface-variant);
  background: none;
  cursor: default;
}

.doc-btn:hover {
  background: var(--color-primary);
  color: #fff;
}

/* ── Kontakt: zarząd, gospodarz, formularz ────────────────────────────────── */

.board-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
  /* Karty mają różną wysokość (pięć osób w zarządzie, trzy u gospodarza) — bez tego
     krótsze rozciągałyby się przez grid (align-items: stretch) i świeciły pustym miejscem. */
  align-items: start;
}

/* Świadome odstępstwo od canvasu (dwie kolumny od 1024 px), dopiero od 1200 px —
   węższa kolumna łamie imiona i nazwiska w połowie. Zarząd stoi po lewej na dwa
   rzędy, obok niego w pierwszym rzędzie gospodarz i komisja rewizyjna, a pod nimi
   formularz na szerokość obu kolumn (wypełnia miejsce pod krótszymi kartami).
   Poniżej 1200 px wszystko układa się w pionie w kolejności z szablonu. */
@media (min-width: 1200px) {
  .board-layout { grid-template-columns: repeat(3, 1fr); }
  .board-layout > :first-child { grid-row: span 2; }
  .board-layout > .contact-panel { grid-column: span 2; }
}

/* Panel z adresem — ciemny wariant karty, jak .bank-card na stronie opłat. */
.address-card {
  background: var(--color-primary-container);
  color: #fff;
  padding: 20px 24px;
  border-radius: 12px;
  box-shadow: var(--shadow-md);
  font-size: 18px;
  line-height: 28px;
}

/* Jaśniejsze pole na same dane — jak .bank-value z numerem konta. */
.address-box {
  background: rgba(255, 255, 255, 0.12);
  padding: 10px 12px;
  border-radius: 8px;
}

.address-title {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 24px;
  line-height: 32px;
  font-weight: 600;
  margin: 0 0 8px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.address-title .icon {
  color: var(--color-secondary-container);
}

.address-card address {
  font-style: normal;
  display: grid;
}

.address-nip {
  margin: 0;
}

.card-plain {
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-border-subtle);
  border-radius: 12px;
  box-shadow: var(--shadow-sm);
  padding: 32px;
}

/* Wariant dla długiego tekstu (polityka prywatności) — dawniej style="max-width:920px". */
.card-plain--prose {
  max-width: 920px;
  margin: 0 auto;
}

.card-title {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 24px;
  line-height: 32px;
  font-weight: 600;
  color: var(--color-primary);
  margin: 0 0 24px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.card-title .icon {
  color: var(--color-secondary);
}

.team-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.team-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  padding: 16px;
  background: var(--color-surface-container-low);
  border-radius: 8px;
}

.team-person {
  display: flex;
  align-items: center;
  gap: 16px;
}

.team-avatar {
  background: var(--color-primary-container);
  color: var(--color-on-primary-container);
  padding: 8px;
  border-radius: 9999px;
  display: flex;
}

.team-name {
  font-weight: 700;
  color: var(--color-primary);
  font-size: 18px;
  line-height: 28px;
  margin: 0;
}

.team-role {
  color: var(--color-on-surface-variant);
  font-weight: 500;
  margin: 4px 0 0;
}

.team-contact {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  margin-left: auto;
}

.team-plot {
  display: flex;
  align-items: center;
  gap: 4px;
  color: var(--color-on-surface-variant);
  font-size: 13px;
  font-weight: 500;
  margin: 0;
}

/* Wabiki w numerach telefonu (src/lib/phone.js). Cyfry-śmieci wplecione między
   grupy prawdziwego numeru, żeby scraper czytający surowy HTML nie wyjął z niego
   niczego użytecznego. `display: none` pomijają zarówno czytniki ekranu, jak
   i schowek przeglądarki — człowiek widzi, słyszy i kopiuje sam numer, także bez
   JavaScriptu. */
.tel-x {
  display: none;
}

/* Numer to jedna całość — złamany między grupami cyfr („797 / 170 / 975”) jest
   trudniejszy do przeczytania i do przepisania na klawiaturę telefonu. */
.tel-guard {
  white-space: nowrap;
}

.team-phone {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--color-primary);
  font-size: 16px;
  line-height: 24px;
  font-weight: 600;
}

.form-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
}

@media (min-width: 768px) {
  .form-grid-2 { grid-template-columns: 1fr 1fr; }
}

.field label {
  display: block;
  font-weight: 600;
  font-size: 14px;
  color: var(--color-on-surface);
  margin-bottom: 8px;
}

.field input,
.field textarea {
  width: 100%;
  background: var(--color-background);
  border: 1px solid var(--color-outline-variant);
  border-radius: 8px;
  padding: 12px 16px;
  color: var(--color-on-surface);
  font-family: inherit;
  font-size: 15px;
  min-height: var(--touch-target);
}

.field textarea {
  min-height: 120px;
}

.field input:focus,
.field textarea:focus {
  outline: 3px solid var(--color-primary);
  border-color: var(--color-primary);
}

/* Odstępy między polami formularza — dawniej style="margin-bottom:24px". */
.contact-form > .field,
.contact-form > .form-grid {
  margin-bottom: 24px;
}

.submit-btn {
  width: 100%;
  background: var(--color-secondary);
  color: #fff;
  padding: 16px 24px;
  border-radius: 8px;
  font-weight: 600;
  font-size: 18px;
  border: none;
  cursor: pointer;
  box-shadow: var(--shadow-md);
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 8px;
  min-height: var(--touch-target);
}

/* Formularz rusza w sesji 6; do tego czasu przycisk jest wyłączony. */
.submit-btn:disabled,
.submit-btn:disabled:hover {
  background: var(--color-outline-variant);
  color: var(--color-on-surface-variant);
  box-shadow: none;
  cursor: not-allowed;
}

.submit-btn:hover {
  background: var(--color-primary);
}

/* Honeypot captchy (docs/PLAN.md, „Captcha”): pole tekstowe zwykłe (nie
   type="hidden"), niewidoczne dla ludzi i czytników ekranu, ale obecne w DOM —
   proste boty czytają znaczniki wprost i pomijają tylko oczywisty hidden. */
.hp-trap {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  left: -9999px;
}

.notice-box--error {
  background: var(--color-error-container);
  color: var(--color-on-error-container);
}

.notice-box--error .icon {
  color: var(--color-on-error-container);
}

/* public/js/captcha.js przełącza te trzy elementy atrybutem hidden zamiast
   dopisywania/usuwania węzłów DOM (uniknięcie problemu z ikonami dobieranymi
   per żądanie — patrz komentarz w partials/contact-form.eta). Jawne [hidden]
   jest konieczne: bez niego specyficzność wiąże się z domyślnym
   [hidden]{display:none} przeglądarki, a o remisie rozstrzyga kolejność w
   arkuszu — dokładnie ten sam błąd co .icon-picker-panel w sesji 5. */
.notice-box[hidden],
.sent-banner[hidden],
.submit-btn[hidden] {
  display: none;
}

.sent-banner {
  width: 100%;
  background: var(--color-secondary-container);
  color: var(--color-on-secondary-container);
  padding: 16px 24px;
  border-radius: 8px;
  font-weight: 600;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 8px;
}

/* ── Ogłoszenia ───────────────────────────────────────────────────────────── */

.board-head-row {
  display: flex;
  flex-direction: column;
  gap: 24px;
  margin-bottom: 48px;
}

@media (min-width: 768px) {
  .board-head-row {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
  }
}

.notice-box {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  background: var(--color-surface-variant);
  color: var(--color-on-surface-variant);
  padding: 16px 20px;
  border-radius: 8px;
  margin-bottom: 32px;
}

.notice-box .icon {
  color: var(--color-primary);
}

.notice-box p {
  margin: 0;
  font-size: 15px;
  line-height: 22px;
}

.ogl-grid {
  display: grid;
  grid-template-columns: repeat(1, minmax(0, 1fr));
  gap: 24px;
}

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

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

.ogl-card {
  background: var(--color-surface-cream);
  padding: 24px;
  border-radius: 8px;
  border-left: 4px solid var(--color-secondary);
  box-shadow: var(--shadow-sm);
  position: relative;
  overflow: hidden;
}

.ogl-watermark {
  position: absolute;
  top: 0;
  right: 0;
  padding: 16px;
  opacity: 0.08;
}

.ogl-tag {
  display: inline-block;
  font-size: 12px;
  font-weight: 700;
  padding: 4px 10px;
  border-radius: 6px;
  margin-bottom: 12px;
}

/* Barwy pigułek ogłoszeń — dawniej AD_COLORS. Prefiks klas zmieniony z `ad-`
   na `ogl-`, bo blokery reklam (Opera, uBlock/EasyList) kasują generycznie
   elementy z klasami zaczynającymi się od "ad-". */
.ogl-tag--odstapie {
  background: var(--color-error-container);
  color: var(--color-on-error-container);
}

.ogl-tag--sprzedam {
  background: var(--color-tertiary-container);
  color: var(--color-on-tertiary-container);
}

.ogl-tag--oddam {
  background: var(--color-secondary-container);
  color: var(--color-on-secondary-container);
}

.ogl-tag--inne {
  background: var(--color-surface-variant);
  color: var(--color-on-surface-variant);
}

.ogl-title {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 22px;
  font-weight: 600;
  color: var(--color-on-surface);
  margin: 0 0 12px;
}

.ogl-desc {
  color: var(--color-on-surface-variant);
  margin: 0 0 16px;
}

.ogl-phone {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  color: var(--color-primary);
  background: rgba(20, 59, 55, 0.06);
  padding: 8px;
  border-radius: 6px;
}

/* ── Stopka ───────────────────────────────────────────────────────────────── */

.site-footer {
  background: var(--color-surface-container-lowest);
  border-top: 1px solid var(--color-outline-variant);
}

.footer-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 48px 16px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  text-align: center;
}

@media (min-width: 768px) {
  .footer-inner {
    padding: 48px 40px;
    flex-direction: row;
    justify-content: space-between;
    text-align: left;
  }
}

.footer-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

@media (min-width: 768px) {
  .footer-brand { align-items: flex-start; }
}

.footer-brand-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: 'Hanken Grotesk', sans-serif;
  color: var(--color-primary);
}

.footer-copy {
  font-size: 16px;
  line-height: 24px;
  color: var(--color-on-surface);
  margin: 0;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 24px;
}

.footer-links a,
.footer-links button {
  font-size: 16px;
  line-height: 24px;
  color: var(--color-on-surface-variant);
  background: none;
  border: none;
  cursor: pointer;
  font-family: inherit;
  padding: 0;
  text-decoration: none;
}

.footer-links a:hover,
.footer-links button:hover {
  text-decoration: underline;
  color: var(--color-primary);
}

/* ── Strony zastępcze i błędy ─────────────────────────────────────────────── */

/* Widok tymczasowy dla tras, których treść powstaje w kolejnych sesjach. */
.placeholder-note {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  background: var(--color-surface-container-lowest);
  border: 1px dashed var(--color-outline-variant);
  color: var(--color-on-surface-variant);
  padding: 24px;
  border-radius: 12px;
}

.placeholder-note .icon {
  color: var(--color-primary);
}

.placeholder-note p {
  margin: 0;
  font-size: 16px;
  line-height: 24px;
}

.error-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 32px;
}

/* ── Panel administracyjny (sesja 4) ──────────────────────────────────────
   Samodzielny layout bez publicznej nawigacji — src/lib/render.js#renderAdminPage.
   Karta i pola reużywają .field/.submit-btn z formularza kontaktowego. */

.admin-body {
  background: var(--color-background);
}

/* Tło ciemnozielone jest tylko tłem karty logowania/2FA — pulpit i listy
   (.admin-shell--wide, sesja 5) dostają zwykłe jasne tło strony. */
.admin-shell {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: var(--color-primary);
}

.admin-card {
  width: 100%;
  max-width: 420px;
  background: var(--color-surface-container-lowest);
  border-radius: 16px;
  box-shadow: var(--shadow-md);
  padding: 40px 32px;
}

.admin-card--wide {
  max-width: 560px;
}

.admin-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--color-primary);
  margin-bottom: 32px;
}

.admin-brand .icon {
  color: var(--color-secondary);
}

.admin-title {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 24px;
  line-height: 32px;
  font-weight: 600;
  margin: 0;
}

.admin-error {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: var(--color-error-container);
  color: var(--color-on-error-container);
  border-radius: 8px;
  padding: 12px 16px;
  margin-bottom: 24px;
}

.admin-error .icon {
  color: var(--color-on-error-container);
  flex-shrink: 0;
}

.admin-error p {
  margin: 0;
  font-size: 15px;
}

.admin-form > .field {
  margin-bottom: 24px;
}

/* ── Panel administracyjny: pasek nawigacji i szeroki układ (sesja 5) ─────── */

.admin-shell--wide {
  align-items: flex-start;
  justify-content: flex-start;
  flex-direction: column;
  padding: 0;
  background: var(--color-background);
}

.admin-topbar {
  width: 100%;
  background: var(--color-primary);
  color: var(--color-on-primary);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 16px 24px;
  padding: 16px 24px;
}

.admin-topbar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--color-on-primary);
  font-family: 'Hanken Grotesk', sans-serif;
  font-weight: 600;
  font-size: 18px;
  text-decoration: none;
  margin-right: auto;
}

.admin-topbar-brand .icon {
  color: var(--color-secondary-container);
}

.admin-topbar-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.admin-nav-link {
  color: var(--color-on-primary);
  text-decoration: none;
  font-size: 15px;
  font-weight: 500;
  padding: 10px 14px;
  border-radius: 8px;
  min-height: var(--touch-target);
  display: flex;
  align-items: center;
}

.admin-nav-link:hover {
  background: rgba(255, 255, 255, 0.12);
  color: var(--color-on-primary);
}

.admin-nav-link--active {
  background: var(--color-secondary);
  color: var(--color-on-secondary);
}

.admin-logout-form {
  margin: 0;
}

.admin-logout-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.4);
  color: var(--color-on-primary);
  border-radius: 8px;
  padding: 10px 16px;
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
  min-height: var(--touch-target);
}

.admin-logout-btn:hover {
  background: rgba(255, 255, 255, 0.12);
}

.admin-page {
  width: 100%;
  max-width: 960px;
  margin: 0 auto;
  padding: 32px 24px 64px;
}

.admin-page--narrow {
  max-width: 520px;
}

.admin-page--form {
  max-width: 760px;
}

.admin-page-title {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 28px;
  line-height: 36px;
  font-weight: 600;
  color: var(--color-primary);
  margin: 0 0 24px;
}

.admin-section-title {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 20px;
  font-weight: 600;
  color: var(--color-primary);
  margin: 40px 0 16px;
}

.admin-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 24px;
}

.admin-toolbar .admin-page-title {
  margin: 0;
}

.admin-toolbar-links {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.admin-btn-inline {
  width: auto;
  text-decoration: none;
  display: inline-flex;
}

.admin-btn-secondary {
  background: var(--color-primary-container);
}

.admin-btn-secondary:hover {
  background: var(--color-primary);
}

/* ── Pulpit: liczniki i aktywność ──────────────────────────────────────────── */

.admin-stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 20px;
  margin-bottom: 32px;
}

.admin-stat-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  background: var(--color-surface-container-lowest);
  border-radius: 12px;
  box-shadow: var(--shadow-sm);
  padding: 20px 24px;
  text-decoration: none;
  color: inherit;
}

a.admin-stat-card:hover {
  box-shadow: var(--shadow-md);
}

.admin-stat-number {
  font-family: 'Hanken Grotesk', sans-serif;
  font-size: 36px;
  font-weight: 700;
  color: var(--color-primary);
}

.admin-stat-label {
  font-weight: 600;
  color: var(--color-on-surface);
}

.admin-stat-sub {
  font-size: 13px;
  color: var(--color-on-surface-variant);
}

.admin-quick-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 16px;
}

.admin-empty {
  color: var(--color-on-surface-variant);
  font-size: 15px;
}

.admin-activity-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.admin-activity-item {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px;
  padding: 12px 0;
  border-bottom: 1px solid var(--color-border-subtle);
  font-size: 14px;
}

.admin-activity-action {
  font-weight: 600;
  color: var(--color-on-surface);
}

.admin-activity-meta {
  color: var(--color-on-surface-variant);
}

/* ── Listy: wiadomości i ogłoszenia ────────────────────────────────────────── */

.admin-filter-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 24px;
}

.admin-filter-tab {
  text-decoration: none;
  color: var(--color-on-surface-variant);
  background: var(--color-surface-container-low);
  border-radius: 999px;
  padding: 8px 16px;
  font-size: 14px;
  font-weight: 600;
}

.admin-filter-tab--active {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.admin-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.admin-list-row {
  background: var(--color-surface-container-lowest);
  border-radius: 12px;
  box-shadow: var(--shadow-sm);
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.admin-list-main {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

.admin-list-title {
  font-weight: 600;
  font-size: 17px;
  color: var(--color-on-surface);
}

.admin-list-icon {
  color: var(--color-on-surface-variant);
}

.admin-list-meta {
  color: var(--color-on-surface-variant);
  font-size: 14px;
}

.admin-list-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-top: 4px;
}

.admin-list-actions form {
  margin: 0;
}

.admin-action-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: none;
  color: var(--color-secondary);
  font-weight: 600;
  font-size: 14px;
  text-decoration: none;
  cursor: pointer;
  padding: 8px 0;
  min-height: var(--touch-target);
}

.admin-action-link:hover {
  color: var(--color-primary);
}

.admin-action-link--danger {
  color: var(--color-on-error-container);
}

.admin-action-link--danger:hover {
  color: #6a0007;
}

.admin-status-pill {
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  padding: 4px 12px;
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.admin-status-pill--draft {
  background: var(--color-surface-variant);
  color: var(--color-on-surface-variant);
}

.admin-status-pill--published {
  background: var(--color-secondary-container);
  color: var(--color-on-secondary-container);
}

.admin-status-pill--expired {
  background: var(--color-error-container);
  color: var(--color-on-error-container);
}

/* ── Formularze wiadomości i ogłoszeń ──────────────────────────────────────── */

.admin-error ul {
  margin: 0;
  padding-left: 20px;
}

.admin-error li {
  margin-bottom: 4px;
}

.admin-image-field {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.admin-image-preview {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  background: var(--color-surface-container-low);
  border-radius: 8px;
  padding: 12px;
}

.admin-image-preview img {
  border-radius: 6px;
  object-fit: cover;
  display: block;
}

.admin-checkbox-label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--color-on-surface-variant);
}

/* ── Wybór ikony z podglądem (admin/partials/icon-picker.eta) ─────────────── */

.icon-picker {
  position: relative;
}

.icon-picker-toggle {
  width: 100%;
  min-height: var(--touch-target);
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--color-background);
  border: 1px solid var(--color-outline-variant);
  border-radius: 8px;
  padding: 8px 16px;
  font-family: inherit;
  font-size: 15px;
  color: var(--color-on-surface);
  cursor: pointer;
  text-align: left;
}

.icon-picker-toggle:focus {
  outline: 3px solid var(--color-primary);
  border-color: var(--color-primary);
}

.icon-picker-toggle::after {
  content: '';
  margin-left: auto;
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--color-on-surface-variant);
  border-bottom: 2px solid var(--color-on-surface-variant);
  transform: rotate(45deg);
  flex-shrink: 0;
}

.icon-picker-current {
  display: flex;
  color: var(--color-secondary);
  flex-shrink: 0;
}

.icon-picker-current-label {
  color: var(--color-on-surface-variant);
  font-size: 13px;
}

.icon-picker-panel {
  position: absolute;
  z-index: 20;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  max-height: 288px;
  overflow-y: auto;
  background: var(--color-surface-container-lowest);
  border: 1px solid var(--color-outline-variant);
  border-radius: 8px;
  box-shadow: var(--shadow-md);
  padding: 8px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 4px;
}

/* `display: grid` w regule wyżej ma taką samą specyficzność jak domyślne
   [hidden] { display: none } z arkusza przeglądarki, więc bez tego panel
   zostawałby widoczny mimo atrybutu hidden ustawianego przez JS. */
.icon-picker-panel[hidden] {
  display: none;
}

.icon-picker-option {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: var(--touch-target);
  padding: 10px 6px;
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
  cursor: pointer;
  color: var(--color-on-surface);
}

.icon-picker-option:hover {
  background: var(--color-surface-container-low);
}

.icon-picker-option:focus {
  outline: 3px solid var(--color-primary);
}

.icon-picker-option--active {
  border-color: var(--color-secondary);
  background: var(--color-secondary-container);
}

.icon-picker-option-label {
  font-size: 11px;
  line-height: 14px;
  color: var(--color-on-surface-variant);
  text-align: center;
  word-break: break-word;
}

/* Trix — nadpisanie minimalne, żeby edytor pasował do reszty systemu designu.
   Selektory na nazwach elementów niestandardowych (nie klasach) — tak Trix
   sam się strukturyzuje, my tylko dostrajamy wygląd. */
.admin-editor {
  min-height: 220px;
  border: 1px solid var(--color-outline-variant);
  border-top: none;
  border-radius: 0 0 8px 8px;
  padding: 16px;
  font-size: 16px;
  line-height: 26px;
  font-family: 'Inter', system-ui, sans-serif;
  color: var(--color-on-surface);
}

trix-toolbar {
  display: block;
  border: 1px solid var(--color-outline-variant);
  border-bottom: none;
  border-radius: 8px 8px 0 0;
  background: var(--color-surface-container-low);
  padding: 8px;
}

trix-toolbar .trix-button {
  min-height: 40px;
}

/* Komunikat uploadu załącznika (public/js/admin-editor.js). Celowo bez
   własnego `display` — reguła wygrałaby wtedy z atrybutem hidden. */
.admin-editor-error {
  margin: 8px 0 0;
  padding: 10px 14px;
  border-radius: 8px;
  background: var(--color-error-container);
  color: var(--color-on-error-container);
  font-size: 15px;
}
