/* Copyright (c) 2026 Bc. Jan Krejčí. All rights reserved.                   */
/* Proprietary and confidential. See LICENSE in the project root.            */

/* Přechody mezi stránkami — View Transitions API.
 *
 * Dvě cesty, jeden vzhled:
 *
 *  1. MEZI DOKUMENTY (`@view-transition`): plné načtení stránky — přepnutí
 *     jazyka (culture cookie + forceLoad), příchod z odkazu, odhlášení.
 *     Prohlížeč pořídí snímek starého dokumentu při odchodu a nového při
 *     příchodu; CSS níž je sváže. Firefox to zatím neumí — pravidlo tiše
 *     ignoruje a stránka se načte jako dřív.
 *
 *  2. UVNITŘ DOKUMENTU (`kp-vt-nav.js`): navigace interaktivním routerem
 *     (InteractiveServer) dokument nemění, takže `@view-transition` nemá
 *     kdy zabrat — skript obalí překreslení do `startViewTransition` sám,
 *     stejným vzorem jako `kp-auth-transition.js`.
 *
 * Návrh pohybu: ŽÁDNÝ plošný půlvteřinový fade. Odchod je krátký a
 * rozhodný (stránka lehce ustoupí nahoru a zeslábne), příchod pomalejší
 * a zespodu — asymetrie působí jako gesto, ne jako prolnutí. Křivky jsou
 * tytéž jako u zbytku webu (Motion Bible): odchod `ease-in`, příchod
 * `cubic-bezier(0.22, 1, 0.36, 1)`.
 *
 * UVNITŘ DOKUMENTU se od kola v105 neprolíná, ale ODHALUJE MASKOU: nová
 * stránka vyrůstá z místa kliknutí jako kruh, přesně jako nový motiv
 * z tlačítka. Řídí to WAAPI v `kp-vt-nav.js`, protože poloměr se počítá
 * z bodu kliknutí; CSS níž pod značkou `kp-vt-page` jen vypne prolnutí,
 * aby si ty dvě věci nelezly do cesty. Prolnutí zůstává pro přechod MEZI
 * DOKUMENTY (přepnutí jazyka), kde žádné místo kliknutí není.
 *
 * SOUŽITÍ s ostatními přechody: kruhové odhalení motivu
 * (kp-theme-transition.js, značka `kp-vt-active`), karta účtů
 * (kp-auth-transition.js, `kp-vt-auth`) i odhalení stránky (`kp-vt-page`)
 * si `root` režírují samy přes WAAPI. Pravidla níž se proto vypínají,
 * jakmile na kořeni sedí kterákoli z těch značek. */

@view-transition {
    navigation: auto;
}

/* Příchod: nová stránka NAJEDE PŘES starou — 300 ms, jemný pohyb zdola.
   `both` drží počáteční stav i během případné prodlevy. */
@keyframes kp-vt-in {
    from {
        opacity: 0;
        transform: translateY(12px);
    }
}

/* Stará stránka se ZÁMĚRNĚ nikam neztrácí: leží pod novou v plném krytí,
   dokud ji nová nepřekryje.
   
   Dřív odcházela (opacity → 0 za 160 ms) a nová nastupovala až po ní. Mezi
   nimi tak vznikla mezera, ve které nekrylo ani jedno a probleskla holá
   plocha stránky — v tmavém motivu jako tmavé bliknutí. Změřeno při přepnutí
   jazyka: jas spadl ze 120 na 50 a zpátky. Překryv bez mezery drží krytí na
   100 % po celou dobu.

   Dvojexpozice, kvůli které se u karty účtů odchod a příchod naopak
   ROZDĚLOVAL, tu nevadí: obě stránky mají tutéž kostru a text sedí na týchž
   místech, takže to čte jako prolnutí, ne jako dva texty přes sebe. */
html:not(.kp-vt-active):not(.kp-vt-auth):not(.kp-vt-page)::view-transition-old(root) {
    animation: none;
    opacity: 1;
}

html:not(.kp-vt-active):not(.kp-vt-auth):not(.kp-vt-page)::view-transition-new(root) {
    animation: kp-vt-in 0.22s cubic-bezier(0.22, 1, 0.36, 1) both;
}

/* Skupina `root` má vlastní dobu a bez zásahu je to výchozích 250 ms — tedy
   pátá hodnota vedle našich čtyř. Přechod pak končí po částech: obsah dojede,
   ale rám ještě dobíhá. Naměřeno: `transition.finished` padalo 400–440 ms,
   ačkoli nejdelší NAŠE doba byla 320. Srovnáno na tutéž dobu jako příchod. */
