/* TECH-040 — 1A3 Landing page specific styles.
   Importováno PO atlas-base.css. Obsahuje:
     - .top-bar (search + toggle)
     - .atlas-grid (bubble map + ranking sidebar layout)
     - #bubble-map container + .map-popup__* (Iter 2.3)
     - .filter-help / .filter-help-text (Iter 2.3 inline help)
     - .ranking sidebar + .ranking-card
     - .top-species section
*/

/* ============================================================
   Hero row — sladění landing headeru s kempy index stylem.
   Iter 2.7 hotfix #10. Mimické styly .kempy-hero__row +
   .kempy-hero__count z atlas-kempy.css:15-37 (per-page stylesheets,
   žádný shared CSS). Title + pill badge + hint v jednom flex row;
   flex-wrap zajistí graceful wrap na 320px viewport.

   TECH-045 iter 3.11 (founder image #14, 2026-05-20): align-items
   baseline → center. Baseline alignment vizuálně off-set pill count
   badge vůči h1 text (pill má padding xs+md + radius-pill → text-baseline
   uvnitř pill sedí pod x-height linií h1, ale celý pill vypadá příliš
   nahoře). Center vertically aligne badge midline s h1 midline =
   vizuálně čisté „in-line s textem" feeling. .hint (snapshot date) zůstává
   sensible — pill je dominantní visual block, hint je sekundární a center
   alignment ho přirozeně srovná s ostatními items v row.

   TECH-045 iter 3.12 (founder image, 2026-05-20): universal layout napříč
   všemi viewport widths (desktop + tablet + mobile pro .hero-row). Cíl:
   title vlevo, count úplně vpravo (justify-content: space-between),
   hint (date snapshot) force-wrap na nový řádek a align-right pod count.
   Iter 3.11 řešilo mobile `.top-bar__title-row` (separate element v
   `.top-bar__mobile-header`); iter 3.12 přináší stejné chování i do
   `.hero-row` (visible na desktop + tablet a v některých templatech
   i na mobile). flex-wrap: wrap zachován (důležitý pro hint force-wrap
   přes flex: 1 0 100%). .hero-title má flex: 0 1 auto (no grow), takže
   se nerozlije na celou šířku ani na 1440px+ viewport; .hero-count má
   flex-shrink: 0 (chrání pill před zmenšením); space-between distribuuje
   volné místo mezi title a count badge.

   TECH-045 iter 3.13 (founder image #16, 2026-05-20): iter 3.12 force-wrap
   hintu (flex: 1 0 100%) vytvořil extra vertical row uvnitř `.hero-row` →
   mezera mezi h1 a tagline „Kdy a kde se chytá v Norsku" se zvětšila o
   line-height hintu. Cíl iter 3.13: nechat natural flex-wrap behavior
   (hint inline když se vejde na wide viewport, wraps na narrow), zmenšit
   font hintu z --fs-sm na --fs-xs (víc často se vejde inline). Push-apart
   pattern: justify-content: space-between odstraněno, místo toho
   `margin-right: auto` na `.hero-title` push count + hint do right group
   jako pair. flex-shrink: 0 na .hint chrání před zúžením (vejde se celé
   nebo wraps). text-align: right zachován jako fallback pro wrap scenario. */
/* TECH-045 iter 3.15 (founder report, 2026-05-21): align-items: center →
   flex-end. Důvod: `.hero-meta` je stacked column (pill ~31px + gap 2px +
   hint ~20px ≈ 54px), title je single line (~47px). Tagline `.hero-sub`
   sedí AFTER `.hero-row`, takže její gap se měří od row.bottom = max(title,
   meta).bottom. S align-items: center title byl vertical middle → mezi
   title.bottom a row.bottom byl 3.5px prázdný prostor → effective gap
   title↔tagline = 9.32px místo target ~4px. flex-end aligne title.bottom
   s row.bottom (= meta.bottom = hint.bottom). title baseline ≈ hint
   baseline (date snapshot), gap title↔tagline = konzistentní row.margin-
   bottom (4px) napříč 800-1500px viewporty. Meta column visual hierarchy
   zachována (pill nahoře, hint pod pillem — natural column flow uvnitř
   meta nezávisí na align-items rodiče). */
