/* TECH-040 — Atlas base stylesheet (tokens + reset + a11y utility).
   Sdíleno všemi 3 templates: landing, kempy index, kempy detail.
   Per-page CSS soubory IMPORTUJÍ tento přes <link> (ne @import — perf).

   Obsahuje:
     - Design tokens (colors, typography, spacing, radius)
     - CSS reset + box-sizing
     - Typography base (h1–h3, p, a)
     - Skip-link + sr-only + focus-visible (a11y)
     - .badge, .pill, .btn base
     - .nlod-attribution footer
     - .breadcrumb shared component
*/

:root {
  /* ------------------------------------------------------------
     Paleta A — Deep fjord + coral (founder approved TECH-038)
     ------------------------------------------------------------ */
  --color-bg: #fbfaf6;          /* cream paper */
  --color-bg-soft: #f1ede2;     /* warm sand */
  --color-fg: #0f2a3d;          /* deep fjord */
  --color-fg-muted: #3d5061;    /* slate — WCAG AA contrast */
  --color-border: #d9d2c0;      /* driftwood */
  --color-primary: #1d4a6a;     /* north sea */
  --color-primary-hover: #163a55;
  --color-accent: #e76f51;      /* coral CTA */
  --color-accent-hover: #d4583a;
  --color-success: #2f855a;     /* moss */
  --color-warn: #8a5814;        /* amber — WCAG AA contrast */
  --color-danger: #b91c1c;
  --color-overlay: rgba(15, 42, 61, 0.08);
  --color-white: #ffffff;
  --color-marker-identified: #1d4a6a;
  --color-marker-unidentified: #8a9aa8;
  --color-marker-highlighted: #f4a261;

  /* Backward-compat aliasy — TECH-038 component CSS používá tyto. */
  --fg: var(--color-fg);
  --fg-muted: var(--color-fg-muted);
  --bg: var(--color-bg);
  --bg-soft: var(--color-bg-soft);
  --border: var(--color-border);
  --accent: var(--color-primary);
  --badge-bg: #d4ecdb;
  --badge-fg: #1f5538;

  /* ------------------------------------------------------------
     Typography scale (modular 1.250 major third, 16px base)
     System fonts only — privacy + perf.
     ------------------------------------------------------------ */
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI",
               "Helvetica Neue", Arial, sans-serif;
  --font-display: var(--font-sans);
  /* TECH-045 iter 3.14: --fs-2xs přidán pro úzký viewport <420px overflow
     protection v `.top-bar__hint`. Hodnota 0.7rem (~11 px @ 16px root) sedí
     pod --fs-xs (0.8rem) — držíme modular scale „1 stop dolů". */
  --fs-2xs: 0.7rem;
  --fs-xs: 0.8rem;
  --fs-sm: 0.9rem;
  --fs-base: 1rem;
  --fs-md: 1.25rem;
  --fs-lg: 1.563rem;
  --fs-xl: 1.953rem;
  --fs-2xl: 2.441rem;
  --fs-3xl: 3.052rem;
  --lh-tight: 1.2;
  --lh-base: 1.6;
  --tracking-tight: -0.02em;
  --tracking-wide: 0.05em;

  /* Spacing (2 / 4 / 8 / 16 / 24 / 32 / 48 px)
     TECH-045 iter 3.14: --space-2xs přidán pro tight stacked gaps v
     `.hero-meta` (pill ↔ snapshot date) + `.top-bar__meta` paritě
     + tagline margin-top. Hodnota 0.125rem (~2 px) je „polovic --space-xs". */
  --space-2xs: 0.125rem;
  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2rem;
  --space-2xl: 3rem;

  /* Radius */
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 16px;
  --radius-pill: 999px;

  /* Shadows */
  --shadow-sm: 0 1px 2px rgba(15, 42, 61, 0.06);
  --shadow-md: 0 2px 8px rgba(15, 42, 61, 0.10);
}

/* ============================================================
   Reset + base typography
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
/* TECH-031 v12 fix (founder feedback 2026-05-22): cross-page layout shift caused
   by scrollbar appearing/disappearing — landing (mobile sheet layout) nemá body
   scroll → žádný scrollbar → docClientWidth 500. Kempy + detail (page scroll)
   mají scrollbar → docClientWidth 485 → všechen right-aligned content (pill)
   skáče 15 px doleva. `scrollbar-gutter: stable` reserves space pro scrollbar
   na ALL pages (i kdyby content neoverflowed) → konzistentní viewport width
   napříč pages. */
