/* =====================================================================
 * VÝKON NA MOBILU — méně vrstev, žádné rozostření pod prstem
 *
 * Petr i Kareem hlásili, že na iPhonu 14 Pro jde /nemovitosti chvíli
 * scrollovat a pak stránka zamrzne. Na desktopu se to nereprodukuje: heap
 * neroste, uzly nepřibývají, nula dlouhých úloh. Rozdíl není v JavaScriptu,
 * ale v tom, kolik vrstev musí držet kompozitor — a iOS má na ně mnohem
 * nižší strop než desktop.
 *
 * Změřeno na vykreslené stránce (390 px, 49 nemovitostí):
 *
 *   backdrop-filter …… 124 prvků  (49 karet + 49 hover overlayů
 *                                  + 22 „Prodáno" + 4 „Rezervováno")
 *   will-change ……….  60 prvků  (z toho 49 karet)
 *   filter ……………….  26 obrázků (šedivění prodaných)
 *
 * Každý backdrop-filter si vynutí vlastní vrstvu a v každém snímku, kdy je
 * na obrazovce, musí přečíst pixely pod sebou a rozostřit je. Každé
 * will-change promuje prvek do vrstvy natrvalo. Sto dvacet čtyři rozostření
 * a šedesát trvalých vrstev iPhone neuveze; kompozitor začne vrstvy
 * odkládat a načítat zpátky, a záložka se zastaví.
 *
 * Načítá se jako POSLEDNÍ stylopis, protože rozostření karet je v inline
 * <style> v properties/index.php a jinak by nešlo přebít.
 *
 * ---------------------------------------------------------------------
 * OPRAVA DIAGNÓZY, 2026-08-26
 *
 * Vrstvy byly skutečný problém a sekce 1–3 níž ho vyřešily — přeměřeno na
 * živém webu, mobilní viewport: backdrop-filter 124 → 0 prvků,
 * will-change 60 → 0. Jenže zasekávání zůstalo, takže vrstvy nebyly to
 * hlavní. Tou příčinou bylo content-visibility, které tenhle soubor v
 * sekci 4 sám přidal; je odstraněné a proč, stojí tam, kde bývalo.
 *
 * Ještě žije filter: grayscale(35%) brightness(0.92) na 35 z 57 obrázků
 * (properties/index.php:1665, index.php:1317) — text nahoře ho jmenuje
 * mezi příčinami, ale pravidlo pro mobil se pro něj nikdy nenapsalo.
 * ===================================================================== */

/* ---------------------------------------------------------------------
 * 1. Uvolnit will-change, jakmile prvek doanimuje.
 *
 * .reveal-on-scroll nese will-change: opacity, transform (redesign-2026.css)
 * a scroll-reveal.js tou třídou označí mimo jiné každou .property-card.
 * Jenže po přidání .is-visible je animace u konce a vrstva už k ničemu není
 * — držela se ale dál, u všech 49 karet, po celou dobu návštěvy.
 *
 * will-change je příslib prohlížeči „tohle se bude měnit". Nechat ho tam
 * napořád je přesně ten způsob, jak si z optimalizace udělat problém.
 * Platí na všech šířkách; na desktopu to nic nestojí a taky to nic nekazí.
 * ------------------------------------------------------------------- */
.reveal-on-scroll.is-visible {
  will-change: auto;
}

/* ---------------------------------------------------------------------
 * 1b. Na mobilu will-change pryč úplně, i u neodhalených prvků.
 *
 * Pravidlo výš samo nestačilo — naměřeno po projetí celé stránky: třídu
 * .is-visible dostala **jedna** karta z 49, ostatní ji nikdy nedostanou
 * (jsou viditelné i bez ní, opacity jim přebíjí jiné pravidlo). Zbylých
 * 48 karet si tedy will-change drželo napořád a čekání na .is-visible
 * bylo čekání na něco, co nepřijde.
 *
 * Reveal animace funguje i bez toho slibu — opacity a transform umí
 * kompozitor bez nápovědy. Padesát trvalých vrstev je vždycky horší
 * obchod než žádná.
 * ------------------------------------------------------------------- */