.hero-row {
  display: flex;
  align-items: flex-end;
  gap: var(--space-md);
  flex-wrap: wrap;
  margin: 0 0 var(--space-xs);
}
.hero-row .hero-title {
  flex: 0 1 auto;
  margin-right: auto;
}
.hero-count {
  display: inline-block;
  background: var(--color-primary);
  color: var(--color-white);
  padding: var(--space-xs) var(--space-md);
  border-radius: var(--radius-pill);
  font-weight: 700;
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}

/* TECH-031 v7 (Variant C-i): .hero-count--compliance — compliance pill button
   modifier. Aplikuje se na `<button class="hero-count hero-count--compliance">`
   (index + kempy_index entry pages). Detail page kempy_camp zachovává decorative
   `<span class="hero-count">` bez modifier — base styly z `.hero-count` stačí.
   Internal flex layout pro 3 children: __icon (✓) + __value (count) + __chevron (▾).
   Spec: docs/design/2026-05-21-compliance-banner-v7-variant-c-refined.md (sekce 2). */
.hero-count--compliance {
  /* Button reset (overrides default browser button styling) */
  border: 0;
  font-family: inherit;
  cursor: pointer;
  /* Flex layout pro 3 spans + change z inline-block na inline-flex */
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  /* WCAG 2.5.5 touch target (44 px) — large target heuristic */
  min-height: 2.75rem;
  /* Smooth transitions pro hover/open feedback */
  transition: background-color 150ms ease, transform 150ms ease, box-shadow 150ms ease;
}
/* TECH-031 v11 fix (founder feedback 2026-05-22 Image #10): pill internal
   vertical alignment sync — explicit line-height: 1 na value aby `align-items:
   center` na pillu vycentroval midpointy správně (bez `line-height: 1` value
   dědí --lh-base 1.6 → tall line-box → off-center proti icon + chevron). */
.hero-count__icon {
  font-size: var(--fs-base);
  line-height: 1;
}
.hero-count__value {
  line-height: 1;
}
.hero-count__chevron {
  font-size: 0.75em;
  line-height: 1;
  margin-left: var(--space-2xs);
  transition: transform 200ms ease;
}
.hero-count--compliance:hover {
  background: var(--color-primary-hover, #163a55);
  transform: translateY(-1px);
  box-shadow: 0 2px 6px rgba(15, 42, 61, 0.15);
}
.hero-count--compliance:active {
  transform: translateY(0);
  box-shadow: none;
}
.hero-count--compliance:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
/* Open state — chevron flip ▾ → ▴ */
.hero-count--compliance[aria-expanded="true"] .hero-count__chevron {
  transform: rotate(180deg);
}
@media (prefers-reduced-motion: reduce) {
  .hero-count--compliance,
  .hero-count__chevron {
    transition: background-color 150ms ease;
  }
  .hero-count--compliance:hover {
    transform: none;
    box-shadow: none;
  }
  .hero-count--compliance[aria-expanded="true"] .hero-count__chevron {
    transition: none;
  }
}
/* Iter 3.13: hint (date snapshot) natural flex-wrap behavior — inline
   na wide viewport (vejde se vedle count), wraps na narrow. Smaller font
   (--fs-xs) zvyšuje šanci inline placement. text-align: right je fallback
   když hint wraps na samostatný řádek.

   TECH-045 iter 3.14 (founder Image #1, 2026-05-20): hint je nyní child
   `.hero-meta` (sourozenec `.hero-count` ve stacked column), ne `.hero-row`
   direct child jako v iter 3.13. Selektor `.hero-row .hint` stále matchuje
   (descendant combinator), takže font-size + text-align persist. Margin: 0
   ponechán; spacing mezi pillem a hintem řeší `.hero-meta { gap }`. */
.hero-row .hint {
  font-size: var(--fs-xs);
  flex-shrink: 0;
  text-align: right;
  margin: 0;
}

/* TECH-045 iter 3.14 (founder Image #1, 2026-05-20): desktop meta wrapper —
   pill count + snapshot date stacked v column zarovnaný doprava. Nahrazuje
   inline placement hintu vedle pillu z iter 3.13 (kde hint na úzké šířce
   wrap-oval pod count se shodnou pravou hranou, ale visually drift bez
   container groupingu).

   Mechanika:
   - flex-direction: column → pill nad hintem (visual hierarchy: dominant
     badge nahoře, sekundární date pod ním).
   - align-items: flex-end → oba items zarovnány k pravému okraji wrappera.
   - gap: var(--space-2xs) → minimal vertical spacing (paritní s mobile
     stacking v `.top-bar__meta`).
   - flex-shrink: 0 → meta wrapper nezužuje když title grow-uje (chrání
     pill před zmenšením; hint má vlastní flex-shrink: 0 z `.hero-row .hint`). */
.hero-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-2xs);
  flex-shrink: 0;
}

