/* Wspólne komponenty wyniku (landing + analyze + report + analyze_lead). Scope .rd-results. */

/* ── Design-tokeny (te same wartości co .lp-design w landing-redesign.css /
   :root w redesign.css). Zdefiniowane lokalnie na .rd-results, bo widoki
   wewnętrzne (analyze.html/report.html extends base.html) ładują tylko
   style.css, który NIE ma tokenów --color-*. Dzięki temu przeniesione reguły
   var(--color-*) renderują się identycznie na wszystkich 4 widokach. ── */
.rd-results {
  --color-primary: #5a2fa8;
  --color-primary-dark: #3a1d72;
  --color-accent-text: #7c4db5;
  --color-accent: #e30e7d;
  --color-border: #e2e0e8;
  --color-text: #1a1a2e;
  --color-text-muted: #6b6b80;
  --color-bg: #ffffff;
  --color-bg-light: #f7f5ff;
  --color-bg-page: #f0edf8;
  --color-success: #22c55e;
  --color-success-mid: #16a34a;
  --color-error: #dc2626;
  --heading: "Montserrat", system-ui, sans-serif;
}

/* ── SEASON-CARDS 1:1 z referencji (Task 9D, komp. 4). Karty w grid-kontenerze
   .scan-items (wspólna ramka na <li>, BEZ ramki per karta). Nagłówki <h3> Okna
   wzrostowe/spadkowe. Autorskie reguły wg tokenów. ── */