html { scrollbar-gutter: stable; }
body {
  font-family: var(--font-sans);
  color: var(--color-fg);
  background: var(--color-bg);
  line-height: var(--lh-base);
  font-size: var(--fs-base);
  -webkit-text-size-adjust: 100%;
  text-rendering: optimizeLegibility;
}

main {
  display: block;
  max-width: 100%;
  margin: 0 auto;
  padding: var(--space-md);
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  line-height: var(--lh-tight);
  margin: 0 0 var(--space-sm);
}
h1 { font-size: var(--fs-xl); }
h2 { font-size: var(--fs-md); color: var(--color-primary); }
h3 { font-size: var(--fs-base); color: var(--color-fg-muted); text-transform: uppercase; letter-spacing: var(--tracking-wide); }

p { margin: 0 0 var(--space-md); }
a { color: var(--color-primary); text-decoration: underline; }
a:hover, a:focus-visible { color: var(--color-primary-hover); }

ul, ol { margin: 0; padding: 0; }
dl { margin: 0; }
dt { font-weight: 600; color: var(--color-fg-muted); margin-top: var(--space-sm); font-size: var(--fs-sm); }
dd { margin: var(--space-xs) 0 0; font-size: var(--fs-base); }

.hint {
  color: var(--color-fg-muted);
  font-size: var(--fs-sm);
  font-weight: 400;
}

/* ============================================================
   A11y utilities — skip-link, sr-only, focus-visible
   ============================================================ */
.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  /* Step 1b a11y fix: switch z --color-accent (#e76f51 coral, ~3.4:1 fail)
     na --color-primary (#1d4a6a fjord blue, ~10:1 AAA) pro WCAG AA contrast. */
  background: var(--color-primary);
  color: var(--color-white);
  padding: var(--space-sm) var(--space-md);
  z-index: 10000;
  text-decoration: none;
  border-radius: 0 0 var(--radius-sm) 0;
  font-weight: 600;
}
.skip-link:focus,
.skip-link:focus-visible {
  top: 0;
  background: var(--color-primary);
  color: var(--color-white);
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* ============================================================
   Buttons (base — overridable per page)
   ============================================================ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-sm) var(--space-lg);
  border-radius: var(--radius-md);
  font-family: inherit;
  font-weight: 600;
  font-size: var(--fs-base);
  border: 2px solid transparent;
  background: transparent;
  color: var(--color-fg);
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
  min-height: 44px; /* touch target */
}
.btn-primary {
  background: var(--color-accent);
  color: var(--color-white);
  border-color: var(--color-accent);
}
.btn-primary:hover, .btn-primary:focus-visible {
  background: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
  color: var(--color-white);
}
.btn-ghost {
  color: var(--color-primary);
  border-color: var(--color-primary);
}
.btn-ghost:hover, .btn-ghost:focus-visible {
  background: var(--color-primary);
  color: var(--color-white);
}

/* ============================================================
   Badges + pills (shared across all pages)
   ============================================================ */
.badge {
  display: inline-block;
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  font-weight: 600;
}
.badge--identified {
  background: var(--badge-bg);
  color: var(--badge-fg);
  border-radius: var(--radius-pill);
  padding: 0 var(--space-sm);
}
.badge-warning {
  background: #fed7d7;
  color: #742a2a;
  margin-left: var(--space-xs);
}
.badge-registered {
  background: var(--badge-bg);
  color: var(--badge-fg);
}

.pill {
  display: inline-flex;
  align-items: center;
  padding: var(--space-xs) var(--space-md);
  border-radius: var(--radius-pill);
  font-size: var(--fs-sm);
  font-weight: 500;
  border: 1px solid var(--color-border);
  background: var(--color-bg);
  color: var(--color-fg);
}
.pill--success {
  background: var(--color-success);
  color: var(--color-white);
  border-color: var(--color-success);
}
.pill--ok {
  /* TECH-040 Step 2b: použij darker moss (#1f5538 z badge-fg) místo --color-success (#2f855a),
     aby contrast na cream bg byl >= 4.5:1 WCAG AA (#2f855a:cream = 4.35, #1f5538:cream = 7.61). */
  color: var(--badge-fg);
  border-color: var(--badge-fg);
  background: var(--color-bg);
}
.pill--warn {
  background: var(--color-warn);
  color: var(--color-white);
  border-color: var(--color-warn);
}
.pill--regulation {
  background: var(--color-primary);
  color: var(--color-white);
  border-color: var(--color-primary);
}