/* ============================================================
   Top bar — search + toggle na list view
   ============================================================ */
.top-bar {
  display: flex;
  gap: var(--space-sm);
  align-items: center;
  margin: 0 0 var(--space-md);
}
.top-bar__search {
  flex: 1 1 auto;
  display: block;
}
.top-bar__search input[type="search"] {
  width: 100%;
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg);
  color: var(--color-fg);
  font-family: inherit;
  font-size: var(--fs-base);
  min-height: 44px;
}
.top-bar__search input[type="search"]:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-color: var(--color-accent);
}
/* TECH-045 iter 2 fix P0: .toggle-link ruleset přesunut do atlas-base.css.
   Důvod: utility-level navigation component sdílený přes 3 page typy (landing,
   kempy_index, kempy_camp detail). Detail loaduje atlas-base + atlas-detail,
   bez landing → toggle-link byl unstyled link. Move = single source, žádný
   per-page CSS link extend. */

/* ============================================================
   Atlas grid — bubble map + ranking sidebar
   Mobile: stacked. Tablet+: side-by-side (map 2fr, ranking 1fr).
   ============================================================ */
.atlas-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
  margin: 0 0 var(--space-xl);
}
.atlas-grid__map {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

#bubble-map {
  width: 100%;
  height: 60vh;
  min-height: 400px;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-bg-soft);
  overflow: hidden;
  position: relative;
}
#bubble-map:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 2px;
}
.map-fallback {
  padding: var(--space-md);
  background: var(--color-bg-soft);
  color: var(--color-fg-muted);
  text-align: center;
}

/* ============================================================
   Ranking sidebar — žebříček kempů
   ============================================================ */
.ranking {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-md);
}
.ranking__title {
  margin: 0 0 var(--space-xs);
  font-size: var(--fs-md);
  color: var(--color-primary);
}
.ranking__viewport {
  margin: 0 0 var(--space-sm);
  font-size: var(--fs-xs);
  color: var(--color-fg-muted);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}
.ranking__list {
  list-style: none;
  padding: 0;
  margin: 0;
  max-height: 60vh;
  /* TECH-042 iter 11 → iter 23 (founder report 2026-05-17 22:50): macOS overlay
     scrollbar override — iter 11 (scrollbar-width: thin + custom webkit pseudo)
     nestačil, protože macOS trackpad default „Show scroll bars: Automatically"
     způsobí že Safari/Chrome rendrují overlay scrollbar (hidden until scroll,
     zero gutter, ignoruje ::-webkit-scrollbar { width }). Fix: overflow-y: scroll
     (vždy rezervuje gutter — predictable layout místo auto layout shift při
     filter change z 2 299 → např. 3 kempů) + -webkit-appearance: none na
     ::-webkit-scrollbar (override macOS overlay mode, force always-visible
     custom scrollbar). Width 10px (subtle nárůst z 8px pro lepší affordance).
     Padding-right zajistí že scrollbar neoverlapuje content. */
  overflow-y: scroll;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  scrollbar-width: thin;
  scrollbar-color: var(--color-primary) var(--color-bg-soft);
  padding-right: var(--space-xs);
}
.ranking__list::-webkit-scrollbar {
  -webkit-appearance: none;
  width: 10px;
}
.ranking__list::-webkit-scrollbar-track {
  background: var(--color-bg-soft);
  border-radius: 4px;
}
.ranking__list::-webkit-scrollbar-thumb {
  background: var(--color-primary);
  border-radius: 4px;
  border: 1px solid var(--color-bg-soft);
}
.ranking__list::-webkit-scrollbar-thumb:hover {
  background: var(--color-accent);
}
/* Bottom fade gradient — vizuální cue „více obsahu dole". Iter 23 (founder report
   2026-05-17 23:30 + rybar-reviewer): fade end-color změněn z var(--color-bg)
   (= stejná barva jako .ranking container → 0 vizuální cue, gradient neviditelný)
   na var(--color-bg-soft) (= béžová barva ranking-card → vytváří visible band,
   jako by poslední karta postupně mizela do okraje sidebar). */