@media (max-width: 768px) {
  html body .reveal-on-scroll,
  html body .reveal-on-scroll.is-visible,
  html body .property-card,
  html body .service-card {
    will-change: auto !important;
  }
}

@media (max-width: 768px) {
  /* ---------------------------------------------------------------
   * 2. Žádné rozostření na kartách, štítcích a overlayích.
   *
   * Všechny sedí na neprůhledném pozadí, takže na telefonu není co
   * prosvítat — rozostření se počítá z jednolité plochy a výsledek je
   * k nerozeznání od plné barvy. Platí se za něj ale plnou cenou.
   * Desktopové sklo zůstává beze změny.
   * ------------------------------------------------------------- */
  html body .property-card,
  html body .property-card .hover-content,
  html body .property-hover-overlay,
  html body .sold-badge,
  html body .reserved-badge,
  html body .property-badge,
  html body .filter-buttons,
  html body .menu-overlay {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }

  /* ---------------------------------------------------------------
   * 3. Karta se na dotykovém displeji nezvedá.
   *
   * :hover na telefonu stejně nikdo nevyvolá, ale transform v přechodu
   * stačí k tomu, aby si prohlížeč vrstvu podržel. Bez něj může kartu
   * kreslit rovnou do stránky.
   * ------------------------------------------------------------- */
  html body .property-card {
    transition: box-shadow 200ms ease !important;
  }
  html body .property-card:hover {
    transform: none !important;
  }

  /* Hover overlay („Zobrazit detail") je na dotyku nedosažitelný. */
  html body .property-hover-overlay {
    display: none !important;
  }
}

/* ---------------------------------------------------------------------
 * 4. Nevykreslovat karty mimo obrazovku — ZKOUŠENO A ZAHOZENO 2026-08-26.
 *
 * Tady stálo:
 *
 *   @media (max-width: 768px) {
 *     html body .property-card {
 *       content-visibility: auto;
 *       contain-intrinsic-size: auto 480px;
 *     }
 *   }
 *
 * Byla to ta „vlastní podstata problému" z 2026-08-07. Ve skutečnosti to
 * zasekávání na telefonu způsobilo, ne vyléčilo — Petr psal znovu.
 *
 * Karta na mobilu měří ve skutečnosti ~600–630 px (podle toho, jak se zalomí
 * titulek). Odhad v contain-intrinsic-size byl 480 px — a i ten byl fikce:
 * .property-card má min-height: 500px (properties/index.php:1394, index.php:2381),
 * a min-height klamruje i velikostně kontejnovaný box, takže skrytá karta se
 * ve skutečnosti počítala jako 500 px. Rozdíl je tedy zhruba 100 px na kartu.
 * Mřížka je jednosloupcová a karet je 57, takže se to celé sčítá: dokud je
 * karta mimo obrazovku, drží 500 px, a jakmile vjede do viewportu, vykreslí
 * se na skutečných ~600 px a dokument se prodlouží. Stránka roste pod prstem.
 *
 * Změřeno A/B na živém webu (iPhone 390×844 @3×, 4× CPU throttling,
 * 57 skutečných karet), přepnuta jediná vlastnost:
 *
 *                              s content-visibility   bez něj
 *   růst výšky za jeden scroll        6 206 px          0 px
 *   nejhorší snímek                     467 ms         100 ms
 *   long tasks                              17              9
 *   getBoundingClientRect                7 763          2 814
 *
 * Všechna škoda je v PRVNÍM scrollu po načtení — přesně tam, kde
 * contain-intrinsic-size: auto teprve zjišťuje skutečné výšky. Od druhého
 * passu je to čisté (drift 0). Proto to působilo náhodně: stačí načíst
 * stránku znovu a je to zpátky. Na iOS to bolí víc než na desktopu, protože
 * změna scrollHeight uprostřed setrvačného scrollu přeruší let prstu.
 *
 * Zlepšilo to KAŽDOU metriku. Nezavádět zpátky, ani s „lepším" odhadem —
 * výšky karet jdou od 514 do 631, takže žádná jedna hodnota nesedne.
 *
 * Úsporu, o kterou tu šlo (nestahovat a nedekódovat 55 obrázků mimo
 * obrazovku), dělá loading="lazy" na kartě v js/properties.js. Ten na to
 * je, nelže o výšce layoutu a paměť uvolní doopravdy.
 * ------------------------------------------------------------------- */