/* TECH-045 — pills jako odkazy (REGISTROVANÝ, Ověřený web, Google Maps).
   Inherituje existující .pill--success / .pill--ok / .pill--map vizuál,
   přidá hover/focus + reset default link colors. */
a.pill {
  text-decoration: none;
  cursor: pointer;
  transition: filter 0.15s ease, transform 0.15s ease;
}

a.pill:hover {
  filter: brightness(0.92);
  transform: translateY(-1px);
}

a.pill:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* TECH-045 — nový map pill (📍 Google Maps). Neutrální outline styling
   jako .pill--ok.
   iter 3.5 (2026-05-19): custom invert hover odstraněn — Google Maps pill teď
   dědí default `a.pill:hover` (brightness 0.92 + translateY -1px), parity s Web
   kempu pill. Founder UX explicit: „Google Maps stejně jako Web". */
.pill--map {
  background: var(--color-bg);
  color: var(--badge-fg);
  border-color: var(--badge-fg);
}

/* TECH-045 iter 2 — .pill--info: outline neutral grey, statický informational pill.
   Použit pro GoFish 15 kg (zatím bez akce). Vizuálně = secondary / non-interactive,
   na rozdíl od .pill--success (primary registr claim) nebo .pill--regulation (filled
   accent). Žádný hover state — statický. */
.pill--info {
  background: var(--color-bg);
  color: var(--color-fg-muted, var(--color-fg));  /* fallback pokud --color-fg-muted neexistuje */
  border-color: var(--color-fg-muted, var(--color-fg));   /* TECH-045 iter 2 fix P1: kontrast 1.5:1 → ~5:1, brand parity s ostatními outline pills */
}

/* TECH-045 iter 2 fix P0: .toggle-link utility navigation button (shared přes
   landing top-bar, kempy_index top-bar, kempy_camp detail top-right). Předtím
   ruleset žil v atlas-landing.css, ale detail loaduje jen atlas-base + atlas-detail
   → button byl unstyled link. Přesun do base = single source pro všechny page typy. */
.toggle-link {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-sm) var(--space-md);
  background: var(--color-bg);
  color: var(--color-primary);
  border: 1px solid var(--color-primary);
  border-radius: var(--radius-md);
  text-decoration: none;
  font-weight: 600;
  font-size: var(--fs-sm);
  min-height: 44px;
  min-width: 110px;  /* Iter 2.13: identická šířka ≡ Seznam vs ▦ Mapa — bez min-width
                        se buttony liší kvůli rozdílu glyph width (≡ užší než ▦),
                        při přepínání list↔map by „skákaly". */
  white-space: nowrap;
}
.toggle-link:hover, .toggle-link:focus-visible {
  background: var(--color-primary);
  color: var(--color-white);
}
@media (max-width: 600px) {
  .toggle-link { flex: 1 1 auto; justify-content: center; }
}

.pills {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  padding: 0;
  margin: var(--space-md) 0;
}
@media (max-width: 768px) {
  .pills { justify-content: center; }
}

/* ============================================================
   Breadcrumb (shared)
   ============================================================ */
.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  align-items: center;
  font-size: var(--fs-sm);
  color: var(--color-fg-muted);
  margin: 0 0 var(--space-sm);
}
.breadcrumb a {
  color: var(--color-primary);
  text-decoration: none;
}
.breadcrumb a:hover { text-decoration: underline; }
.breadcrumb-sep { color: var(--color-border); }
.breadcrumb-current { color: var(--color-fg-muted); }

/* ============================================================
   Callout (used in kempy detail for warning messages)
   ============================================================ */
.callout {
  padding: var(--space-md);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-bg-soft);
  margin: var(--space-md) 0;
  font-size: var(--fs-sm);
}
.callout--warn {
  background: #fef5e7;
  border-color: var(--color-warn);
  color: var(--color-warn);
}

/* ============================================================
   Compliance popover — TECH-031 v7 (Variant C-i)
   Shared element pro desktop (position: fixed, JS anchor pod pill) +
   mobile (bottom-sheet modal). Default `hidden` v markup → JS toggle.
   Position dispatched JS-only (matchMedia(max-width:768px)) — desktop
   používá JS-computed top/left k anchor pod pillem; mobile používá
   .compliance-popover--sheet modifier z atlas-mobile-sheet.css pro fixed
   bottom-sheet layout.
   Spec: docs/design/2026-05-21-compliance-banner-v7-variant-c-refined.md (sekce 5).
   Base CSS (utility-level) → shared napříč entry pages (index + kempy_index).
   ============================================================ */