.ranking {
  position: relative;
}
.ranking::after {
  content: '';
  position: absolute;
  left: var(--space-md);
  right: var(--space-md);
  bottom: var(--space-md);
  height: 24px;
  background: linear-gradient(to bottom, transparent 0%, var(--color-bg-soft) 100%);
  pointer-events: none;
  border-radius: 0 0 var(--radius-md) var(--radius-md);
}

/* Ranking card — used in landing sidebar + top-species section.
   Step 1b: <li> je container (žádný role="link" antipattern), interior
   je <a class="ranking-card__link"> wrap — celá karta klikatelná nativně. */
.ranking-card {
  background: var(--color-bg-soft);
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  transition: border-color 0.15s, background 0.15s;
}
.ranking-card:hover {
  border-color: var(--color-primary);
  background: var(--color-bg);
}
/* TECH-042 iter 25 — hover sync z mapy: marker mouseover přidá data-marker-hover
   na odpovídající ranking-card. Stejný visual jako přímý hover myší. Koexistuje
   s data-in-viewport (border-left accent zůstává, border-color overlap je OK). */
.ranking-card[data-marker-hover="true"] {
  border-color: var(--color-primary);
  background: var(--color-bg);
}
/* TECH-042 iter 24 (founder 2026-05-17 23:25): viewport highlight — kemp, který
   je vidět v aktuálním map výřezu, dostane subtle accent border-left. Visual
   cue „tento kemp je vidět na mapě" bez filterování listu. Doplňková informace
   nad rámec base hover/focus. */
.ranking-card[data-in-viewport="true"] {
  border-left: 3px solid var(--color-accent);
}
.ranking-card--loading {
  display: block;
  text-align: center;
  color: var(--color-fg-muted);
  font-style: italic;
  background: transparent;
  border-color: transparent;
  padding: var(--space-sm);
}
.ranking-card--empty {
  display: block;
  text-align: center;
  color: var(--color-fg-muted);
  font-style: italic;
  padding: var(--space-md);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-md);
  background: transparent;
}
/* TECH-042 iter 12: end-of-list marker po remaining=0 (infinite scroll done).
   Vizuální cue „už nic neaplikuje se" — odlišný od sentinel „Načítám…" loading.
   Padding-bottom větší, aby last data-card byla od marker delší pause. */
.ranking-card--end {
  display: block;
  text-align: center;
  color: var(--color-fg-muted);
  font-style: italic;
  font-size: var(--fs-sm);
  padding: var(--space-md) var(--space-sm);
  background: transparent;
  border: none;
  margin-top: var(--space-sm);
}
.ranking-card--sentinel {
  /* Sentinel je pre-end loading placeholder (Načítám další…) — paritní styling
     s .ranking-card--loading, ale jen pro mobile ranking infinite scroll. */
  display: block;
  text-align: center;
  color: var(--color-fg-muted);
  font-style: italic;
  font-size: var(--fs-xs);
  padding: var(--space-md);
  background: transparent;
  border: 1px solid var(--color-border);
  border-style: dashed;
  border-radius: var(--radius-md);
  opacity: 0.7;
}

/* Native link wrap — celá karta klikatelná, screen reader čte z visible text. */
.ranking-card__link {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--space-sm);
  align-items: start;
  padding: var(--space-sm);
  color: inherit;
  text-decoration: none;
  border-radius: var(--radius-sm);
  transition: transform 120ms ease, box-shadow 120ms ease, background-color 120ms ease;
}
.ranking-card__link:hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 6px rgba(15, 42, 61, 0.08);
  color: inherit;
}
.ranking-card__link:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* ============================================================
   Leaflet markery — malé kruhové tečky per TECH-038 baseline.
   14×14 CSS-styled kruh, paleta brand (fjord / slate), white
   ring pro contrast nad tile vrstvou. Žádné SVG, žádný canvas.

   POZN: Leaflet aplikuje inline `transform: translate3d(...)` na outer
   .camp-marker div pro positioning. Hover scale proto děláme přes
   ::before pseudo-element (samostatný transform context), aby
   se nepřebíjelo Leaflet positioning.
   ============================================================ */