html:not(.kp-vt-active):not(.kp-vt-auth):not(.kp-vt-page)::view-transition-group(root) {
    animation-duration: 0.22s;
}

/* ==========================================================================
 *  ODHALENÍ MASKOU — přechod uvnitř dokumentu (`kp-vt-page`)
 *  ---------------------------------------------------------------------
 *  Tady se NIC neprolíná. Kruh v `kp-vt-nav.js` roste nad statickým snímkem
 *  staré stránky a postupně ho zakrývá; každý pixel proto v každém okamžiku
 *  patří právě jedné stránce. Bez těchhle tří pravidel jede navíc výchozí
 *  prolnutí prohlížeče a přes sebe jsou pak vidět OBĚ — přesně ta
 *  dvojexpozice, kvůli které se to celé předělávalo.
 *
 *  Je to táž trojice jako u kruhu motivu (`kp-theme-transition.css`):
 *  vypnout animace, srovnat pořadí, vynulovat dobu skupiny. */
html.kp-vt-page::view-transition-old(root),
html.kp-vt-page::view-transition-new(root) {
    animation: none;
    mix-blend-mode: normal;
    opacity: 1;
}

html.kp-vt-page::view-transition-old(root) { z-index: 1; }
html.kp-vt-page::view-transition-new(root) { z-index: 2; }

/* Bez tohohle vloží prohlížeč mezi snímky ještě vlastní přechod skupiny,
   přes který kruh běží jako druhý, nezávislý efekt. */
html.kp-vt-page::view-transition-group(root) {
    animation-duration: 0s;
}


/* HLAVIČKA NEMÁ VLASTNÍ VRSTVU — a to je celá oprava „probliknutí menu".
 *
 * Dvě kola tu stálo přesvědčení, že se `backdrop-filter` do snímku View
 * Transition nezachytí. Platí to jen z poloviny, a ta druhá polovina je
 * důležitější: nezachytí se do vrstvy, kterou ze snímku VYŘÍZNE vlastní
 * `view-transition-name` — ta pod sebou nemá co vzorkovat. Uvnitř snímku
 * KOŘENE se zachytí úplně normálně, protože v tomtéž snímku je i to, co
 * pod lištou leží.
 *
 * Lišta tedy dostala jméno kvůli problému, který jméno samo způsobovalo.
 * Bez skla vypadala po celou dobu přechodu průsvitnější a ve chvíli dojetí
 * zhoustla; nejvíc vlevo, kde má maska rozostření plnou sílu (kp-site.css).
 * Naměřeno na /cenik -> / v levém třetině lišty, rozdíl proti předchozímu
 * snímku:
 *
 *   se jménem, sklo se vrací přechodem   ocas 0,7 / 1,2 / 0,5 po dojetí
 *   se jménem, sklo se nevypíná          jeden skok 15,7 (uprostřed 20,8)
 *   BEZ JMÉNA, sklo pořád zapnuté        po dojetí samé nuly
 *
 * A nabídka přitom vypadá stejně: snímky lišty z obou variant jsou k
 * nerozeznání. NE proto, že by stará a nová hlavička byly totožné — nejsou
 * (na /cenik je `.kp-header` přilepená a průhledná, na / je
 * `.kp-header--overlay` pevná a krémová na 84 %) — ale proto, že se lišta
 * mění SPOLU se stránkou pod touž maskou. Změna tak proběhne v jednom kroku
 * a ve chvíli, kdy ji odhalení vysvětluje, místo aby se odehrála až za
 * koncem přechodu.
 *
 * Ještě jedna věc, ať se to nemusí měřit znovu: příčiny byly DVĚ a nezávisle
 * na sobě stačila každá. Vedle jména způsobovalo týž ocas i samo pravidlo
 * `html.kp-vt-page .kp-header::before { backdrop-filter: none }` — naměřeno
 * 4,69 součtu (max 1,86), tedy shodně s oběma dohromady. Odstranit se proto
 * musely obě.
 *
 * Kdyby sem někdy jméno mělo přijít zpátky, musí s ním přijít i náhrada za
 * sklo (statická plocha) — jinak se vrací tenhle skok. */


/* Vlas pod aktivní položkou SE PŘESOUVÁ, nepřeskakuje.
 *
 * Vlastní jméno z něj udělá samostatnou vrstvu, jejíž skupina se animuje
 * z místa staré položky na místo nové — čára tedy podjede pod nabídkou tam,
 * kam se kliklo. Bez toho by na jedné položce zhasla a na druhé se rozsvítila,
 * což je ten „přeskok", který klient popisuje.
 *
 * Jméno smí nést jediný prvek: aktivní položka je v hlavičce právě jedna
 * (na mobilu je nabídka v panelu a ten je při navigaci zavřený). Vrstva leží
 * NAD hlavičkou, jinak by ji hlavička překryla. */