.compliance-popover {
  /* Desktop default — JS nastaví top + left inline style při open.
     position: fixed > position: absolute kvůli mobile bottom-sheet variant
     (parent ancestor s `position: relative` by clipnul absolute child;
     fixed bypassuje containing block issue + funguje stejně pro mobile sheet). */
  position: fixed;
  /* TECH-031 v8 fix A: popover MUSÍ být nad .filter-bar (z-index 1100) na desktop.
     v7 hodnota 40 mile pod filter-bar → překryv. Nová hodnota 1200 = nad filter-bar
     i nad veškerý sticky content; pod filter-sheet (10000) která je full-screen modal. */
  z-index: 1200;
  min-width: 280px;
  max-width: min(360px, calc(100vw - var(--space-md) * 2));
  background: var(--color-bg);
  color: var(--color-fg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: 0 4px 16px rgba(15, 42, 61, 0.15);
  padding: var(--space-md);
  font-size: var(--fs-sm);
  line-height: var(--lh-base);
  /* Animate-in — opacity + drobný slide. Reduced motion override níže. */
  animation: compliance-popover-fade 150ms ease-out;
}
.compliance-popover[hidden] {
  /* Hidden attribute respect — explicitní display: none override
     (některé browser stylesheets prioritizují flex/block z .compliance-popover). */
  display: none;
}
.compliance-popover__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-bottom: var(--space-sm);
}
.compliance-popover__title {
  margin: 0;
  font-size: var(--fs-base);
  font-weight: 700;
  color: var(--color-fg);
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
}
.compliance-popover__icon {
  color: var(--color-success);
  font-size: var(--fs-base);
  line-height: 1;
}
.compliance-popover__close {
  /* Button reset + close (×) glyph */
  border: 0;
  background: transparent;
  color: var(--color-fg-muted);
  font-size: var(--fs-lg);
  line-height: 1;
  cursor: pointer;
  padding: 0;
  /* WCAG 2.5.5 touch target — min 44 px (parita s pill button + filter-toggle).
     TECH-031 v7 P1 fix per tech-design conformance check (40 → 44 px). */
  min-width: 2.75rem;
  min-height: 2.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  transition: color 150ms ease, background-color 150ms ease;
}
.compliance-popover__close:hover {
  color: var(--color-fg);
  background: var(--color-bg-soft);
}
.compliance-popover__close:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
.compliance-popover__body p {
  margin: 0;
}
.compliance-popover__body a {
  color: var(--color-primary);
  text-decoration: underline;
}
.compliance-popover__body a:hover {
  color: var(--color-accent);
}

/* Backdrop — desktop hidden (popover je less-modal, klik mimo close),
   mobile visible jako tap-to-close target (per atlas-mobile-sheet.css media query). */
.compliance-sheet-backdrop {
  display: none;  /* hidden default — atlas-mobile-sheet.css ho na ≤768px aktivuje */
}
.compliance-sheet-backdrop[hidden] {
  display: none;
}

@keyframes compliance-popover-fade {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .compliance-popover {
    animation: none;
  }
}

/* ============================================================
   Footer + NLOD attribution
   ============================================================ */
footer {
  margin-top: var(--space-2xl);
  padding-top: var(--space-md);
  border-top: 1px solid var(--color-border);
  font-size: var(--fs-sm);
  color: var(--color-fg-muted);
}
.nlod-attribution {
  margin: 0;
  line-height: 1.5;
}

.empty-state {
  background: var(--color-bg-soft);
  padding: var(--space-md);
  border-radius: var(--radius-md);
  color: var(--color-fg-muted);
  font-style: italic;
}

.noscript-fallback {
  padding: var(--space-md);
  background: var(--color-bg-soft);
  border-radius: var(--radius-md);
}

/* ============================================================
   Strip — sezónní heat strip (sdíleno landing + kempy + detail)
   ============================================================ */