.camp-marker {
  width: 14px;
  height: 14px;
  cursor: pointer;
  position: relative;
}
.camp-marker::before {
  content: '';
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid #ffffff;
  box-shadow: 0 1px 3px rgba(15, 42, 61, 0.4);
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
  box-sizing: border-box;
}
.camp-marker--identified::before {
  background: var(--color-marker-identified);
}
.camp-marker--unidentified::before {
  background: var(--color-marker-unidentified);
  opacity: 0.85;
}
.camp-marker:hover::before,
.camp-marker:focus::before,
.camp-marker--highlighted::before {
  transform: scale(1.4);
  box-shadow: 0 2px 6px rgba(15, 42, 61, 0.6);
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  background: var(--color-marker-highlighted);
  opacity: 1;
}
.camp-marker--highlighted {
  z-index: 1000;
}

/* Iter 2.2 — MarkerCluster override do brand palety.
   Vendor MarkerCluster.Default.css loaduje AFTER landing CSS (HEAD order),
   takže přebíjíme přes !important + selektory na size-tier (vendor používá
   .marker-cluster-{small,medium,large} pro per-size barvy). */
.marker-cluster,
.marker-cluster-small,
.marker-cluster-medium,
.marker-cluster-large {
  background-color: rgba(29, 74, 106, 0.4) !important;
}
.marker-cluster div,
.marker-cluster-small div,
.marker-cluster-medium div,
.marker-cluster-large div {
  background-color: var(--color-marker-identified) !important;
  color: #ffffff !important;
  font-weight: 600;
}

/* Iter 2.7 hotfix #7: highlight cluster při hover ze ranking sidebar
   (matched kemp je skrytý v cluster). Coral outline paritní s
   .camp-marker--highlighted, nepřebíjí brand fjord/slate paletu. */
.marker-cluster--highlighted {
  outline: 3px solid var(--color-accent) !important;
  outline-offset: 2px;
  box-shadow: 0 0 0 4px rgba(255, 127, 80, 0.25), 0 2px 8px rgba(15, 42, 61, 0.5) !important;
  transition: outline 0.15s ease, box-shadow 0.15s ease;
}

/* TECH-042 iter 30 — permanent select (mobile card-tap drží barvu).
   Silnější než --highlighted (hover transient): scale 1.5 vs 1.4, outline 3px
   vs 2px, větší halo box-shadow (opacity 0.45 vs hover/highlighted feel).
   Drží do dalšího tap card nebo manuál map clear.
   POZN: visible kruh je ::before pseudo-element (viz .camp-marker--highlighted
   pattern výše) — outer .camp-marker je wrapper bez box. Cluster element
   nemá ::before pattern, takže outer styling correct s !important (vendor
   MarkerCluster.Default.css loaduje AFTER). */
.camp-marker--selected::before {
  transform: scale(1.5);
  outline: 3px solid var(--color-accent);
  outline-offset: 3px;
  box-shadow: 0 0 0 6px rgba(231, 111, 81, 0.45), 0 2px 8px rgba(15, 42, 61, 0.6);
  background: var(--color-marker-highlighted);
  opacity: 1;
}
.camp-marker--selected {
  z-index: 1001;
}

.marker-cluster--selected {
  outline: 3px solid var(--color-accent) !important;
  outline-offset: 3px;
  box-shadow: 0 0 0 6px rgba(231, 111, 81, 0.45), 0 2px 8px rgba(15, 42, 61, 0.6) !important;
  z-index: 1001;
}

/* Map marker popup (per-camp). */
.map-popup h3 {
  margin: 0 0 4px;
  font-size: var(--fs-base);
}
.map-popup p {
  margin: 0 0 4px;
  font-size: var(--fs-xs);
  color: var(--color-fg-muted);
}
/* TECH-042 iter 15 (founder request 2026-05-17 20:45): „to tlacitko detail kempu
   udelej mensi, at zapada do designu celeho webu, je strasne obrovske a vyrazne,
   a vyhod tam tu sipku". Decentnější styling — kompaktní inline button (ne
   full-width), normal case (no uppercase), kratší padding, jemnější shadow,
   bez šipky. Pořád primary background + white text (kontrast, čitelnost), ale
   méně dominantní v popup layoutu. */
