/* ════════════════════════════════════════════════════════════
   01-base.css

   Reset, a11y (focus ring, skip-link), ikony, animace, utility, backdrop,
   scroll progress. Nic vizualne znackoveho - jen zaklad, na kterem stoji zbytek.

   Cast verejneho stylu. Soubory se nactou v poradi podle nazvu
   (`assets.PUBLIC_CSS`) a kaskada zavisi na tom poradi - nemenit ho
   a nove pravidlo psat do souboru, kam patri obsahove.
   ════════════════════════════════════════════════════════════ */

/* ════════════════════════════════════════════════════════════
   RESPAWN Laser Arena — neonový vzhled podle brand manuálu
   (`static/DESINGER_SOUBORY/guidelines.pdf`).

   Tři pravidla, o která se opírá všechno níž:
   1. Barva svítí, plocha ne. Pozadí je skoro černé (--bg), povrchy jsou
      dva tmavé teal odstíny (--surface, --surface-2) a JEDINÁ svítící barva
      je --accent. Druhá zář v jednom pohledu ruší efekt obou.
   2. Neonové prvky jsou primitiva, ne jednorázové kusy CSS: .puls,
      .neon-frame a .pill. Nový prvek se skládá z nich, nekopíruje se.
   3. Beon (--font-display) jen na krátké verzálkové nadpisy. Je to stencil —
      v odstavci a pod ~18 px se jeho mezery slijí a text zmizí. Všechno
      ostatní včetně nadpisu hera je Space Grotesk (--font), tak to má
      i designer v návrzích.

   Funkční komponenty (kalendář, formuláře, admin) zůstávají token-driven.
   ════════════════════════════════════════════════════════════ */

/* ── RESET ───────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
/* overflow-x: clip i na <html> — samotné `hidden` na <body> viewport
   neuhlídá (Safari/Chrome na mobilu se pak dá odsunout do strany), a `clip`
   na rozdíl od `hidden` nedělá ze stránky scroll kontejner, takže sticky
   prvky dál fungují. */
html { scroll-behavior: smooth; overflow-x: clip; }

/* Záloha pro prohlížeče bez `overflow-x: clip` (Safari < 16). Je schválně
   za `@supports`: `overflow-x: hidden` na <body> z něj v iOS Safari udělá
   scroll kontejner, což rozbíjí setrvačnost scrollu a chování
   `position: fixed` hlavičky. Tam, kde `clip` na <html> funguje (dnes
   všude), tohle pravidlo nevznikne vůbec. */
@supports not (overflow-x: clip) {
  body { overflow-x: hidden; }
}

/* iOS: DVA RYCHLE TAPY NA TLACITKO = PRIBLIZENI STRANKY.
   V pruvodci se to trefuje presne do „+" u poctu her — nikdo neklika jednou,
   takze se stranka zvetsila a (spolu s doskrolovanim na priblizeny prvek)
   vypadalo to, jako by se nacetla jina stranka.
   `manipulation` vypne JEN dvojklik-zoom. Posouvani i pinch-zoom zustavaji,
   takze pristupnost tim netrpi — na rozdil od `maximum-scale=1` ve viewportu,
   ktere zvetsovani zakaze uplne a delat se nesmi.
   Je to pravidlo na ELEMENTECH (specificita 0,0,1), aby ho pozdejsi tridy
   mohly prebit: 3D prohlizece potrebuji `pan-y` a joystick `none`. */
button,
summary,
[role="button"],
input[type="checkbox"],
input[type="radio"],
label.wiz-chip,
.btn,
.pill {
  touch-action: manipulation;
}

/* ── A11Y: viditelný focus ring pro klávesnici (celý web) ──
   Myš/dotyk focus neruší (jen :focus-visible). Formulářové inputy
   mají vlastní focus styl níž, tlačítka/odkazy/kalendář dědí tenhle. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 3px;
}
:focus:not(:focus-visible) { outline: none; }

/* ── A11Y: přeskočení navigace ──
   Skrytý mimo obrazovku, při zaostření klávesnicí se vysune. Nepoužívat
   display:none — to by ho vyřadilo i z pořadí tabů, tedy přesně z toho,
   kvůli čemu existuje. `main` má tabindex="-1", aby na něj skok opravdu
   přesunul fokus (jinak čte screen reader dál od navigace). */
.skip-link {
  position: fixed;
  top: 0; left: 50%;
  transform: translate(-50%, -110%);
  z-index: 200;
  padding: .7rem 1.2rem;
  background: var(--accent); color: var(--accent-ink);
  font-weight: 600; text-decoration: none;
  border-radius: 0 0 var(--radius) var(--radius);
  transition: transform var(--d-pop) var(--ease-out);
}
.skip-link:focus { transform: translate(-50%, 0); }
main:focus { outline: none; }

/* ── Inline SVG ikony (partials/icons.html) — škálují s font-size ── */
.ic {
  width: 1em; height: 1em; flex: none;
  display: inline-block; vertical-align: -0.125em;
}
.ic-lead { margin-right: .45em; }
/* Znackova loga (Instagram, TikTok, YouTube) jsou VYPLNENE glyfy, ne tahy
   o sirce 2 jako zbytek sady. Pri stejne velikosti proto opticky vazi vic,
   takze se o kousek zmensuji, aby v rade s ostatnimi ikonami nekricela. */