.strip {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 2px;
  width: 100%;
  background: var(--color-bg-soft);
  border-radius: var(--radius-sm);
  padding: 2px;
}
.strip__cell {
  position: relative;
  background: var(--color-primary);
  /* opacity řízeno per-cell přes --intensity custom property z makra */
  opacity: calc(0.15 + var(--intensity, 0) * 0.85);
  border-radius: 2px;
  display: flex;
  flex-direction: column;     /* iter 3.5: 3 řádky (měsíc / count / pct) místo 1 label */
  align-items: center;
  justify-content: center;
  gap: 1px;
  font-size: 0.65rem;
  color: var(--color-white);
  font-weight: 600;
  min-height: 14px;
  padding: 2px 1px;
  text-align: center;
  line-height: 1;
}
.strip__cell--peak {
  background: var(--color-accent);
  opacity: 1;
  outline: 1px solid var(--color-accent);
}
/* TECH-045 iter 3.5: 3-řádkový cell content — měsíc (zkratka) + count (počet ryb)
   + pct (% z ročního total). text-shadow zachováno pro čitelnost na světlé části
   gradientu. Legacy .strip__cell-label alias zachován pro případné externí use
   (zatím jen interní; pokud explorer detekuje, smazat v iter 4). */
.strip__cell-month {
  font-size: 0.6rem;
  font-weight: 700;
  text-shadow: 0 1px 1px rgba(15, 42, 61, 0.4);
}
.strip__cell-count {
  font-size: 0.55rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 1px rgba(15, 42, 61, 0.4);
}
.strip__cell-pct {
  font-size: 0.5rem;
  font-weight: 500;
  opacity: 0.85;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 1px rgba(15, 42, 61, 0.4);
}
/* Legacy alias — zachován pro backward compat, pokud někde mimo TECH-045 path
   existuje use. Match s novým .strip__cell-month. */
.strip__cell-label {
  font-size: 0.55rem;
  text-shadow: 0 1px 1px rgba(15, 42, 61, 0.4);
}
.strip--md .strip__cell { min-height: 48px; font-size: 0.7rem; }
.strip--lg .strip__cell { min-height: 64px; font-size: 0.8rem; }
.strip--md .strip__cell-month,
.strip--lg .strip__cell-month { font-size: 0.7rem; }
.strip--md .strip__cell-count,
.strip--lg .strip__cell-count { font-size: 0.65rem; }
.strip--md .strip__cell-pct,
.strip--lg .strip__cell-pct { font-size: 0.6rem; }
.strip--lg .strip__cell-label { font-size: 0.7rem; }

/* `sm` strip cells: drobnější, vhodné pro ranking sidebar.
   Iter 3.5: na desktop pořád zobrazujeme měsíc + count + pct (i v sm), ale
   condensed fonty. Na mobile (≤600px) sm strip cells skryjí count/pct a nechají
   jen měsíc (cells úzké, 3 řádky se nevejdou). */
.strip--sm .strip__cell {
  /* TECH-045 iter 3.16: redukce z 38px → 26px (founder image #5).
     landing ranking-card + /kempy/ camp-grid rendering pouze .strip__cell-label
     (1 span "Le", "Ún", ...), žádné count/pct → kompaktní square-ish badge
     bez rizika overflow. Detail page (.strip--md / --lg) zachován. */
  min-height: 26px;
}
.strip--sm .strip__cell-month {
  font-size: 0.55rem;
  line-height: 1;
}
.strip--sm .strip__cell-count {
  font-size: 0.5rem;
}
.strip--sm .strip__cell-pct {
  font-size: 0.48rem;
}
.strip--sm .strip__cell-label {
  font-size: 0.6rem;
  line-height: 1;
}
@media (max-width: 600px) {
  .strip--sm .strip__cell {
    min-height: 22px;
  }
  .strip--sm .strip__cell-count,
  .strip--sm .strip__cell-pct {
    display: none;            /* mobile sm: jen měsíc */
  }
  .strip--sm .strip__cell-label {
    display: none;
  }
  /* TECH-045 iter 3.6: md/lg strips na mobile schovají count, nechají jen měsíc + pct
     (founder UX 2026-05-20, image #9). Cell na mobile je úzký, 3 řádky se vejdou,
     ale count s thousand separator + tabular nums přetéká. Pct (max 4 char „100%")
     je kompaktnější a stačí jako kvantitativní hint. min-height redukováno
     (3-line → 2-line) — žádný zbytečný white-space. */
  .strip--md .strip__cell-count,
  .strip--lg .strip__cell-count {
    display: none;
  }
  .strip--md .strip__cell { min-height: 32px; }
  .strip--lg .strip__cell { min-height: 44px; }
}

/* ============================================================
   Hero — variants used across pages
   ============================================================ */