.rd-results .scan-items {
  display: grid; grid-template-columns: repeat(3, 1fr);
  margin: 10px 0 0; padding: 0; overflow: hidden;
  border: 1px solid var(--color-border); border-radius: 5px;
  background: var(--color-bg); list-style: none;
}
.rd-results .scan-items.columns-2 { grid-template-columns: repeat(2, 1fr); }
.rd-results .scan-items li { padding: 12px; border-right: 1px solid var(--color-border); }
.rd-results .scan-items li:last-child { border-right: unset; }
@media (max-width: 640px) {
  .rd-results .scan-items,
  .rd-results .scan-items.columns-2 { grid-template-columns: 1fr; }
  .rd-results .scan-items li { border-right: unset; border-bottom: 1px solid var(--color-border); }
  .rd-results .scan-items li:last-child { border-bottom: unset; }
}
.rd-results .season-card {
  display: flex; flex-direction: column; gap: 10px;
  height: 100%; box-sizing: border-box;
}
.rd-results .season-card__header { display: flex; align-items: center; gap: 8px; }
.rd-results .season-card__header h4 {
  flex: 1; min-width: 0; margin: 0;
  font-family: var(--heading); font-size: 12px; font-weight: 600;
  color: var(--color-text);
}
.rd-results .season-card__up-badge,
.rd-results .season-card__down-badge {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 3px 8px 3px 6px; border-radius: 20px; flex-shrink: 0;
  font-weight: 700; letter-spacing: .8px;
}
.rd-results .season-card__up-badge svg,
.rd-results .season-card__down-badge svg { width: 10px; height: 10px; }
.rd-results .season-card__up-badge { background: #e2f5ec; color: var(--color-success); font-size: 12px; }
.rd-results .season-card__down-badge { background: #fde5eb; color: #dc2626; font-size: 8px; }
.rd-results .season-card__pct { font-size: 14px; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; flex-shrink: 0; }
.rd-results .season-card__pct--green { color: var(--color-success); }
.rd-results .season-card__pct--red { color: #dc2626; }
.rd-results .season-card__rows { display: flex; flex-direction: column; gap: 6px; }
.rd-results .season-card__row {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 14px; color: var(--color-text); font-weight: 500;
}
.rd-results .season-card__row-label em { font-style: normal; color: var(--color-text-muted); }
.rd-results .season-card__footer {
  display: flex; align-items: center; gap: 5px;
  margin-top: auto; padding-top: 8px;
  border-top: 1px solid var(--color-border);
  font-size: 12px; font-weight: 500; color: var(--color-text-muted);
}
.rd-results .season-card__footer svg { width: 12px; height: 12px; flex-shrink: 0; color: var(--color-primary); }

/* ── PODSUMOWANIE — kafelki seasonality-stat (Task 9B, port 1:1 z referencji) ── */

/* Kontener #heroSummary nosi jeszcze klasę .hero-summary (z style.css = ciemny
   gradient + padding 36px). renderHeroSummary generuje teraz jasne kafelki, więc
   neutralizujemy starą oprawę: przezroczysty wrapper bez ramki/cienia/paddingu.
   (style.css nietknięty — override scope'owany pod .rd-results, zasada #3.) */
.rd-results .hero-summary {
  background: none;
  animation: none;
  box-shadow: none;
  border-radius: 0;
  padding: 0;
  color: inherit;
}
.rd-results .hero-summary::before { content: none; }

.rd-results .seasonality-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-top: 16px;
}
@media (max-width: 640px) { .rd-results .seasonality-stats { grid-template-columns: 1fr; } }
.rd-results .seasonality-stat {
  min-width: 0;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  position: relative;
  overflow: hidden;
}
.rd-results .seasonality-stat--purple { --stat-color: var(--color-primary); --stat-bg: #f0edf8; }
.rd-results .seasonality-stat--green  { --stat-color: var(--color-success); --stat-bg: #e2f5ec; }
.rd-results .seasonality-stat--red    { --stat-color: #dc2626;              --stat-bg: #fde5eb; }
.rd-results .seasonality-stat__top {
  display: flex; align-items: center; gap: 10px; margin-bottom: 10px;
}
.rd-results .seasonality-stat__icon-wrap {
  width: 34px; height: 34px; border-radius: 5px; padding: 10px;
  background: var(--stat-bg); color: var(--stat-color);
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.rd-results .seasonality-stat__icon-wrap svg { width: 100%; height: 100%; }
/* Czytelność (Task 9B): ref używa 8-9px etykiet — za małe/jasne. Podbijamy
   rozmiar i kontrast, budujemy wyraźną hierarchię: liczba główna = największa
   + bold + kolor statu; etykiety = czytelne, nie krzykliwe. */
.rd-results .seasonality-stat__label {
  font-size: 11px; font-weight: 700; letter-spacing: 0.8px;
  text-transform: uppercase; color: var(--stat-color);
}
.rd-results .seasonality-stat__title {
  margin: 0; font-family: var(--heading);
  font-size: 15px; font-weight: 600; color: var(--color-text); line-height: 1.4;
}
.rd-results .seasonality-stat__divider {
  border: none; border-top: 1px solid var(--color-border); margin: 10px 0;
}
.rd-results .seasonality-stat__index { display: flex; align-items: baseline; gap: 7px; }
.rd-results .seasonality-stat__index span { font-size: 12px; color: var(--color-text-muted); font-weight: 600; }
.rd-results .seasonality-stat__index strong { font-family: var(--heading); font-size: 26px; font-weight: 700; color: var(--stat-color); line-height: 1; }
.rd-results .seasonality-stat__number {
  margin: 0 0 2px; font-family: var(--heading);
  font-size: 26px; font-weight: 700; color: var(--stat-color); line-height: 1.1;
}
/* Kolejność: liczba (główna) → tytuł (miesiąc/etykieta) → sub (jednostka/kontekst).
   __title między liczbą a sub dostaje lekki margines dolny dla oddechu. */
.rd-results .seasonality-stat__number + .seasonality-stat__title { margin-bottom: 4px; }
.rd-results .seasonality-stat__sub {
  font-size: 12px; font-weight: 500; color: var(--color-text-muted); line-height: 1.45; margin: 0;
}

/* .card-light — czysty brand border zamiast gradient-border #632483,
   spójny z .feat-card-light / .season-card */
/* Padding numerowanych sekcji wyniku: na landingu reset `.lp-design *
   { padding:0 }` (landing-redesign.css l.37) zerował padding base .card-light
   (style.css l.207 = 28px), bo ma tę samą specyficzność (0,1,0) i ładuje się
   później → treść/badge .rd-num/wykres/heatmapa przyklejały się do krawędzi.
   Ustawiamy padding jawnie na .rd-results .card-light (0,2,0) — wygrywa kaskadę
   na WSZYSTKICH 4 widokach (landing + analyze + report + analyze_lead), spójnie
   z brandowym 28px. Wykres (#volumeChart), heatmapa (.lp-heatmap/.kh-table) i
   tabela siedzą wewnątrz paddingu (brak negatywnych marginesów/full-width). */
.rd-results .card-light {
  padding: 28px;
  border: 1px solid var(--color-border);
  border-radius: 10px;
  box-shadow: 0 1px 2px rgba(43, 22, 88, 0.05);
}
@media (max-width: 767px) {
  .rd-results .card-light { padding: 20px; }
}
.rd-results .card-light::before { display: none; }
.rd-results .card-light:hover {
  box-shadow: 0 8px 24px rgba(43, 22, 88, 0.10);
  transform: none;
}
.rd-results .card-light h4 {
  font-family: var(--heading);
  color: var(--color-text);
}

/* Bogata heatmapa per-fraza (widoki wewnętrzne) — kh-* div-grid */
/* analyze.js:renderHeatmap() generuje .kh-table/.kh-row/.kh-cell i wstrzykuje
   tło komórek inline (monochrom fiolet rgba(90,47,168,α) przez khColor()).
   Tu NIE ustawiamy background komórek — tylko layout/typografię. Wartości
   literalne równolegle z tokenami, by działało także bez plików z tokenami
   (analyze.html ma tylko style.css). */
.rd-results .kh-table {
  margin-top: 20px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  /* Nigdy nie ściskaj poniżej czytelności: 100px label + 12 kolumn × min-width.
     Gdy szerokość > kontener, wrapper #heatmapContainer (.overflow-x-auto) scrolluje
     CAŁĄ tabelę (nagłówek + dane razem — wspólny rodzic .kh-table), nie wiersze osobno. */
  min-width: max-content;
}
.rd-results .kh-row {
  display: flex;
  align-items: stretch;
  gap: 3px;
}
.rd-results .kh-row--header {
  margin-bottom: 4px;
  align-items: center;
}
.rd-results .kh-label {
  width: 100px;
  min-width: 100px;
  font-size: 10px;
  font-weight: 500;
  color: #1a1a2e;
  padding-right: 8px;
  display: flex;
  align-items: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rd-results .kh-row--grupa .kh-label {
  font-weight: 700;
}
.rd-results .kh-label--cpc {
  display: flex;
  align-items: center;
  gap: 4px;
  color: #6b6b80;
  font-weight: 500;
}
/* Wyrównanie kolumn: nagłówek miesięcy i komórki danych to OSOBNE wiersze flex.
   Żeby kolumny się pokrywały, KAŻDY miesiąc (nagłówek + dane) ma identyczny
   `flex:1 1 0` + wspólny `min-width`. Bez `min-width:0` flex item ma min-width:auto
   = nie zwęża się poniżej swojej treści (komórka z dużą liczbą + nowrap szersza niż
   „STY") → kolumny się rozjeżdżają. Wspólny min-width wymusza równą siatkę we
   wszystkich wierszach; nadwyżkę szerokości przejmuje scroll wrappera. */
.rd-results .kh-month,
.rd-results .kh-cell {
  flex: 1 1 0;
  min-width: 44px;
}
.rd-results .kh-month {
  font-size: 8px;
  font-weight: 600;
  letter-spacing: .8px;
  text-transform: uppercase;
  color: #6b6b80;
  text-align: center;
}
.rd-results .kh-cell {
  /* flex:1 1 0 + min-width — wspólne z .kh-month (wyrównanie kolumn, reguła wyżej) */
  min-height: 32px;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 9px;
  font-weight: 600;
  font-family: "Montserrat", system-ui, sans-serif;
  font-variant-numeric: tabular-nums;
  cursor: default;
  transition: filter .15s;
  white-space: nowrap;
}
.rd-results .kh-cell:hover {
  filter: brightness(.9);
}
.rd-results .kh-row--grupa .kh-cell {
  min-height: 38px;
  font-size: 10px;
  font-weight: 700;
}
.rd-results .kh-cell--cpc {
  background: transparent;
  color: #6b6b80;
  font-weight: 400;
  font-size: 9px;
}
.rd-results .kh-legend {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
}
.rd-results .kh-legend-label {
  font-size: 9px;
  font-weight: 500;
  color: #6b6b80;
  white-space: nowrap;
}
.rd-results .kh-legend-scale {
  display: flex;
  gap: 4px;
}
.rd-results .kh-legend-cell {
  width: 22px;
  height: 22px;
  border-radius: 4px;
}

/* Neutralizacja legacy dekoracji #interpretationSection ze style.css (l.337-349):
   ::after to absolutnie pozycjonowany pasek (left:0; top:0; bottom:0; width:4px,
   gradient fiolet). #interpretationSection ani .rd-results .article NIE mają
   position:relative, więc ::after kotwiczy się do initial containing block →
   pełnowysokościowy pasek przy lewej krawędzi viewportu (x=0). Referencja nie ma
   takiego paska na .article (ref.css :275 — czysta karta). Gasimy oba pseudo
   pod .rd-results, by sekcja renderowała się 1:1 z referencją. */
.rd-results #interpretationSection::after,
.rd-results #interpretationSection::before { content: none; }

/* ── INTERPRETACJA — panele .scan-panel (Task 9D, komp. 3, port 1:1 z ref) ──
   1 akapit = 1 panel. Wariant domyślny zielony (success-light), .purple = fiolet.
   Ikona inline (biała na tle .scan-summary > svg). Treść w .scan-summary p. */
.rd-results .scan-panel {
  display: flex; gap: 25px;
  background-color: #e2f5ec;
  padding: 20px; border-radius: 6px;
  border: 1px solid var(--color-border);
  margin: 10px 0 0;
}
.rd-results .scan-panel.purple { background-color: #f0edf8; color: var(--color-primary); }
.rd-results .scan-panel.tags > div:first-child { width: 100%; }
.rd-results .scan-panel.tags .scan-summary { display: flex; gap: 10px; }
.rd-results .scan-summary { align-items: center; }
.rd-results .scan-summary > svg {
  background-color: var(--color-success);
  padding: 10px; border-radius: 6px;
  width: 44px; height: 44px; aspect-ratio: 1; flex-shrink: 0;
}
.rd-results .scan-panel.purple .scan-summary > svg { background-color: var(--color-primary); }
.rd-results .scan-summary > div { min-width: 0; }
.rd-results .scan-summary p {
  font-size: 14px; margin: 0; color: var(--color-text); line-height: 1.55;
}
.rd-results .scan-panel.purple .scan-summary p { color: var(--color-text); }

/* ── LAYOUT — numerowane nagłówki sekcji (Task 9D, komp. 5, wersja lekka) ──
   CSS-counter na .rd-results; nagłówki opt-in przez klasę .rd-num dostają
   auto-numer 01,02… w fioletowej plakietce (decimal-leading-zero). NIE pełny
   print-dokument 300mm — sekcje zostają w istniejących .card-light. */
.rd-results { counter-reset: rd-section; }
.rd-results .rd-num {
  display: flex; align-items: center; gap: 10px;
  counter-increment: rd-section;
  font-family: var(--heading);
}
.rd-results .rd-num::before {
  content: counter(rd-section, decimal-leading-zero);
  min-width: 26px; max-width: 26px; min-height: 26px; max-height: 26px;
  display: flex; align-items: center; justify-content: center;
  padding: 4px 6px; border-radius: 4px;
  background: #f0edf8; color: var(--color-primary);
  font-size: 13px; font-weight: 600; line-height: 1; text-align: center;
  flex-shrink: 0;
}
/* Sub-nagłówki h3 (Okna wzrostowe/spadkowe w #budgetSummarySection, Analiza CPC
   w #heatmapSection) — purple Montserrat + kreska, 1:1 z referencją (.section h3,
   ref.css :761-783). BEZ licznika .rd-num: liczy się tylko 7 sekcji h2 (01-07). */
.rd-results .season-cards h3,
.rd-results #seasonCards h3,
.rd-results .article h3 {
  display: flex; align-items: center; gap: 10px; margin: 0 0 14px;
  color: var(--color-primary); font-family: var(--heading);
  font-size: 16px; font-weight: 500; letter-spacing: .4px; line-height: 1.2;
}
.rd-results .season-cards h3::after,
.rd-results #seasonCards h3::after,
.rd-results .article h3::after { content: ""; flex: 1; height: 1px; background: var(--color-border); }

/* ── ARTICLE — kanoniczny kontener sekcji wyniku (port z referencji .article,
   ref.css :275-289). Wspólny partial _partials/report_sections.html owija każdą
   sekcję w <article class="article">. Tokeny var(--color-*) zamiast ref
   --border-subtle/--bg-surface (mapowanie 1:1). ── */
.rd-results .article {
  padding: 28px;
  background-color: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 10px;
  margin: 20px 0;
  box-shadow: 0 1px 2px rgba(43, 22, 88, 0.05);
}
@media (max-width: 767px) { .rd-results .article { padding: 20px; } }
.rd-results .article > :last-child { margin-bottom: 0 !important; }
.rd-results .article > :first-child { margin-top: 0 !important; }
.rd-results .article h2 { font-family: var(--heading); color: var(--color-text); }

/* ── CLIENT-AUDIT-INFO — karta hero (port z referencji .client-audit-info,
   ref.css :262-296). Owija blok tytułu .client-audit-details (label + h1 +
   #heroSummary KPI) oraz badge .contract-profile-status (prawy górny róg). ── */
.rd-results .client-audit-info {
  display: flex; align-items: stretch; gap: 25px;
  margin: 0 0 18px; padding: 28px;
  border: 1px solid var(--color-border); border-radius: 10px;
  background: var(--color-bg); position: relative;
}
/* Blok tytułu: label „Raport sezonowości" (uppercase szary) + h1 (fraza) + KPI.
   ref.css :229-261 (.client-audit-details width:100%, span =text-slate 12px 1.6px,
   h1 :191 =primary 24px Montserrat). Mapowanie zmiennych ref→rd jak reszta redesignu. */
.rd-results .client-audit-details { flex: 1; min-width: 0; }
.rd-results .client-audit-details > span {
  display: block;
  color: var(--color-text-muted); font-size: 12px; font-weight: 500;
  letter-spacing: 1.6px; text-transform: uppercase; line-height: 1.2;
}
.rd-results .client-audit-details > h1 {
  margin: 6px 0 14px;
  font-family: var(--heading); font-size: 24px; font-weight: 500;
  color: var(--color-primary); line-height: 1.2;
}
.rd-results .client-audit-info .contract-profile-status {
  position: absolute; top: 10px; right: 10px;
}

/* ── BC-HEAD — flex h2 + przycisk CSV w jednym wierszu (port z referencji
   .bc-head, ref.css :1603-1608). Kalendarz / Szczegóły fraz / Porównanie. ── */
.rd-results .bc-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 20px;
}
.rd-results .bc-head h2 { margin: 0; }

/* ── TOC-NAV — lewe menu „SEKCJE" ze scroll-spy (Task 1, port layoutu z referencji).
   Tylko report.html (standalone). Fixed, na lewo od kolumny treści. Kolumna treści
   raportu to Bootstrap .container (style.css: max-width:100% < 1600px, 1600px ≥ 1600px).
   Kolumna jest płynna pełnoekranowa (brak wąskiego wyśrodkowanego boxu z marginesami),
   więc kotwiczymy nav względem umownej kolumny 1140px (.container xl, spójnie z analyze)
   z clampem max(16px, …) żeby przy 1280–1600px nav nigdy nie wyszedł poza lewą krawędź.
   Poniżej 1200px nav jest ukryty. Nav jest dzieckiem .rd-results → dziedziczy tokeny. ── */
.toc-nav {
  position: fixed; top: 92px;
  left: 24px;
  width: 220px; max-height: calc(100vh - 112px);
  overflow-y: auto; z-index: 800; scrollbar-width: thin;
}
.toc-nav__label {
  display: block; padding: 0 10px 8px;
  font-size: 12px; font-weight: 600; letter-spacing: 1.2px;
  text-transform: uppercase; color: var(--color-text-muted);
}
.toc-nav__list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 1px;
}
.toc-nav__item a {
  display: block; padding: 10px;
  font-size: 17px; color: var(--color-text-muted);
  text-decoration: none; border-left: 2px solid transparent;
  border-radius: 0 4px 4px 0; line-height: 1.6;
  transition: color .15s, border-color .15s, background .15s;
}
.toc-nav__item a:hover { color: var(--color-primary); background: rgba(90, 47, 168, 0.05); }
.toc-nav__item.active a {
  color: var(--color-primary); border-left-color: var(--color-accent);
  background: rgba(90, 47, 168, 0.06); font-weight: 500;
}
/* Toggle „Sekcje: <aktywna> ▾" — tylko mobile (<1200px). Desktop: fixed sidebar,
   lista zawsze widoczna, toggle ukryty. */
.toc-nav__toggle { display: none; }

/* Bez sekcji (np. /app/analyze przed analizą) nav jest pusty — ukryj go i NIE rezerwuj
   guttera/offsetu. JS (toc_nav.html) ustawia body.toc-nav-ready gdy menu ma pozycje;
   offsety treści niżej są bramkowane tą klasą. */
body:not(.toc-nav-ready) .toc-nav { display: none !important; }

/* Report z bocznym menu: rezerwuj lewy gutter na toc-nav, treść zostaje szeroka */
@media (min-width: 1200px) {
  /* !important bo style.css:58 `.container { padding: 0 !important }` inaczej zeruje ten offset
     (wyższa specyficzność body.has-toc-nav .container.py-4 + !important wygrywa) */
  body.has-toc-nav.toc-nav-ready .container.py-4 { padding-left: 260px !important; }
  .toc-nav { left: 24px; }
}
@media (min-width: 1600px) {
  /* przy wyśrodkowanym kontenerze 1600px trzymaj nav tuż przy jego lewej krawędzi */
  .toc-nav { left: calc(50% - 800px + 24px); }
}

/* ── TOC-NAV mobile (<1200px) — pełnoszeroki pasek FIXED pod navbarem zamiast
   fixed sidebara. Musi być `position:fixed` (nie sticky), bo nav jest OSTATNIM
   dzieckiem .rd-results (toc_nav.html: root.appendChild) → sticky przyklejałby się
   dopiero na DOLE treści, nie u góry. Fixed jest niezależny od pozycji w DOM.
   JS (toc_nav.html) mierzy wysokość sticky navbara i wpycha ją w --toc-top, więc
   pasek siedzi POD navbarem (różna wysokość navbara → zmienna, nie stała).
   Lista sekcji domyślnie zwinięta, rozwijana przyciskiem .toc-nav__toggle przez
   klasę .toc-nav--open (dropdown absolutnie pod paskiem, overlay — nie pcha treści).
   Offset treści (padding-top na .container.py-4) odsłania hero spod paska. ── */
@media (max-width: 1200px) {
  .toc-nav {
    position: fixed; top: var(--toc-top, 56px); left: 0; right: 0;
    width: auto; max-height: none !important;
    overflow: visible; z-index: 790;
    margin: 0; padding: 0;
    background: #fff; border: 0; border-bottom: 1px solid var(--color-border);
  }
  /* Pasek toc-nav jest fixed nad treścią → odsuń hero w dół o jego wysokość.
     Navbar (.sticky-top) rezerwuje swoje miejsce we flow, więc dokładamy TYLKO
     wysokość paska toc-nav. !important bije style.css:58 `.container{padding:0!important}`. */
  body.has-toc-nav.toc-nav-ready .container.py-4 { padding-top: 52px !important; }
  /* Toggle = cały klikalny pasek: nazwa aktywnej sekcji + strzałka. */
  .toc-nav__toggle {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    width: 100%; padding: 12px 14px; box-sizing: border-box;
    background: transparent; border: 0; border-radius: 8px;
    font-size: 14px; font-weight: 600; color: var(--color-text);
    text-align: left; cursor: pointer; line-height: 1.3;
  }
  .toc-nav__toggle-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .toc-nav__toggle-arrow { flex: 0 0 auto; color: var(--color-text-muted); transition: transform .15s; }
  .toc-nav--open .toc-nav__toggle-arrow { transform: rotate(180deg); }
  /* Label „SEKCJE" zbędny na mobile — toggle już go niesie. */
  .toc-nav__label { display: none; }
  /* Lista zwinięta domyślnie; .toc-nav--open → dropdown pod paskiem. */
  .toc-nav__list {
    display: none;
    position: absolute; left: 0; right: 0; top: 100%;
    margin-top: 4px; padding: 6px;
    background: #fff; border: 1px solid var(--color-border); border-radius: 8px;
    box-shadow: 0 8px 24px rgba(26, 10, 46, 0.12);
    max-height: 60vh; overflow-y: auto;
  }
  .toc-nav--open .toc-nav__list { display: flex; }
  .toc-nav__item a {
    border-left: 0; border-radius: 6px; padding: 10px 12px; font-size: 15px;
  }
  .toc-nav__item.active a { border-left: 0; }
}
@media print { .toc-nav { display: none !important; } }

/* ── Analiza CPC — lekkie chipy statusu (label + contract-profile-status) ── */
.rd-results .scan-item-label { display: flex; align-items: center; gap: 10px; }
.rd-results .scan-item-label h4 {
  color: var(--color-text); font-size: 12px; font-weight: 500;
  letter-spacing: 1.6px; margin: 0; width: 100%;
}
.rd-results .scan-item-label .contract-profile-status { padding: 4px 7px; font-size: 12px; }
.rd-results .contract-profile-status {
  display: flex; align-items: center; gap: 8px; padding: 8px 14px;
  border: 1px solid var(--color-border); border-radius: 5px; background: #fff;
  color: var(--color-text-muted); font-size: 10px; font-weight: 500;
  letter-spacing: .6px; text-transform: uppercase; white-space: nowrap;
}
.rd-results .contract-profile-status span { width: 7px; height: 7px; border-radius: 50%; background: var(--color-success-mid); }
.rd-results .contract-profile-status.fail span { background: var(--color-error); }

/* ── PT-TABLE — kanoniczny styl tabel (port z referencji .pt-table, ref.css :1459-1508).
   Tabele Szczegóły fraz (#keywordDetailsTable), Kalendarz (#calendarTable), Porównanie
   (#kwComparisonContent). Zastępuje Bootstrap .table. Tokeny var(--color-border/text)
   zamiast ref --border-subtle/--text-color (mapowanie 1:1). Portujemy tylko reguły
   strukturalne realnie używane przez nasze tabele — klasy treści komórek z referencji
   (.pt-phrase/.pt-badge/.pt-sort-icon/.pt-sorted) nie są emitowane przez analyze.js,
   więc pominięte (DRY — bez martwego CSS). Sortowanie hookuje po ID (initSortableTable),
   nie po klasie — .pt-table to czysty styl. Cell-styling (.status-pill, .cal-scale-bar,
   .cal-row-*, .fw-bold) celuje w elementy WEWNĄTRZ td → bez konfliktu z .pt-table td. ── */
.rd-results .pt-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 11px;
  border-radius: 5px;
  border: 1px solid var(--color-border);
  overflow: hidden;
}
.rd-results .pt-table thead tr { border-bottom: none; }
.rd-results .pt-table th {
  padding: 10px 14px;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--color-text-muted);
  text-align: left;
  white-space: nowrap;
  user-select: none;
  cursor: pointer;
  border-bottom: 1px solid var(--color-border);
}
.rd-results .pt-table th:hover { color: var(--color-text); }
.rd-results .pt-table td {
  padding: 14px;
  color: var(--color-text);
  border-bottom: 1px solid var(--color-border);
  vertical-align: middle;
  font-size: 11px;
}
.rd-results .pt-table tbody tr:last-child td { border-bottom: none; }
.rd-results .pt-table tbody tr:hover td { background: #fdf9ff; }

/* Wykres belek budżetu (renderBudgetTimeline) — większy oddech nad wykresem,
   między kartami „Okna wzrostowe/spadkowe" (#budgetSummarySection) a wykresem.
   JS ustawia inline display:block (nie nadpisuje margin-top). */
.rd-results #budgetBarsSection { margin-top: 40px; }

/* ── RESPONSYWNOŚĆ MOBILE (<640px) — sekcje wyniku. ──────────────────────────
   Hero, wykres budżetu, heatmapa, tabele. Tylko CSS — markup i analyze.js
   nietknięte. ─────────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
  /* Hero: na wąskim ekranie blok tytułu + badge w kolumnie, badge wraca do flow
     (na desktopie absolute w prawym górnym rogu → na mobile wylatuje za kartę). */
  .rd-results .client-audit-info {
    flex-direction: column; align-items: stretch; gap: 16px; padding: 20px;
  }
  .rd-results .client-audit-info .contract-profile-status {
    position: static; align-self: flex-start;
  }

  /* Wykres budżetu: 12 belek + etykiety ściskają się poniżej czytelności.
     Cały wykres (oś Y + belki) scrolluje poziomo jako całość, z min-width
     trzymającym belki w czytelnej szerokości. Bez zmian w JS. */
  .rd-results #budgetBarsContent { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .rd-results #budgetBarsContent > div { min-width: 480px; }

  /* Tabele i heatmapa mają wrapper .overflow-x-auto (scrollują) — dociśnij
     padding/font komórek, żeby mniej trzeba było scrollować. */
  .rd-results .pt-table th { padding: 8px 10px; }
  .rd-results .pt-table td { padding: 10px; font-size: 11px; }
  /* Heatmapa: zmniejsz font/min-width SYMETRYCZNIE w nagłówku i komórkach, by
     kolumny zostały wyrównane (różne min-width = rozjazd). Mniejszy min-width →
     tabela mieści się węziej; nadwyżkę przejmuje scroll wrappera .overflow-x-auto. */
  .rd-results .kh-month,
  .rd-results .kh-cell { min-width: 30px; padding: 0 2px; }
  .rd-results .kh-cell { font-size: 8px; }
  .rd-results .kh-month { font-size: 7px; }
}