.ic-brand { width: .92em; height: .92em; }
body {
  font-family: var(--font);
  margin: 0; padding: 0;
  background: var(--bg); color: var(--text);
  -webkit-font-smoothing: antialiased;
  line-height: 1.55;
  /* Sticky footer: obsah roztáhne stránku, footer drží dole.
     `svh`, NE `dvh`. `dvh` se na telefonu mění průběžně, jak se skrývá a
     vysouvá adresní řádek — takže při každém rychlém scrollu se přepočítávala
     minimální výška <body>, což je layout celé stránky uprostřed setrvačného
     pohybu. Přesně to bylo cítit jako „stránka mě kopne". `svh` je nejmenší
     (stabilní) viewport, takže se nemění nikdy a patička dosedne i ve chvíli,
     kdy je adresní řádek vidět. */
  min-height: 100svh;
  display: flex; flex-direction: column;
}
/* Hlavička je `position: fixed`, takže si obsah musí odsazení uhlídat sám.
   Je tady, a ne v každé stránce zvlášť, aby přidání položky do navigace
   (= vyšší header) nezvedlo úkol projít šestnáct šablon. */
main { flex: 1 0 auto; padding-top: var(--nav-h); }
h1 {
  color: var(--text-strong);
  font-family: var(--font); font-weight: 700;
  letter-spacing: -0.025em; line-height: 1.05;
}
h2 {
  margin-top: 0; font-size: 1.15rem;
  font-family: var(--font); font-weight: 700; letter-spacing: -0.01em;
}
a { color: inherit; }

/* ── ANIMATIONS ──────────────────────────────────── */
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Scroll reveal (motion.js doplní .visible)
   Krátká dráha + krátký čas. Dlouhý reveal nevypadá elegantně, jen pomalu. */
.reveal {
  opacity: 0; transform: translateY(10px);
  transition: opacity var(--d-reveal) var(--ease-out),
              transform var(--d-reveal) var(--ease-out);
  transition-delay: var(--rd, 0s);
}
.reveal.visible { opacity: 1; transform: none; }

[data-reveal] {
  opacity: 0; will-change: transform, opacity;
  transition: opacity var(--d-reveal) var(--ease-out),
              transform var(--d-reveal) var(--ease-out);
  transition-delay: var(--rd, 0s);
}
[data-reveal="up"]    { transform: translateY(18px); }
[data-reveal="left"]  { transform: translateX(-24px); }
[data-reveal="right"] { transform: translateX(24px); }
[data-reveal="scale"] { transform: scale(.97); }
[data-reveal].visible { opacity: 1; transform: none; }

/* Hero titulek po řádcích — 3 kroky po 60 ms, ne jeden blok.
   Nadpis sám se nehýbe (jinak by se pohyb sčítal), animují jen řádky;
   .reveal na něm zůstává jen kvůli tomu, aby dostal .visible. */
.hero-title.reveal { opacity: 1; transform: none; }
.hero-title .hl {
  display: block; opacity: 0; transform: translateY(12px);
  transition: opacity 340ms var(--ease-out), transform 340ms var(--ease-out);
  transition-delay: var(--hl-d, 0s);
}
.hero-title.visible .hl { opacity: 1; transform: none; }

/* ── UTILITIES ───────────────────────────────────── */
.hidden { display: none !important; }
.muted { color: var(--muted); }
.small { font-size: .85rem; }
.lead { color: var(--muted); font-size: 1.05rem; line-height: 1.6; }
.container { max-width: var(--maxw); margin: 0 auto; }
/* Text jen pro odečítače obrazovky (např. <caption> tabulky, kde nadpis nad ní
   nese význam vizuálně). `display:none` by ho skryl i před nimi. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ── BACKDROP ──
   Manuál má na pozadí „PATTERN": tenké protínající se laserové paprsky.
   Kreslí se v CSS gradienty, ne obrázkem — je to pár set bajtů místo dalšího
   requestu a škáluje to na jakýkoli viewport.

   BARVA JE DODANÁ DESIGNÉREM: `--beam` = #0f2719. Není odvozená z akcentu a
   nesmí se „doladit od oka" — proti pozadí (#000E12) je to velmi malý rozdíl
   a přesně o tu polohu jde. Dřív tu byla průhledná zelená přes `rgba()` +
   `opacity: .5`, což nad tmavým podkladem četlo neutrálně šedě — právě to,
   na co designér ukazoval. Plná neprůhledná barva se aspoň nemá jak posunout.

   Kresba je ZÁMĚRNĚ nepravidelná: různé úhly, různé pozice, občasné křížení.
   Ne mřížka, ne raster — na geometrii nezáleží, záleží na tom, aby si toho
   člověk všiml až při druhém pohledu.

   `.arena-bg` je `position: fixed` a nic tu není animované: pozadí se při
   scrollu NEPŘEPOČÍTÁVÁ. Homepage má na mobilu přes 10 000 px a cokoli, co by
   se počítalo za snímek scrollu, by ji položilo.

   POZOR na `.neon-frame`: jeho přerušení se kreslí „gumami" v barvě
   `--frame-bg` (= barva pozadí za rámečkem). Paprsek, který projede přesně
   pod přerušením, se v něm na pár pixelů ztratí. Proto musí mít každý panel,
   který leží PŘÍMO na pozadí stránky, vlastní neprůhlednou plochu
   (`.hero-panel`, `.err-panel` — viz tam); u karet na `--surface` je přerušení
   1px široké a při téhle barvě není co vidět. Nová plná plocha pod rámečkem
   znamená přenastavit `--frame-bg`. */