.hero {
  margin: 0 0 var(--space-xl);
  padding: var(--space-xl) 0;
}
.hero--compact {
  padding: var(--space-lg) 0 var(--space-md);
  margin-bottom: var(--space-md);
}
.hero-title {
  font-size: var(--fs-2xl);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  line-height: var(--lh-tight);
  color: var(--color-fg);
  margin: 0 0 var(--space-xs);
}
/* TECH-045 iter 3.8: hero title je klikatelný link na "/" (reset filtrů).
   Vypadá jako brand-text (žádný underline default), on-hover/focus affordance
   prozradí klikatelnost. Stejné pravidlo platí pro mobile `.top-bar__title`
   (změněn ze <span> na <a> v iter 3.8). */
.hero-title__link,
a.top-bar__title {
  color: inherit;
  text-decoration: none;
}
.hero-title__link:hover,
.hero-title__link:focus-visible,
a.top-bar__title:hover,
a.top-bar__title:focus-visible {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 4px;
}
.hero-sub {
  font-size: var(--fs-md);
  color: var(--color-fg-muted);
  margin: 0 0 var(--space-sm);
  font-weight: 400;
}
.hero-stats-badge {
  font-size: var(--fs-sm);
  color: var(--color-fg-muted);
  margin: 0;
}
.hero-stats-badge strong {
  color: var(--color-primary);
  font-size: var(--fs-base);
}

/* TECH-045 iter 3.14 (founder Image #1, 2026-05-20): mobile parita
   `.hero-meta` — stacked column wrapper pro `.top-bar__count` + `.top-bar__hint`
   uvnitř `.top-bar__title-row` v `.top-bar__mobile-header`. Sdílený selektor
   (žije v atlas-base.css aby fungoval napříč všemi 3 page typy: landing,
   kempy_index, kempy_camp detail, které mají vlastní per-page CSS overridy
   pro `.top-bar__title-row` ale `.top-bar__meta` nemusí každý duplikovat).

   Mechanika identická s desktop `.hero-meta` (atlas-landing.css):
   - column direction + align-items: flex-end → pill nad hintem, oba right.
   - gap: var(--space-2xs) → minimal vertical spacing.
   - flex-shrink: 0 → wrapper drží svou width vůči flex-growing title. */
.top-bar__meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-2xs);
  flex-shrink: 0;
  /* TECH-045 iter 3.14 fix-loop #1 BLOCKER #1: insurance proti wrap break.
     Pokud by title flex-grew (1 1 0 ale obsah víc než dostupný prostor po
     meta), `margin-left: auto` push meta-wrapper vpravo i kdyby flex-wrap
     vyvolal nový řádek. Belt-and-suspenders k flex 1 1 0 + min-width 0
     na `.top-bar__title`. */
  margin-left: auto;
}

/* ============================================================
   Filter bar — shared form layout (per-page CSS overrides spacing)
   ============================================================ */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  align-items: end;
  margin: 0 0 var(--space-md);
  padding: var(--space-md);
  background: var(--color-bg-soft);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  /* Iter 2.4 fix: vlastní stacking context (vyšší než Leaflet pane 400–1000)
     aby help popovery byly NAD mapou. Bez tohoto by .filter-help-text
     i s z-index 100 zmizel za #bubble-map (sibling stacking order). */
  position: relative;
  z-index: 1100;
}
.filter-bar__chip {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  flex: 1 1 140px;
  min-width: 140px;
}
.filter-bar__label {
  font-size: var(--fs-xs);
  color: var(--color-fg-muted);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  font-weight: 600;
}
.filter-bar select {
  padding: var(--space-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  color: var(--color-fg);
  font-family: inherit;
  font-size: var(--fs-sm);
  min-height: 44px; /* touch target */
  cursor: pointer;
}
.filter-bar select:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-color: var(--color-accent);
}
.filter-bar__reset {
  padding: var(--space-sm) var(--space-md);
  font-size: var(--fs-sm);
  font-weight: 600;
  background: var(--color-bg);
  color: var(--color-primary);
  border: 1px solid var(--color-primary);
  border-radius: var(--radius-sm);
  cursor: pointer;
  min-height: 44px;
  flex: 0 0 auto;
}
.filter-bar__reset:hover, .filter-bar__reset:focus-visible {
  background: var(--color-primary);
  color: var(--color-white);
}

