/* Pierwszy ekran przed załadowaniem aplikacji (`index.html`, `#first-paint`) i wspólny układ pierwszej wizyty (`.fv`,
   `components/first-visit.ts`). Plik z `public/`, ładowany w <head>: działa bez paczki aplikacji, więc kolory mają wartości
   zapasowe zamiast samych tokenów z `styles.css`, a CSP (`style-src 'self'`) zostaje bez wyjątków.
   Audyt 24.10.2026: pusty `<div id="app">` dawał 1–2,5 s czarnego ekranu, a pierwszym czytanym tekstem był baner cookies.
   Gość z wejścia (`.fp-entry` z `theme-boot.js`) widzi planszę partii operowej i obietnicę; reszta tylko znak na tle. */
/* Szeryf tytułu (pakiet wyglądu 25.10.2026): ten sam plik i te same zakresy co `@font-face` w `src/web/styles/pismo.css`. */
@font-face {
  font-family: 'Newsreader'; font-style: normal; font-weight: 200 800; font-display: swap;
  src: url(/fonts/newsreader-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Newsreader'; font-style: normal; font-weight: 200 800; font-display: swap;
  src: url(/fonts/newsreader-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
#first-paint { position: fixed; inset: 0; z-index: 1; background: var(--bg, #121110); }
#first-paint.is-leaving { opacity: 0; transition: opacity .18s ease-out; pointer-events: none; }
/* Komputer: w miejscu paska portalu pas z tym samym tłem i znakiem (pierwsza wizyta stoi pod prawdziwym paskiem). */
#first-paint .fp-bar { display: none; }
#first-paint .fp-mark { position: absolute; left: 50%; top: 50%; width: 40px; height: 40px; translate: -50% -50%; opacity: .9; }
.fp-entry #first-paint .fp-mark, #first-paint .fv { display: none; }
.fp-entry #first-paint .fv { display: grid; }

/* Układ pierwszej wizyty: telefon = znak, tytuł, plansza, panel; komputer = tytuł i panel po lewej, plansza po prawej
   (pakiet wyglądu 25.10.2026: czyta się od obietnicy do planszy, jak w kierunku „Dowód”). */
.fv {
  position: fixed; inset: 0; overflow-y: auto; overscroll-behavior: contain;
  background: var(--bg, #121110); color: var(--text, #f3eee5);
  font-family: "IBM Plex Sans Variable", "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  grid-template-columns: minmax(0, 1fr); align-content: start; gap: 0;
  /* Baner cookies przykrywa dół pierwszej wizyty zamiast go rezerwować (Kacper 26.10.2026: plansza jest najważniejsza, okno zgody
     może zasłonić inne elementy); dawna rezerwa `--consent-h` zmniejszała planszę aktu 3 na telefonie do miniatury. */
  padding: max(16px, env(safe-area-inset-top)) 16px 16px;
}
/* Tło pierwszej wizyty: kadr gór z Dziś (decyzja Kacpra 24.10.2026), wyraźniejszy niż pod treścią strony Dziś, bo tu jest
   jedynym obrazem obok planszy. Kadr górny wygaszany ku dołowi, dolny ku górze; środek to tło strony. */
.fv-art { position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.fv-art img { position: absolute; left: 0; width: 100%; height: auto; display: block; }
.fv-art-top { top: 0; opacity: .6; -webkit-mask-image: linear-gradient(to bottom, #000 40%, transparent 96%); mask-image: linear-gradient(to bottom, #000 40%, transparent 96%); }
.fv-art-bottom { bottom: 0; opacity: .75; -webkit-mask-image: linear-gradient(to top, #000 45%, transparent 100%); mask-image: linear-gradient(to top, #000 45%, transparent 100%); }
.fv-brand, .fv-head, .fv-side { position: relative; z-index: 1; }
.fv-board-slot { z-index: 1; }
/* Logo większe i nad szachownicą (Kacper 24.10.2026): na telefonie pierwszy wiersz, na komputerze nad kolumną planszy. */
/* Wiersz logo zajmuje całą szerokość, ale kliknięcia łapią tylko znak i nazwa: flaga celu na szczycie (w kadrze pod spodem)
   ma być do kliknięcia obok nich. */
.fv-brand { display: flex; align-items: center; height: 48px; margin: 0; pointer-events: none; }
.fv-brand > * { pointer-events: auto; }
.fv-brand img { display: block; height: 32px; width: auto; }
/* Nagłówek pierwszego ekranu (briefing wejścia 25.10.2026): nadtytuł „Twój szachowy warsztat”, obietnica drogi do celu
   szeryfem, pod nią kto z kim gra (Kacper 26.10.2026: w miejscu podpisu o pętli). Te same słowa w `components/first-visit.ts`. */
.fv-head { margin: 8px 0 14px; }
.fv-eyebrow { margin: 0 0 6px; font-size: 14px; font-weight: 500; letter-spacing: .01em; color: var(--muted, #b3aa9c); }
.fv-title {
  margin: 0; font-family: "Newsreader", "Iowan Old Style", "Palatino Linotype", Georgia, serif;
  font-size: 40px; line-height: 1; font-weight: 450; letter-spacing: -.03em;
  color: var(--text, #f3eee5); text-wrap: balance;
}
.fv-board-slot { position: relative; width: min(100%, 62svh); aspect-ratio: 1; justify-self: center; }
.fv-static-board {
  position: absolute; inset: 0; border-radius: 0; overflow: hidden;
  background: #b58863 url("/boards/orzech.svg?v=20261011") 0 0 / 100% 100% no-repeat;
}
.fv-static-board img { position: absolute; width: 12.5%; height: 12.5%; display: block; }
.fv-source { margin: 10px 0 0; font-size: 15px; line-height: 1.4; color: var(--muted, #b3aa9c); text-wrap: balance; }
.fv-panel { margin-top: 16px; min-width: 0; }

/* Tablet w układzie telefonu: tytuł o stopień większy, plansza nadal pod nim. */
@media (min-width: 600px) and (max-width: 900px) { .fv-title { font-size: 52px; } .fv-source { font-size: 17px; } }
/* Telefon jak ekran aplikacji, bez przewijania (Kacper 26.10.2026, zdjęcia z telefonu: przycisk aktu 1 był pod krawędzią).
   U góry logo, obietnica i partia, przy dolnej krawędzi przyklejony dok (`.fv-side`: w aplikacji pasek aktów, zdanie
   kroku i przyciski), a plansza bierze całe miejsce między nimi: kwadrat wpisany w wolny prostokąt (`container-type: size`),
   najwyżej na szerokość ekranu, na środku wolnego miejsca. Dok ma stałą rezerwę `--fv-dock` (wysokość aktu 1), więc plansza
   nie zmienia wielkości między krokami i jest taka sama w tym statycznym ekranie; wyższy dok (akt 3, duże pismo systemu)
   podaje swoją wysokość w `--fv-dock-h` (`first-visit.ts`). Krótki ekran oddaje nadtytuł i zmniejsza tytuł. */
@media (max-width: 900px) {
  .fv {
    --fv-dock: 144px;
    grid-template-rows: auto auto minmax(200px, 1fr);
    padding-bottom: var(--fv-dock-h, calc(var(--fv-dock) + env(safe-area-inset-bottom, 0px)));
  }
  .fv-board-slot { width: 100%; height: 100%; min-height: 0; aspect-ratio: auto; container-type: size; }
  .fv-static-board, .fv-board-slot > .fv-board {
    position: absolute; left: 50%; top: 50%; width: min(100cqw, 100cqh); height: min(100cqw, 100cqh); translate: -50% -50%;
  }
  .fv-side {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 2; box-sizing: border-box;
    min-height: calc(var(--fv-dock) + env(safe-area-inset-bottom, 0px));
    /* Treść od góry doku: podpis partii stoi w tym samym miejscu w statycznym ekranie i w lekcji (akt 1 wypełnia rezerwę). */
    display: flex; flex-direction: column; justify-content: flex-start;
    padding: 12px max(16px, calc((100vw - 600px) / 2)) calc(12px + env(safe-area-inset-bottom, 0px));
  }
  .fv-source { font-size: 14px; }
  .fv-panel { margin-top: 0; }
}
@media (max-width: 900px) and (max-height: 819px) { .fv-eyebrow { display: none; } }
@media (max-width: 900px) and (max-height: 719px) {
  .fv-brand { height: 40px; }
  .fv-head { margin: 4px 0 12px; }
  .fv-title { font-size: 34px; }
}
/* Telefon poziomo: plansza po lewej na całą wysokość, obietnica i dok w kolumnie obok (dok w zwykłym układzie, nie przyklejony). */
@media (max-width: 900px) and (orientation: landscape) and (max-height: 560px) {
  .fv {
    --fv-board: calc(100svh - 24px);
    grid-template-columns: var(--fv-board) minmax(0, 1fr); grid-template-rows: auto auto minmax(0, 1fr);
    column-gap: 24px; align-content: start;
    padding: 12px max(16px, env(safe-area-inset-right, 0px)) 12px max(16px, env(safe-area-inset-left, 0px));
  }
  .fv-brand { grid-column: 2; height: 40px; padding-right: 48px; }
  .fv-head { grid-column: 2; margin: 2px 0 10px; }
  .fv-eyebrow { display: none; }
  .fv-title { font-size: 28px; }
  .fv-board-slot { grid-column: 1; grid-row: 1 / span 3; height: auto; aspect-ratio: 1; align-self: start; }
  .fv-side { position: static; grid-column: 2; grid-row: 3; min-height: 0; padding: 0; justify-content: flex-start; }
}
/* Telefon: oba kadry pełną szerokością ekranu (góry niskim pasem u góry, szczyt przy prawej krawędzi), bez kadru
   z Dziś: pod tytułem i planszą ilustracja jest tylko tłem (recenzja 25.10.2026: dawna reguła kadru i tak przegrywała
   z `.fv-art img`). */

@media (min-width: 901px) {
  .fv {
    /* Prawa kolumna jako jeden blok przy środku planszy (Kacper 24.10.2026: pod tekstem zostawała pusta połowa): tytuł kończy się
       na wysokości środka planszy, tekst i przyciski zaczynają się pod nim. */
    /* Drugi wiersz ma sztywno pół planszy: tytuł kończy się zawsze na jej środku i nie skacze między aktami o różnej wysokości. */
    /* Plansza od wysokości ekranu, te same liczby co bohater Dziś (`today.css`): po zamknięciu lekcji stoi w tym samym miejscu. */
    --fv-board: min(560px, calc(100svh - 260px), calc(100vw - 608px));
    /* Kontener strony (`--frame`) z wcięciem hero (`--hero-inset`, Kacper 25.10.2026): kolumna tekstu bierze resztę, plansza stoi
       przy prawej krawędzi wcięcia, więc krawędzie zgadzają się z górnym blokiem Dziś przy każdej szerokości (1366, 1440, 1920).
       Ramę robi wewnętrzny margin (`--fv-pad-x`), a sam kontener ma całą szerokość okna (Kacper 26.10.2026): przewijany kontener
       przycina wszystko, co z niego wystaje, więc w ramie 1280 px łuna planszy po dobrym ruchu kończyła się ostrą krawędzią. */
    --fv-pad-x: max(calc(var(--frame-pad, 24px) + var(--hero-inset, 64px)), calc((100vw - var(--frame, 1280px)) / 2 + var(--frame-pad, 24px) + var(--hero-inset, 64px)));
    grid-template-columns: minmax(0, 1fr) var(--fv-board); grid-template-rows: auto calc(var(--fv-board) / 2) auto;
    /* Plansza na środku wysokości w każdym akcie: siatka od góry z odstępem liczonym z planszy, zamiast centrowania całości. Akt 3
       ma wyższy panel i dawniej podnosił tytuł z planszą o ok. 40 px, aż tytuł wchodził na szlak w górach (Kacper 25.10.2026). */
    column-gap: clamp(72px, 7vw, 120px); align-content: start;
    padding: max(40px, calc(24px + (100svh - 240px - var(--fv-board)) / 2)) var(--fv-pad-x) 32px;
  }
  /* Logo na środku strony nad obiema kolumnami (Kacper 24.10.2026): nad planszą zasłaniało szczyt kadru. Telefon bez zmian:
     tam szczyt stoi na środku ekranu, więc logo zostaje po lewej. */
  /* Zamiast logo pasek portalu nad pierwszą wizytą (Kacper 24.10.2026); kliknięcie w pasek kończy pierwszą wizytę. */
  .fv-brand { display: none; }
  .fv { top: var(--fv-top, 56px); }
  .fv-art { top: var(--fv-top, 56px); }
  /* Górny kadr w lustrze (Kacper 25.10.2026): plansza stoi po prawej, więc szczyt z flagą i szlak idą na lewą stronę, nad tytuł.
     W aplikacji `.fv-art-top` to kontener obrazka, szlaku lekcji i warstwy flagi (`first-visit.css`), więc odbijają się razem.
     Dolna część ilustracji zostaje bez odbicia: jej droga idzie lewym dołem, z dala od planszy. */
  .fv-art .fv-art-top { transform: scaleX(-1); }
  .fp-entry #first-paint .fp-bar { display: flex; position: fixed; top: 0; left: 0; right: 0; height: 56px; align-items: center; padding: 0 20px;
    background: var(--bg, #121110); border-bottom: 1px solid rgba(222, 206, 184, .13); z-index: 2; }
  .fp-bar img { display: block; height: 26px; width: auto; }
  .fv-brand img { height: 40px; }
  .fv-board-slot { grid-column: 2; grid-row: 2 / span 2; width: 100%; align-self: start; }
  /* Nagłówek kończy się na środku planszy; tytuł w dwóch wierszach na szerokość kolumny („Pokażemy Ci drogę.” mieści się
     w 560 px do 64 px pisma). */
  /* Tytuł bierze wielkość od szerokości kolumny (`cqw`), nie okna: od ramy 1280 px z wcięciem (0e21d179) kolumna ma ok. 424 px
     i przy 1440/1920 tytuł łamał się w trzy wiersze, przez które szedł szlak w górach (audyt 26.10.2026). 11 cqw to „Pokażemy Ci
     drogę.” w jednym wierszu. */
  .fv-head { grid-column: 1; grid-row: 2; align-self: end; margin: 0 0 28px; container-type: inline-size; }
  .fv-eyebrow { margin-bottom: 12px; font-size: 15px; }
  .fv-title { margin: 0 0 0 -.04em; font-size: clamp(40px, 11cqw, 64px); line-height: .98; font-weight: 400; letter-spacing: -.035em; }
  .fv-source { margin-top: 16px; font-size: 17px; }
  .fv-side { grid-column: 1; grid-row: 3; align-self: start; }
  .fv-panel { margin-top: 24px; }
}

:root[data-theme="light"] #first-paint, :root[data-theme="light"] .fv { background: var(--bg, #f1ede5); color: var(--text, #2c2822); }
:root[data-theme="light"] .fv-title { color: var(--text, #2c2822); }
:root[data-theme="light"] #first-paint .fp-bar { background: var(--bg, #f1ede5); border-bottom-color: rgba(58, 53, 46, .11); }
/* Obrazki w dwóch wersjach (`index.html`): widać tylko tę z bieżącego motywu. Samo chowanie, bez wymuszania `display`,
   bo `.fp-entry` też chowa znak. */
:root:not([data-theme="light"]) #first-paint .fp-light, :root[data-theme="light"] #first-paint .fp-dark { display: none; }
/* Niskie okno szersze niż 900 px (telefon poziomo 915–932 × 412–430, okno przeglądarki zmniejszone w pionie): plansza od wysokości
   okna pod paskiem portalu, bez nadtytułu i podpisu, tytuł mniejszy; dawna rezerwa 260 px dawała planszę ok. 150 px. */
@media (min-width: 901px) and (max-height: 520px) {
  .fv {
    --fv-board: min(560px, calc(100svh - var(--fv-top, 56px) - 24px), calc(100vw - 2 * var(--fv-pad-x) - 220px));
    grid-template-rows: auto auto minmax(0, 1fr); column-gap: 32px; padding-top: 12px; padding-bottom: 12px;
  }
  .fv-board-slot { grid-row: 1 / span 3; }
  .fv-head { grid-row: 1; align-self: start; margin: 0 0 8px; }
  .fv-side { grid-row: 2; }
  .fv-eyebrow { display: none; }
  .fv-source { margin-top: 8px; font-size: 14px; }
  .fv-title { font-size: clamp(26px, 8cqw, 40px); }
  .fv-panel { margin-top: 8px; }
}