.arena-bg {
  position: fixed; inset: 0; z-index: -1;
  overflow: hidden; background: var(--bg); pointer-events: none;
}
.arena-beams {
  /* Kolo 4 (7. 9.): docasne skryto ("jen jednolita barva"), pak ve stejnem
     kole zase vraceno zpet ("random cary, co se nespojujou") - presne to,
     co scripts/check_beams.py dole hlida (zadne rovnobezky, zrcadla ani
     trojice v jednom bode). Zustava zapnute. */
  position: absolute; inset: -20%;
  /* Úhly a odsazení NEJSOU napsané od oka — jsou výsledek hledání ve
     `scripts/check_beams.py`, které na sedmi tvarech okna (mobil, tablet,
     desktop, FullHD, vysoký mobil, 2K, 4K) ověřuje tři věci:
       1. žádné dvě čáry nejsou skoro rovnoběžné (< 9°) — dvojice rovnoběžek
          se čte jako kolejnice, tedy jako vzor;
       2. žádná dvojice není zrcadlová (|a + b − 180| < 11°) — dvě čáry
          symetrické podle svislice tvoří „véčko" a pár véček už je rytmus;
       3. žádnou trojicí čar neprochází skoro jeden bod — tři čáry v jednom
          místě vypadají jako hvězda, tedy jako záměr.
     Přesně tohle byla vada předchozí sady: všech deset úhlů leželo mezi 64°
     a 117°, takže z čar byl pravidelný zig-zag, který se navíc potkával
     u horní a dolní hrany okna. Kdo čísla mění, pustí skript znovu:
         python scripts/check_beams.py            # ověří současnou sadu
         python scripts/check_beams.py --search   # najde novou
     Čára jde vždycky přes celou plochu, nikdy jako kus useknutý uprostřed:
     konec čáry ve vzduchu vypadá jako chyba vykreslení, ne jako paprsek. */
  background-image:
    linear-gradient(7deg, transparent calc(85% - 1px), var(--beam) 85%, transparent calc(85% + 1px)),
    linear-gradient(51deg, transparent calc(25% - 1px), var(--beam) 25%, transparent calc(25% + 1px)),
    linear-gradient(61deg, transparent calc(76% - 1px), var(--beam) 76%, transparent calc(76% + 1px)),
    linear-gradient(70deg, transparent calc(5% - 1px), var(--beam) 5%, transparent calc(5% + 1px)),
    linear-gradient(79deg, transparent calc(88% - 1px), var(--beam) 88%, transparent calc(88% + 1px)),
    linear-gradient(89deg, transparent calc(66% - 1px), var(--beam) 66%, transparent calc(66% + 1px)),
    linear-gradient(143deg, transparent calc(37% - 1px), var(--beam) 37%, transparent calc(37% + 1px)),
    linear-gradient(153deg, transparent calc(74% - 1px), var(--beam) 74%, transparent calc(74% + 1px)),
    linear-gradient(162deg, transparent calc(56% - 1px), var(--beam) 56%, transparent calc(56% + 1px));
}
/* Mekky prechod dela SAMOTNY gradient, ne `filter: blur(130px)`. Rozmazani
   nutilo prohlizec vyrobit pro kazdou zar zvlastni rasterovou plochu (a to
   na KAZDE strance, `.arena-bg` je v base.html) — u 130px polomeru je ta
   plocha nekolikanasobek prvku. Gradient, ktery uz na 70 % dojede do nuly,
   vypada na 10% krytí stejne a nestoji nic. */
/* Kolo 4 (7. 9.): stejny duvod jako u .arena-beams - pozadi ma byt
   jednolita barva, ne barevny svit v rozich. */
.arena-glow { display: none; position: absolute; width: 60vw; height: 60vw; border-radius: 50%; opacity: .10; }
.arena-glow-blue { top: -22%; left: -16%; background: radial-gradient(circle, var(--accent) 0%, rgba(105,188,68,.45) 35%, transparent 72%); }
.arena-glow-red  { bottom: -26%; right: -16%; background: radial-gradient(circle, var(--accent) 0%, rgba(105,188,68,.45) 35%, transparent 72%); }

/* ── SCROLL PROGRESS (tenký, jednobarevný) ── */
.scroll-progress {
  position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 200;
  background: var(--accent);
  transform: scaleX(0); transform-origin: left;
  will-change: transform;
}