/* ============================================================
   Sticky controls — top-bar + filter-bar zůstávají nahoře viditelné
   při scrollu (hero se schová). Native `position: sticky`, žádný JS
   scroll handler (pouze data-scrolled attribut toggle).

   Shared pattern landing + kempy index (extracted z atlas-kempy.css
   iter 2.15 — paritní mobile auto-collapse na obou stránkách).

   Full-bleed trick: `margin: 0 calc(-1 * var(--space-md))` rozšíří
   sticky pruh přes `<main>` padding (1rem) → background pokrývá
   plnou šířku viewportu při scrollu, jinak by prosvítal content.

   z-index 50 = nad camp-grid (static flow), pod .filter-bar
   stacking context (1100) takže popovery `.filter-help-text`
   uvnitř .filter-bar zůstávají naviditelné.
   ============================================================ */
.sticky-controls {
  /* TECH-042 iter 8 (founder Image #8): position: sticky vrátí na pure mobile.
     Na desktop byl sticky-controls po scroll překryjícím vrchol ranking sidebar
     vpravo — sticky behavior tady nemá smysl (mapa má fixed height 70vh
     viditelná celá, žádný důvod stick controls). Position: static = normal flow,
     posune se s page scroll. Iter 7 opaque background zachován pro mobile use case
     (kde sticky-controls position: fixed overlayem nad full-screen mapou). */
  position: static;
  z-index: 50;
  margin: 0 calc(-1 * var(--space-md));
  padding: 0 var(--space-md);
  background: var(--color-bg);
  box-shadow: none;
  transition: box-shadow 0.15s ease;
}
.sticky-controls[data-scrolled="true"] {
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}
/* Sticky pouze na mobile breakpoint (≤600px) — TECH-040 iter 2.11/2.15 logika
   auto-collapse + tap-to-expand. Desktop má position: static (viz výše). */
@media (max-width: 600px) {
  .sticky-controls {
    position: sticky;
    top: 0;
  }
}

/* Mobile: full-bleed na menší page padding (`--space-sm`). Vertical padding nadále 0. */
@media (max-width: 600px) {
  .sticky-controls {
    margin: 0 calc(-1 * var(--space-sm));
    padding: 0 var(--space-sm);
  }
}

/* ============================================================
   Iter 2.11 — Filtry toggle button (mobile auto-collapse pattern).
   At-top (scrollY < 80px): button hidden, filter-bar visible (default).
   Scrolled (≥80px): button visible, filter-bar default hidden.
   User klikne toggle → filter-bar re-visible (data-filter-expanded override),
   icon flipne (▾ → ▴ via CSS transform). Desktop (>600px): button vždy hidden,
   filter-bar vždy visible — scroll listener data attrs ignorované media query.
   JS handler: initStickyFilterCollapse() v atlas-filters.js.
   ============================================================ */
.filter-toggle {
  display: none;  /* default hidden — desktop vždy, mobile dokud nejsme scrolled */
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-sm) var(--space-md);
  background: var(--color-bg);
  color: var(--color-primary);
  border: 1px solid var(--color-primary);
  border-radius: var(--radius-md);
  font-family: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  min-height: 44px;
  cursor: pointer;
  white-space: nowrap;
}
.filter-toggle:hover,
.filter-toggle:focus-visible {
  background: var(--color-primary);
  color: var(--color-white);
}
.filter-toggle:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
.filter-toggle__icon {
  transition: transform 0.15s ease;
  display: inline-block;
  line-height: 1;
}
.filter-toggle[aria-expanded="true"] .filter-toggle__icon {
  transform: rotate(180deg);
}

@media (max-width: 600px) {
  /* Mobile po scrollu: zobraz Filtry button, hide filter-bar (default collapse). */
  .sticky-controls[data-scrolled="true"] .filter-toggle {
    display: inline-flex;
  }
  .sticky-controls[data-scrolled="true"] .filter-bar {
    display: none;
  }
  /* User klik na Filtry → expand override (re-display filter-bar).
     Vrací stejný display jako default .filter-bar (`flex` v atlas-base.css L447). */
  .sticky-controls[data-scrolled="true"][data-filter-expanded="true"] .filter-bar {
    display: flex;
  }
}

/* ============================================================
   Identify score (TECH-038 — used in landing + can be reused)
   ============================================================ */