.map-popup__link {
  display: inline-block;
  margin-top: var(--space-xs);
  padding: 6px var(--space-md);
  background: var(--color-primary);
  /* Iter 14: !important override Leaflet default link color. */
  color: #ffffff !important;
  font-weight: 600;
  font-size: var(--fs-sm);
  text-decoration: none;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-primary);
  line-height: 1.4;
  transition: background 0.15s ease;
  cursor: pointer;
}
.map-popup__link:hover {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: #ffffff !important;
  text-decoration: none;
}
.map-popup__link:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
.map-popup__status {
  font-weight: 600;
  color: var(--color-fg) !important;
}
.map-popup__status--identified {
  margin-top: var(--space-2xs, 0.25rem);
  font-size: var(--fs-sm);
  font-weight: 400;
  color: var(--color-fg-muted) !important;
}
.map-popup__stats {
  font-variant-numeric: tabular-nums;
}
/* Iter 2.5 hotfix #2: top druh NO název v závorce (muted) + empty fallback. */
.map-popup__species-no {
  color: var(--color-fg-muted);
  font-weight: 400;
}
.map-popup__stats--empty {
  font-style: italic;
  color: var(--color-fg-muted);
}

/* Iter 2.3/2.4 — Inline help toggle pro filter chips (newcomer onboarding).
   Iter 2.4: help text je popover (`role="tooltip"` + `data-open`) — absolute
   positioning uvnitř `.filter-bar__chip`, zero layout shift. Desktop hover/
   focus-within. Mobile: JS tap toggle + outside-click + Esc close. */
.filter-bar__chip {
  position: relative;  /* anchor pro absolute popover (Iter 2.4) */
}
.filter-bar__label-row {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}
.filter-help {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: 50%;
  background: var(--color-bg);
  color: var(--color-fg-muted);
  font-size: var(--fs-xs);
  font-weight: 600;
  line-height: 1;
  cursor: help;
  transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}
.filter-help:hover,
.filter-help:focus-visible {
  background: var(--color-primary);
  color: var(--color-white);
  border-color: var(--color-primary);
  outline: none;
}
/* Popover — default skrytý, plovoucí mimo flow → žádný layout shift. */
.filter-help-text {
  display: none;
  position: absolute;
  top: calc(100% + var(--space-xs));
  left: 0;
  z-index: 100;
  margin: 0;
  padding: var(--space-sm) var(--space-md);
  max-width: 280px;
  min-width: 200px;
  width: max-content;
  background: var(--color-bg);
  color: var(--color-fg);
  font-size: var(--fs-sm);
  line-height: var(--lh-base);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: 0 4px 12px rgba(15, 42, 61, 0.15);
  pointer-events: auto;
}
/* Šipka nahoře, ukazující na `?` button. */
.filter-help-text::before {
  content: "";
  position: absolute;
  top: -6px;
  left: 12px;
  width: 12px;
  height: 12px;
  background: var(--color-bg);
  border-left: 1px solid var(--color-border);
  border-top: 1px solid var(--color-border);
  transform: rotate(45deg);
}
/* JS-controlled open state — click toggle (desktop + mobile shodný UX).
   Iter 2.4 hotfix: smazán @media (hover: hover) auto-show, protože hover
   přebíjel JS data-open="false" → second click na ? popover nezavřel
   (myš stále nad chipem → :hover znovu otevřel). Click-only je předvídatelný. */
.filter-help-text[data-open="true"] {
  display: block;
}
/* Mobile: popover roztáhnout na šířku chipu, šipka vlevo. */
@media (max-width: 600px) {
  .filter-help-text {
    left: 0;
    right: 0;
    max-width: none;
    width: auto;
    min-width: 0;
  }
  .filter-help-text::before {
    left: 16px;
  }
}

.ranking-card__rank {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--color-primary);
  min-width: 1.5rem;
  text-align: center;
}
.ranking-card__body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}
.ranking-card__name {
  margin: 0;
  font-size: var(--fs-base);
  font-weight: 600;
  color: var(--color-fg);
  line-height: 1.3;
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  flex-wrap: wrap;
}
/* Server-side macro variant: <h3><a>{name}</a></h3> uvnitř ranking_card.
   Při JS rendru (Step 1b) je celá karta wrapped v <a class="ranking-card__link">,
   takže nested <a> není přítomen. Tahle rule cílí jen na server-rendered fallback. */