/* ---------------------------------------------------------------------
 * Diagnostické přepínače ?perf=… odstraněny 2026-08-26 — odpověď je známá.
 *
 * Byly tu proto, že se freeze nedal reprodukovat na desktopu ani v emulaci
 * a musel rozhodnout skutečný iPhone. Rozhodl: ?perf=noimg i ?perf=nocdn
 * jely hladce, takže viníkem byly TŘI titulní fotky z webnode CDN
 * (1920×1280 do boxu 324×240 — 3,04 MB dat a 26,7 MB dekódovaného bitmapu
 * kvůli třem kartám z 57). Opraveno v datech: `image` u nemovitostí 2, 3 a 4
 * teď ukazuje na jejich vlastní první fotku z galerie, která na serveru
 * dávno leží i s náhledem.
 *
 * Pryč jsou schválně: přepínač, který návštěvníkovi schová fotky, se dá
 * omylem nechat v adrese a vypadá to jako rozbitý web.
 * ------------------------------------------------------------------- */

/* ---------------------------------------------------------------------
 * Karta nesmí trčet 20 px pod svým místem — jinak z každého předka
 * s `overflow-x: hidden` udělá scrollovací kontejner.
 *
 * TOHLE bylo to zasekávání scrollu na iPhonu.
 *
 * `.reveal-on-scroll` (redesign-2026.css:413) dává prvku
 * `transform: translateY(20px)` a `opacity: 0`, dokud nedostane
 * `.is-visible`. U karet ale opacity přebíjí jiné pravidlo, takže karty
 * jsou vidět i bez `.is-visible` — a `.is-visible` proto většina z nich
 * nikdy nedostane. Naměřeno na živém webu: 43 ze 43 karet v sekci
 * pronájmů mělo opacity 1 a přitom pořád `transform: translateY(20px)`.
 * Animace se u nich nikdy nepřehraje; karta jen natrvalo sedí o 20 px níž.
 *
 * Těch 20 px přetéká z poslední karty do gridu a dál do sekce. A protože
 * `properties/index.php` má `overflow-x: hidden !important` na 21 místech,
 * stačí to k tomu, aby se z předka stal svislý scrollovací kontejner:
 * když je jedna osa `hidden`, specifikace nedovolí druhé zůstat `visible`
 * a přepočítá ji na `auto`.
 *
 * Naměřeno před opravou: #rentSection 27 844 px, #saleSection 8 431 px,
 * #tenerifeSection 745 px — dohromady 37 020 px z 39 050 px stránky (95 %)
 * pokryto kontejnerem s 20 px pohybu. Na iOS dá Safari gesto jemu:
 * odscrolluje 20 px a zastaví se, stránka se nehne. Zvedneš prst, švihneš
 * znovu a jede to. Přesně ten hlášený příznak.
 *
 * Vypnutím transformu se nic neztrácí — u karet se stejně nikdy nepřehrál.
 * Specificita (0,2,0) přebíjí .reveal-on-scroll (0,1,0) bez !important.
 * ------------------------------------------------------------------- */
.property-card.reveal-on-scroll {
  transform: none;
}

/* Kdo si vyžádal omezení pohybu, nemá dostat ani reveal animaci —
   a tím pádem ani jedinou vrstvu navíc. */
@media (prefers-reduced-motion: reduce) {
  .reveal-on-scroll,
  .reveal-on-scroll.is-visible {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    will-change: auto !important;
  }
}