.identify-score {
  background: var(--color-bg-soft);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-md);
  margin: var(--space-lg) 0;
}
.identify-score h2 {
  margin: 0 0 var(--space-sm);
  font-size: var(--fs-base);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--color-fg-muted);
}
.score-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-sm);
}
.score-cell {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-sm);
  text-align: center;
}
.score-value {
  display: block;
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: 700;
  margin-bottom: var(--space-xs);
  color: var(--color-fg);
}
.score-label {
  display: block;
  font-size: var(--fs-xs);
  color: var(--color-fg-muted);
}
.score-good { border-left: 3px solid var(--color-success); }
.score-warn { border-left: 3px solid var(--color-warn); }
.score-pending { border-left: 3px solid var(--color-fg-muted); }
.score-pct { border-left: 3px solid var(--color-primary); }
.identify-score .hint {
  margin: var(--space-sm) 0 0;
  font-size: var(--fs-sm);
  color: var(--color-fg-muted);
}

/* ============================================================
   Responsive baseline — mobile-first
   ============================================================ */
@media (min-width: 768px) {
  main {
    padding: var(--space-xl) var(--space-lg);
  }
  .hero-title { font-size: var(--fs-3xl); }
  .hero--compact .hero-title { font-size: var(--fs-2xl); }
}

@media (min-width: 1200px) {
  main {
    max-width: 1200px;
  }
}

/* Mobile fine-tune (< 600px) */
@media (max-width: 600px) {
  h1 { font-size: var(--fs-lg); }
  h2 { font-size: var(--fs-base); }
  .hero-title { font-size: var(--fs-lg); }
  .score-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-sm);
  }
  .filter-bar { padding: var(--space-sm); }
  .filter-bar__chip { flex-basis: 100%; }
}

/* ===========================================================================
   TECH-042 iter 6 (founder report 2026-05-17 18:30): Leaflet 1.9+ nastavuje
   na .leaflet-tile vlastnost `mix-blend-mode: plus-lighter` (additive blending),
   která způsobuje viditelné bílé pruhy na hranicích sousedních tiles — vypadá
   to jako mřížka poledníků a rovnoběžek. Override na default `normal` blend
   ji odstraní. Globální fix — aplikuje se na landing mapu i camp detail mapu.
   Reference: https://github.com/Leaflet/Leaflet/issues/8783
   =========================================================================== */
.leaflet-container img.leaflet-tile {
  /* !important nutné — leaflet.css se loaduje AFTER atlas-base.css v <head>,
     stejná specificity → bez !important by leaflet.css vyhrál cascade. */
  mix-blend-mode: normal !important;
}

/* ===========================================================================
   TECH-042 iter 21 (founder 2026-05-17 22:15): persistent footer bar dole
   na všech mobilních stránkách — landing (.page-footer page-footer--main),
   /kempy/ + camp detail (main > footer). Stejná pozice, stejný visual.
   atlas-base.css je shared napříč všemi stránkami (zatímco atlas-mobile-sheet.css
   loaduje JEN landing). Per-stránka override (sheet bottom, body padding) zůstává
   v atlas-mobile-sheet.css.
   =========================================================================== */
@media (max-width: 768px) {
  .page-footer--main,
  main > footer {
    display: block;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 40;  /* nad sheet (z-index 20) + Leaflet (default 1) */
    background: var(--color-bg);
    border-top: 1px solid var(--color-border);
    padding: 6px var(--space-md) calc(6px + env(safe-area-inset-bottom));
    margin: 0;
    text-align: center;
    font-size: var(--fs-xs);
    line-height: 1.3;
  }
  .page-footer--main .nlod-attribution,
  main > footer .nlod-attribution {
    margin: 0;
    color: var(--color-fg-muted);
    font-size: var(--fs-xs);
  }
  /* Body padding-bottom aby content scroll-end nebyl překrytý fixed footer.
     /kempy/ + camp detail scrollují page (žádný fixed sheet) — potřebují space. */
  body {
    padding-bottom: 28px;
  }
}

/* TECH-045 iter 3.14 fix-loop #1 BLOCKER #2 (2026-05-20): `@media (max-width: 420px)
   { .top-bar__hint }` PŘESUNUTO z atlas-base.css do 3 mobile CSS souborů
   (atlas-mobile-sheet, atlas-kempy, atlas-detail). Důvod: cascade order +
   specificity — `atlas-mobile-sheet.css` měl pozdější `@media (max-width: 768px)
   { .top-bar__hint { font-size: var(--fs-sm) } }` přebíjející base 420px override,
   `atlas-detail.css` měl vyšší specificity scoped selector přebíjející base.
   Per-page 420px override v každém z 3 page CSS souborů řeší obojí. */