.ranking-card__name a {
  color: var(--color-fg);
  text-decoration: none;
}
.ranking-card__name a:hover {
  color: var(--color-primary);
  text-decoration: underline;
}
.ranking-card__meta {
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--color-fg-muted);
}
.ranking-card__count {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.ranking-card__count-num {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--color-fg);
  line-height: 1;
}
.ranking-card__count-label {
  font-size: 0.65rem;
  color: var(--color-fg-muted);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  margin-top: var(--space-xs);
}

/* ============================================================
   Top species section
   ============================================================ */
.top-species {
  margin: var(--space-xl) 0;
  padding-top: var(--space-lg);
  border-top: 1px solid var(--color-border);
}
.top-species__list {
  list-style: none;
  padding: 0;
  margin: var(--space-md) 0 0;
  display: grid;
  gap: var(--space-sm);
  grid-template-columns: 1fr;
}
.top-species__card {
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  gap: var(--space-sm);
  align-items: center;
  padding: var(--space-sm);
  background: var(--color-bg-soft);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
}
.top-species__rank {
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--color-primary);
  min-width: 1.5em;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.top-species__image {
  width: 96px;
  height: 64px;
  object-fit: contain;  /* Iter 2.7 hotfix #2: ryby vidět celé (ne ořezávat per cover) */
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  padding: 2px;
}
/* Iter 2.7 hotfix #5: vysvětlující intro k sekci (regulatorní kontext). */
.top-species__intro {
  margin: var(--space-xs) 0 var(--space-md);
  padding: var(--space-sm) var(--space-md);
  background: var(--color-bg-soft);
  border-left: 3px solid var(--color-primary);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  line-height: var(--lh-base);
  color: var(--color-fg-muted);
}
.top-species__intro strong { color: var(--color-fg); }
.top-species__body { min-width: 0; }
.top-species__name {
  margin: 0;
  font-size: var(--fs-base);
  font-weight: 600;
  color: var(--color-fg);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
}
.top-species__alias {
  font-weight: 400;
  font-size: var(--fs-sm);
  color: var(--color-fg-muted);
  text-transform: none;
  letter-spacing: 0;
}
.top-species__no-name {
  margin: 2px 0 0;
  font-size: var(--fs-xs);
  color: var(--color-fg-muted);
}
.top-species__no-label {
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-weight: 600;
}
.top-species__no-value { font-style: italic; }
.top-species__count {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.top-species__count strong {
  display: block;
  font-size: var(--fs-md);
  font-weight: 700;
  color: var(--color-primary);
}
.top-species__count span {
  font-size: var(--fs-xs);
  color: var(--color-fg-muted);
  text-transform: uppercase;
}
.image-attribution {
  margin: var(--space-xs) 0 0;
  font-size: var(--fs-xs);
  color: var(--color-fg-muted);
}

/* ============================================================
   Responsive — tablet+ side-by-side layout
   ============================================================ */
@media (min-width: 768px) {
  .atlas-grid {
    grid-template-columns: minmax(0, 2fr) minmax(280px, 1fr);
    gap: var(--space-lg);
  }
  #bubble-map { height: 70vh; min-height: 500px; }
  .top-species__list {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1200px) {
  .top-species__list {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 600px) {
  #bubble-map { height: 50vh; min-height: 320px; }
  .top-bar { flex-wrap: wrap; }
  /* TECH-045 iter 2 fix P0: .toggle-link mobile rule přesunut do atlas-base.css. */
  .ranking { padding: var(--space-sm); }
  .ranking__list { max-height: 40vh; }
  .ranking-card__link { padding: var(--space-xs); gap: var(--space-xs); }
  .ranking-card__rank { font-size: var(--fs-base); }
  .ranking-card__count-num { font-size: var(--fs-base); }
}

/* Mobile narrow: stack image+body, count na svůj řádek/sloupec.
   Image span 2 řádky aby seděla vedle textu + count pod ní. */
@media (max-width: 480px) {
  .top-species__card {
    grid-template-columns: auto 1fr auto;
  }
  .top-species__image {
    grid-row: span 2;
    width: 72px;
    height: 52px;
  }
}