html.kp-vt-page .kp-header .kp-nav__link--active::after {
    view-transition-name: kp-nav-active;
}

::view-transition-group(kp-nav-active) {
    z-index: 4;
    animation-duration: 0.42s;
    animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1);
}

::view-transition-old(kp-nav-active) {
    animation: none;
    opacity: 0;
}

::view-transition-new(kp-nav-active) {
    animation: none;
    opacity: 1;
}


/* Nová vždy NAD starou — jinak by ji překryv nezakryl. */
html:not(.kp-vt-active):not(.kp-vt-auth):not(.kp-vt-page)::view-transition-old(root) { z-index: 1; }
html:not(.kp-vt-active):not(.kp-vt-auth):not(.kp-vt-page)::view-transition-new(root) { z-index: 2; }

/* SDÍLENÉ PRVKY TU UŽ NEJSOU — a je to podstatné.
 *
 * Značka, hero fotka i hlavička měly svoje `view-transition-name`, aby při
 * prolnutí zůstaly na místě. S odhalením maskou to nedává smysl a přímo
 * škodí: pojmenovaný prvek se vyčlení do vlastní vrstvy, kterou kruh
 * nezakrývá, takže by přes rostoucí masku pořád svítila stará hlavička.
 * Jedna z těch vrstev (fotka) navíc kreslila PŘES hlavičku, protože uvnitř
 * přechodu neplatí `z-index` ze stránky a skupiny se malují v pořadí
 * zachycení — menu kvůli tomu na `/` a `/reference` mizelo na sedm snímků.
 *
 * Po odhalení jsou obě stránky v jednom snímku kořene, takže se nemá co
 * vyčlenit ani co splést. A že fotka „nepřeskočí" drží něco lepšího než
 * sdílené jméno: `.kp-ref__photo` a `.kp-hero__media` nesou TÝŽ snímek ve
 * stejném výřezu (`kp-reference.css`), takže je na obou stranách masky
 * pixel po pixelu totéž. */

/* Druhý sdílený prvek: hero fotka. Tentýž snímek nese úvod domovské stránky
   i pozadí referencí a od v94 mají OBĚ tutéž geometrii (`max(620px, 100dvh)`,
   výřez `70% 100%`), takže se při přechodu nepřenáší jen plynule — ono se
   fakticky nemá co hýbat. Protějšek je `.kp-ref__photo` v kp-reference.css.
   `:not(--out)` vybírá právě jednu vrstvu i uprostřed výměny nálady. */







/* ==========================================================================
 *  Jak dlouho přechod trvá — a proč zrovna tolik
 *  ---------------------------------------------------------------------
 *  Doby se zkrátily z 300/320/280 ms na 220/240/220. Důvod je měřený, ne
 *  estetický: 300 ms, ze kterých se deset snímků vynechá, působí hůř než
 *  220 ms, které doběhnou celé.
 *
 *  Naměřeno na prokliku v menu (okno 1600 px, tři běhy na variantu):
 *
 *    proklik                 celá doba PŘED   PO
 *    ----------------------------------------------
 *    Domů → Reference (teplý)   511 ms      335–349 ms
 *    Reference → Domů           449 ms      380 ms
 *    Domů → O projektu          433 ms      352 ms
 *
 *  První proklik na Reference je dražší (167 ms v jednom výpadku), protože
 *  se poprvé počítá celá galerie. Řeší to `content-visibility` v
 *  kp-reference.css, ne zdejší doby.
 *
 *  SLEPÁ ULIČKA, ať ji nikdo nezkouší znovu: zastavovat během přechodu
 *  animace hero fotky nepomáhá vůbec. Snímek staré stránky vzniká
 *  SYNCHRONNĚ při volání `startViewTransition`, takže se pak animuje statický
 *  obrázek; a nová stránka takovou animaci nemá. Změřeno, rozdíl v šumu. */

/* Omezený pohyb: systémová volba i ruční přepínač v Tweaks vypínají všechno
   — mezi dokumenty i uvnitř nich. `kp-vt-nav.js` se v obou případech ani
   nespustí, tohle jistí zbytek (např. přechod mezi dokumenty). */
@media (prefers-reduced-motion: reduce) {
    @view-transition {
        navigation: none;
    }

    ::view-transition-group(*),
    ::view-transition-old(*),
    ::view-transition-new(*) {
        animation: none !important;
    }
}

html[data-motion="reduced"]::view-transition-group(*),
html[data-motion="reduced"]::view-transition-old(*),
html[data-motion="reduced"]::view-transition-new(*) {
    animation: none !important;
}
