| Server IP : 193.86.120.172 / Your IP : 216.73.216.67 Web Server : Apache/2.4.63 (Unix) System : Linux JServices 3.10.108 #86003 SMP Wed Oct 22 13:20:46 CST 2025 x86_64 User : kubec ( 1026) PHP Version : 8.2.28 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /volume1/web/hotellesnizatisi_cz/new/includes/ |
Upload File : |
<?php
// ============================================================
// Sdílená šablona veřejného webu — používají ji index.php (CS),
// en/index.php a de/index.php. Proměnná $lang musí být nastavená
// PŘED require_once tohoto souboru.
// ============================================================
if (!isset($lang) || !in_array($lang, ['cs', 'en', 'de'], true)) {
$lang = 'cs';
}
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/site-lock.php';
site_lock_check($lang);
// Cesta k assetům (uploads/) — z podsložek en/, de/ je potřeba o úroveň výš
$assetBase = $lang === 'cs' ? '' : '../';
// --- UI texty šablony (nav, tlačítka, popisky) — needitovatelné v adminu,
// jen "obsah" sekcí (nadpisy/texty z web_sekce) je přes administraci editovatelný ---
$UI = [
'cs' => [
'nav_domu' => 'Domů', 'nav_ohotelu' => 'O hotelu', 'nav_okoli' => 'V okolí',
'nav_pokoje' => 'Pokoje', 'nav_cenik' => 'Ceník', 'nav_kontakt' => 'Kontakt',
'hero_cta_rooms' => 'Zobrazit pokoje', 'hero_cta_trip' => 'Naplánovat výlet', 'hero_scroll' => 'Skrolovat',
'about_eyebrow' => 'Od hotelu k bráně skal · 8 minut pěšky',
'about_stat1' => 'pokojů', 'about_stat2' => 'lůžek', 'about_stat3' => 'restaurace', 'about_stat4' => 'parkoviště u dveří',
'okoli_eyebrow' => 'Na dosah pěšky', 'okoli_further_label' => 'Dále v regionu',
'pokoje_eyebrow' => 'Ubytování', 'pokoje_cta' => 'Zobrazit ceník', 'pokoje_gallery_empty' => '',
'dining_eyebrow' => 'Restaurace',
'cenik_eyebrow' => 'Ceny a podmínky', 'tab_cenik' => 'Ceník', 'tab_storno' => 'Storno podmínky',
'doplnky_title' => 'Doplňkové služby k pobytu',
'uctovani_jednorazove' => 'jednorázově', 'uctovani_za_noc' => 'za noc', 'uctovani_za_osobu_noc' => 'za osobu a noc',
'kontakt_eyebrow' => 'Kontakt', 'kontakt_title' => 'Najdete nás u brány skal',
'contact_address_label' => 'Adresa', 'contact_reach_label' => 'Spojení', 'contact_reception_label' => 'Recepce',
'contact_reception_hours' => 'Denně 7:00–21:00', 'contact_restaurant_hours' => 'Restaurace 11:00–22:00',
'contact_maplink' => 'Otevřít v Google Mapách →',
'contact_form_name' => 'Vaše jméno a příjmení', 'contact_form_email' => 'Váš e-mail',
'contact_form_phone' => 'Váš telefon', 'contact_form_subject' => 'Předmět', 'contact_form_message' => 'Vaše zpráva',
'contact_form_submit' => 'Odeslat zprávu',
'contact_form_success' => 'Děkujeme, vaše zpráva byla odeslána.',
'contact_form_error' => 'Zprávu se nepodařilo odeslat. Zkuste to prosím znovu, nebo nám napište přímo na e-mail.',
'footer_credit' => 'Web vytvořil <a href="https://jservices.cz" target="_blank" rel="noopener" style="text-decoration:underline;">J Services</a>',
],
'en' => [
'nav_domu' => 'Home', 'nav_ohotelu' => 'About', 'nav_okoli' => 'Surroundings',
'nav_pokoje' => 'Rooms', 'nav_cenik' => 'Prices', 'nav_kontakt' => 'Contact',
'hero_cta_rooms' => 'View rooms', 'hero_cta_trip' => 'Plan a trip', 'hero_scroll' => 'Scroll',
'about_eyebrow' => 'From the hotel to the rock gate · 8 minutes on foot',
'about_stat1' => 'rooms', 'about_stat2' => 'beds', 'about_stat3' => 'restaurant hours', 'about_stat4' => 'parking at the door',
'okoli_eyebrow' => 'Within walking distance', 'okoli_further_label' => 'Further afield',
'pokoje_eyebrow' => 'Accommodation', 'pokoje_cta' => 'View prices', 'pokoje_gallery_empty' => '',
'dining_eyebrow' => 'Restaurant',
'cenik_eyebrow' => 'Prices & terms', 'tab_cenik' => 'Price list', 'tab_storno' => 'Cancellation terms',
'doplnky_title' => 'Additional services',
'uctovani_jednorazove' => 'one-time', 'uctovani_za_noc' => 'per night', 'uctovani_za_osobu_noc' => 'per person per night',
'kontakt_eyebrow' => 'Contact', 'kontakt_title' => 'Find us at the gateway to the rocks',
'contact_address_label' => 'Address', 'contact_reach_label' => 'Get in touch', 'contact_reception_label' => 'Front desk',
'contact_reception_hours' => 'Daily 7 AM – 9 PM', 'contact_restaurant_hours' => 'Restaurant 11 AM – 10 PM',
'contact_maplink' => 'Open in Google Maps →',
'contact_form_name' => 'Your full name', 'contact_form_email' => 'Your email',
'contact_form_phone' => 'Your phone', 'contact_form_subject' => 'Subject', 'contact_form_message' => 'Your message',
'contact_form_submit' => 'Send message',
'contact_form_success' => 'Thank you, your message has been sent.',
'contact_form_error' => 'Sorry, the message could not be sent. Please try again, or email us directly.',
'footer_credit' => 'Website by <a href="https://jservices.cz" target="_blank" rel="noopener" style="text-decoration:underline;">J Services</a>',
],
'de' => [
'nav_domu' => 'Start', 'nav_ohotelu' => 'Über uns', 'nav_okoli' => 'Umgebung',
'nav_pokoje' => 'Zimmer', 'nav_cenik' => 'Preise', 'nav_kontakt' => 'Kontakt',
'hero_cta_rooms' => 'Zimmer ansehen', 'hero_cta_trip' => 'Ausflug planen', 'hero_scroll' => 'Scrollen',
'about_eyebrow' => 'Vom Hotel zum Felsentor · 8 Gehminuten',
'about_stat1' => 'Zimmer', 'about_stat2' => 'Betten', 'about_stat3' => 'Restaurant', 'about_stat4' => 'Parkplatz vor der Tür',
'okoli_eyebrow' => 'Zu Fuß erreichbar', 'okoli_further_label' => 'Weiter entfernt',
'pokoje_eyebrow' => 'Unterkunft', 'pokoje_cta' => 'Preise ansehen', 'pokoje_gallery_empty' => '',
'dining_eyebrow' => 'Restaurant',
'cenik_eyebrow' => 'Preise & Bedingungen', 'tab_cenik' => 'Preisliste', 'tab_storno' => 'Stornobedingungen',
'doplnky_title' => 'Zusatzleistungen',
'uctovani_jednorazove' => 'einmalig', 'uctovani_za_noc' => 'pro Nacht', 'uctovani_za_osobu_noc' => 'pro Person und Nacht',
'kontakt_eyebrow' => 'Kontakt', 'kontakt_title' => 'Sie finden uns am Tor zu den Felsen',
'contact_address_label' => 'Adresse', 'contact_reach_label' => 'Erreichbarkeit', 'contact_reception_label' => 'Rezeption',
'contact_reception_hours' => 'Täglich 7–21 Uhr', 'contact_restaurant_hours' => 'Restaurant 11–22 Uhr',
'contact_maplink' => 'In Google Maps öffnen →',
'contact_form_name' => 'Ihr vollständiger Name', 'contact_form_email' => 'Ihre E-Mail',
'contact_form_phone' => 'Ihre Telefonnummer', 'contact_form_subject' => 'Betreff', 'contact_form_message' => 'Ihre Nachricht',
'contact_form_submit' => 'Nachricht senden',
'contact_form_success' => 'Vielen Dank, Ihre Nachricht wurde gesendet.',
'contact_form_error' => 'Die Nachricht konnte nicht gesendet werden. Bitte versuchen Sie es erneut oder schreiben Sie uns direkt per E-Mail.',
'footer_credit' => 'Website von <a href="https://jservices.cz" target="_blank" rel="noopener" style="text-decoration:underline;">J Services</a>',
],
];
$t = $UI[$lang];
// --- Obsah z databáze ---
$sekceRows = db()->query('SELECT * FROM web_sekce WHERE aktivni = 1')->fetchAll();
$sekce = [];
foreach ($sekceRows as $row) {
$sekce[$row['klic']] = $row;
}
function S(array $sekce, string $klic, string $field, string $lang): string
{
return $sekce[$klic][$field . '_' . $lang] ?? '';
}
function render_paragraphs(?string $text): string
{
if (!$text) {
return '';
}
$html = '';
foreach (preg_split('/\n\s*\n/', trim($text)) as $p) {
$p = trim($p);
if ($p === '') {
continue;
}
$html .= '<p>' . nl2br(htmlspecialchars($p)) . '</p>';
}
return $html;
}
function fotky_kategorie(string $kategorie): array
{
$stmt = db()->prepare("
SELECT * FROM web_fotky
WHERE kategorie = ? AND referencni_id IS NULL AND aktivni = 1
ORDER BY poradi
");
$stmt->execute([$kategorie]);
return $stmt->fetchAll();
}
$okoli = db()->query('SELECT * FROM web_okoli_atrakce WHERE aktivni = 1 ORDER BY poradi')->fetchAll();
$cenik = db()->query('SELECT * FROM web_cenik_polozky WHERE aktivni = 1 ORDER BY poradi')->fetchAll();
$storno = db()->query('SELECT * FROM web_storno_podminky WHERE aktivni = 1 ORDER BY poradi')->fetchAll();
$doplnky = db()->query('SELECT * FROM web_doplnky WHERE aktivni = 1 ORDER BY poradi')->fetchAll();
$fotkyPokoje = fotky_kategorie('typ_pokoje');
$fotkyHotel = fotky_kategorie('hotel');
$fotkyOkoli = fotky_kategorie('okoli');
$fotkyRestaurace = fotky_kategorie('restaurace');
// --- Odkazy mezi jazykovými mutacemi (relativní, fungují z /, /en/, /de/) ---
function lang_href(string $current, string $target): string
{
if ($current === $target) {
return '#';
}
$map = [
'cs' => ['en' => 'en/', 'de' => 'de/'],
'en' => ['cs' => '../', 'de' => '../de/'],
'de' => ['cs' => '../', 'en' => '../en/'],
];
return $map[$current][$target] ?? '#';
}
?>
<!DOCTYPE html>
<html lang="<?= htmlspecialchars($lang) ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z3DS6TCLND"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-Z3DS6TCLND');
</script>
<title>Hotel Lesní zátiší — Adršpach</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Big+Shoulders+Display:wght@700;800;900&family=Lora:ital@1&family=Work+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet">
<style>
/* ========================================================= DESIGN TOKENS */
:root{
--charcoal-moss: #1F2620;
--deep-stone: #2B3527;
--deep-stone-2: #344030;
--sandstone: #C2884F;
--sandstone-dim: #9C6E3F;
--amber: #E2A552;
--limestone: #EDE8DD;
--limestone-card: #E2DBC8;
--limestone-card2: #D8CFB6;
--sage: #6B7860;
--sage-light: #A9B49C;
--ink: #232A1F;
--display: "Big Shoulders Display", sans-serif;
--serif: "Lora", serif;
--body: "Work Sans", sans-serif;
--mono: "IBM Plex Mono", monospace;
--container: 1180px;
}
*{margin:0;padding:0;box-sizing:border-box;}
html{scroll-behavior:smooth;}
body{
font-family:var(--body);
background:var(--limestone);
color:var(--ink);
line-height:1.5;
-webkit-font-smoothing:antialiased;
}
img,svg{display:block;max-width:100%;}
a{color:inherit;text-decoration:none;}
ul{list-style:none;}
button{font-family:inherit;cursor:pointer;border:none;background:none;color:inherit;}
table{border-collapse:collapse;}
:focus-visible{outline:2px solid var(--amber);outline-offset:3px;}
.wrap{max-width:var(--container);margin:0 auto;padding-inline:6vw;}
.eyebrow{
font-family:var(--mono);
font-size:.72rem;
letter-spacing:.14em;
text-transform:uppercase;
display:flex;align-items:center;gap:.6em;
}
.eyebrow::before{
content:"";
width:22px;height:1px;
background:currentColor;
opacity:.6;
}
h1,h2,h3{font-family:var(--display);text-transform:uppercase;letter-spacing:-0.01em;line-height:.98;font-weight:800;}
@media (prefers-reduced-motion: reduce){
*{animation-duration:0.001ms !important;animation-iteration-count:1 !important;transition-duration:0.001ms !important;scroll-behavior:auto !important;}
}
/* ========================================================= NAV */
.nav{
position:fixed;top:0;left:0;right:0;z-index:100;
display:flex;align-items:center;justify-content:space-between;
padding:22px 6vw;
transition:background .35s ease, padding .35s ease, box-shadow .35s ease;
}
.nav.is-scrolled{
background:rgba(31,38,32,.92);
backdrop-filter:blur(8px);
padding:14px 6vw;
box-shadow:0 8px 30px rgba(0,0,0,.25);
}
.nav__logo{
font-family:var(--display);
font-weight:800;
font-size:1.3rem;
letter-spacing:.02em;
color:var(--limestone);
text-transform:uppercase;
display:flex;flex-direction:column;line-height:1;
}
.nav__logo span{
font-family:var(--mono);
font-size:.6rem;
letter-spacing:.18em;
color:var(--sandstone);
margin-top:4px;
text-transform:uppercase;
}
.nav__links{display:flex;gap:1.7rem;}
.nav__links a{
font-size:.82rem;
letter-spacing:.03em;
color:var(--limestone);
opacity:.85;
position:relative;
padding-bottom:4px;
white-space:nowrap;
}
.nav__links a::after{
content:"";position:absolute;left:0;bottom:0;height:1px;width:0;
background:var(--amber);transition:width .25s ease;
}
.nav__links a:hover::after{width:100%;}
.nav__links a:hover{opacity:1;}
.nav__right{display:flex;align-items:center;gap:1.4rem;}
.nav__phone{
font-family:var(--mono);font-size:.8rem;color:var(--limestone);opacity:.85;
}
.nav__langs{display:flex;gap:.4rem;font-family:var(--mono);font-size:.72rem;letter-spacing:.05em;}
.nav__langs a{
color:var(--sage-light);padding:3px 6px;border-radius:3px;
}
.nav__langs a.active{color:var(--charcoal-moss);background:var(--sandstone);}
.nav__burger{display:none;flex-direction:column;gap:5px;}
.nav__burger span{width:24px;height:2px;background:var(--limestone);}
@media (max-width:980px){
.nav__links,.nav__phone{display:none;}
.nav__burger{display:flex;}
}
/* ========================================================= HERO */
.hero{
position:relative;
min-height:100vh;
overflow:hidden;
background:linear-gradient(180deg, var(--charcoal-moss) 0%, var(--deep-stone) 55%, var(--charcoal-moss) 100%);
display:flex;flex-direction:column;
}
.hero__mist{
position:absolute;inset:0;
background:radial-gradient(60% 40% at 50% 38%, rgba(237,232,221,.10), transparent 70%);
pointer-events:none;
}
.hero__content{
position:relative;z-index:5;
padding-top:clamp(150px, 24vh, 260px);
padding-inline:6vw;
max-width:980px;
}
.hero__content h1{
font-size:clamp(3rem, 7.5vw, 6.6rem);
color:var(--limestone);
}
.hero__sub{
font-family:var(--serif);
font-style:italic;
font-size:clamp(1.05rem,1.6vw,1.3rem);
color:var(--sage-light);
max-width:40ch;
margin-top:1.6rem;
}
.hero__cta{
display:flex;gap:1rem;margin-top:2.4rem;flex-wrap:wrap;
}
.btn{
font-family:var(--mono);
font-size:.82rem;letter-spacing:.06em;text-transform:uppercase;
padding:.95rem 1.8rem;
border-radius:2px;
display:inline-flex;align-items:center;gap:.6em;
transition:transform .2s ease, background .2s ease, color .2s ease, border-color .2s ease;
}
.btn--primary{background:var(--amber);color:var(--charcoal-moss);}
.btn--primary:hover{transform:translateY(-2px);background:var(--sandstone);}
.btn--ghost{border:1px solid rgba(237,232,221,.4);color:var(--limestone);}
.btn--ghost:hover{border-color:var(--limestone);transform:translateY(-2px);}
.hero__rocks{
position:absolute;left:0;right:0;bottom:0;width:100%;
height:58vh;min-height:340px;
z-index:1;
}
.hero__rocks svg{position:absolute;bottom:0;left:0;width:100%;height:100%;}
.layer-back{opacity:.45;}
.layer-mid{opacity:.7;}
.layer-front{opacity:1;}
.hero__marker{
position:absolute;left:6vw;bottom:28px;z-index:6;
font-family:var(--mono);font-size:.7rem;letter-spacing:.1em;
color:rgba(237,232,221,.65);text-transform:uppercase;
}
.hero__scroll{
position:absolute;right:6vw;bottom:30px;z-index:6;
font-family:var(--mono);font-size:.68rem;letter-spacing:.15em;
color:rgba(237,232,221,.55);text-transform:uppercase;
display:flex;align-items:center;gap:.6em;
}
.hero__scroll i{
width:1px;height:34px;background:rgba(237,232,221,.4);
position:relative;overflow:hidden;
}
.hero__scroll i::after{
content:"";position:absolute;top:0;left:0;width:100%;height:40%;
background:var(--amber);
animation:scrollline 2.4s ease-in-out infinite;
}
@keyframes scrollline{0%{top:-40%;}100%{top:100%;}}
/* ========================================================= SECTION GENERICS */
section{padding:clamp(70px,10vw,130px) 0;}
.section--dark{background:var(--deep-stone);color:var(--limestone);}
.section--dark .eyebrow{color:var(--sandstone);}
.section--light .eyebrow{color:var(--sandstone-dim);}
h2.section-title{
font-size:clamp(2.1rem,4.4vw,3.6rem);
margin-top:.5rem;margin-bottom:1.4rem;
}
/* ========================================================= O HOTELU */
.about{
display:grid;grid-template-columns:1.1fr .9fr;gap:5vw;align-items:center;
}
.about__text p{
max-width:46ch;color:var(--ink);opacity:.85;margin-bottom:1.6rem;font-size:1.02rem;
}
.about__stats{
display:flex;gap:2.2rem;flex-wrap:wrap;margin-top:1.6rem;
}
.about__stats div{font-family:var(--mono);}
.about__stats strong{
display:block;font-size:1.6rem;color:var(--sandstone-dim);font-weight:500;
}
.about__stats span{font-size:.72rem;letter-spacing:.05em;text-transform:uppercase;opacity:.7;}
.about__visual{
position:relative;height:clamp(320px,46vw,520px);
border-radius:50% 50% 6px 6px / 22% 22% 6px 6px;
overflow:hidden;
background:linear-gradient(160deg,#3E4A37 0%, #2B3527 55%, #1F2620 100%);
background-size:cover;background-position:center;
}
.about__visual svg{position:absolute;bottom:0;left:0;width:100%;}
.about__visual::after{
content:"DOLNÍ ADRŠPACH Č. 121";
position:absolute;left:50%;bottom:24px;transform:translateX(-50%);
font-family:var(--mono);font-size:.65rem;letter-spacing:.16em;
color:rgba(237,232,221,.55);text-transform:uppercase;white-space:nowrap;
}
@media (max-width:900px){
.about{grid-template-columns:1fr;}
.about__visual{order:-1;}
}
/* ========================================================= FOTOGALERIE (sdílené pro O hotelu / Pokoje / Stravování / V okolí) */
.photo-gallery{
display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:1rem;margin-top:2.6rem;
}
.photo-gallery img{
width:100%;height:230px;object-fit:cover;border-radius:4px;display:block;
transition:transform .35s ease;
}
.photo-gallery a:hover img{transform:scale(1.03);}
/* ========================================================= V OKOLÍ */
.surroundings__head{max-width:640px;margin-bottom:3rem;}
.surroundings__head p{color:var(--sage-light);max-width:52ch;}
.tower-grid{
display:grid;grid-template-columns:repeat(3,1fr);gap:1px;
background:rgba(237,232,221,.12);
}
.tower-card{
background:var(--deep-stone-2);
padding:2.2rem 1.4rem 2rem;
min-height:280px;
display:flex;flex-direction:column;justify-content:flex-end;gap:.9rem;
position:relative;
transition:background .3s ease;
}
.tower-card:hover{background:#3a4734;}
.tower-card .stat{
font-family:var(--mono);font-size:1.9rem;color:var(--amber);line-height:1;
}
.tower-card h3{
font-size:1.05rem;text-transform:none;letter-spacing:0;font-weight:700;
color:var(--limestone);
}
.tower-card p{font-size:.86rem;color:var(--sage-light);max-width:24ch;}
.okoli__further{
max-width:680px;margin:2.6rem 6vw 0;
font-size:.88rem;color:var(--sage-light);
}
.okoli__further strong{
color:var(--amber);font-family:var(--mono);font-weight:500;
text-transform:uppercase;font-size:.72rem;letter-spacing:.08em;
display:block;margin-bottom:.5rem;
}
.okoli .photo-gallery{margin-top:3rem;}
@media (max-width:900px){.tower-grid{grid-template-columns:repeat(2,1fr);}}
@media (max-width:560px){.tower-grid{grid-template-columns:1fr;}}
/* ========================================================= POKOJE */
.rooms__head{margin-bottom:1.6rem;}
.rooms__text{max-width:60ch;font-size:1.02rem;opacity:.85;}
.rooms__text p{margin-bottom:1rem;}
/* ========================================================= STRAVOVÁNÍ */
.dining{
background:var(--sandstone);color:var(--charcoal-moss);
padding-block:clamp(70px,10vw,110px);
}
.dining__head{
display:flex;align-items:center;justify-content:space-between;gap:2rem;flex-wrap:wrap;
}
.dining__head h2{font-size:clamp(1.8rem,3.6vw,2.6rem);max-width:14ch;}
.dining__head p{max-width:36ch;font-size:.98rem;opacity:.85;margin-top:.8rem;}
.dining .photo-gallery img{height:200px;}
/* ========================================================= CENÍK A STORNO PODMÍNKY */
.cenik__head{max-width:640px;margin-bottom:2.8rem;}
.cenik__tabs{
display:flex;gap:2rem;
border-bottom:1px solid rgba(237,232,221,.15);
margin-bottom:2.4rem;
}
.cenik__tab{
font-family:var(--mono);font-size:.8rem;letter-spacing:.05em;text-transform:uppercase;
padding:.9rem 0;color:var(--sage-light);position:relative;
transition:color .2s ease;
}
.cenik__tab:hover{color:var(--limestone);}
.cenik__tab.active{color:var(--limestone);}
.cenik__tab.active::after{
content:"";position:absolute;left:0;bottom:-1px;height:2px;width:100%;background:var(--amber);
}
.cenik__panels{max-width:680px;}
.cenik__panel{display:none;}
.cenik__panel.active{display:block;}
.cenik__note{font-size:.86rem;color:var(--sage-light);margin-bottom:1.6rem;max-width:54ch;}
.price-table{width:100%;}
.price-table tr{border-bottom:1px solid rgba(237,232,221,.1);}
.price-table tr:first-child{border-top:1px solid rgba(237,232,221,.1);}
.price-table td{padding:1rem 0;font-size:.95rem;color:var(--limestone);}
.price-table td:last-child{
text-align:right;font-family:var(--mono);color:var(--amber);
white-space:nowrap;padding-left:1.2rem;font-size:1rem;
}
.storno-list{display:flex;flex-direction:column;gap:1rem;}
.storno-list li{padding-left:1.5rem;position:relative;color:var(--limestone);font-size:.95rem;line-height:1.5;}
.storno-list li::before{content:"—";position:absolute;left:0;color:var(--amber);}
.storno-list li p{margin-bottom:.7rem;}
.storno-list li p:last-child{margin-bottom:0;}
/* ========================================================= KONTAKT / FOOTER */
.contact{display:grid;grid-template-columns:1.2fr 1fr 1fr;gap:3rem;}
.contact h2.section-title{margin-bottom:2rem;}
.contact__block .eyebrow{margin-bottom:.8rem;color:var(--sandstone);}
.contact__block p,.contact__block a{font-size:.95rem;color:var(--sage-light);}
.contact__block a:hover{color:var(--limestone);}
.contact__gps{
font-family:var(--mono);font-size:.82rem;color:var(--limestone);margin:.6rem 0 1.1rem;
letter-spacing:.03em;
}
.contact__map-link{
display:inline-flex;align-items:center;gap:.5em;
font-family:var(--mono);font-size:.78rem;letter-spacing:.05em;text-transform:uppercase;
color:var(--amber);border-bottom:1px solid rgba(226,165,82,.4);padding-bottom:3px;
}
.contact__map-link:hover{border-color:var(--amber);}
.footer-bottom{
margin-top:5rem;padding-top:1.8rem;border-top:1px solid rgba(237,232,221,.12);
display:flex;justify-content:space-between;flex-wrap:wrap;gap:1rem;
font-family:var(--mono);font-size:.72rem;color:var(--sage);letter-spacing:.04em;
}
@media (max-width:880px){.contact{grid-template-columns:1fr;gap:2.4rem;}}
.contact__form-wrap{margin-top:3.5rem;padding-top:2.6rem;border-top:1px solid rgba(237,232,221,.12);}
.contact__form{max-width:680px;}
.contact__form-row{display:grid;grid-template-columns:1fr 1fr;gap:1.4rem;}
.contact__form .field{margin-bottom:1.2rem;}
.contact__form label{
display:block;font-family:var(--mono);font-size:.72rem;letter-spacing:.05em;text-transform:uppercase;
color:var(--sage-light);margin-bottom:.5rem;
}
.contact__form input,.contact__form textarea{
width:100%;padding:.8rem .9rem;border:1px solid rgba(237,232,221,.2);border-radius:3px;
background:rgba(237,232,221,.05);color:var(--limestone);font-family:var(--body);font-size:.92rem;
}
.contact__form input:focus,.contact__form textarea:focus{outline:2px solid var(--amber);outline-offset:1px;}
.contact__form textarea{resize:vertical;min-height:110px;}
.contact__form button{margin-top:.4rem;}
.hp-field{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;}
.contact__form-msg{padding:.9rem 1.1rem;border-radius:4px;font-size:.88rem;margin-bottom:1.6rem;max-width:680px;}
.contact__form-msg--ok{background:rgba(154,184,108,.15);color:#A9C98A;border:1px solid rgba(154,184,108,.3);}
.contact__form-msg--err{background:rgba(180,84,60,.15);color:#E0917D;border:1px solid rgba(180,84,60,.3);}
@media (max-width:640px){.contact__form-row{grid-template-columns:1fr;}}
.reveal{opacity:0;transform:translateY(24px);transition:opacity .7s ease, transform .7s ease;}
.reveal.is-visible{opacity:1;transform:translateY(0);}
/* ========================================================= LIGHTBOX (prohlížeč fotek) */
.lightbox{
position:fixed;inset:0;z-index:200;
background:rgba(15,18,13,.94);
display:none;align-items:center;justify-content:center;
}
.lightbox.is-open{display:flex;}
.lightbox__img{max-width:92vw;max-height:86vh;border-radius:4px;display:block;}
.lightbox__close,.lightbox__prev,.lightbox__next{
position:absolute;display:flex;align-items:center;justify-content:center;
border-radius:50%;background:rgba(237,232,221,.14);color:var(--limestone);
font-family:var(--body);line-height:1;transition:background .2s ease;
}
.lightbox__close:hover,.lightbox__prev:hover,.lightbox__next:hover{background:rgba(237,232,221,.26);}
.lightbox__close{top:18px;right:5vw;width:42px;height:42px;font-size:1.2rem;}
.lightbox__prev,.lightbox__next{top:50%;transform:translateY(-50%);width:50px;height:50px;font-size:1.7rem;}
.lightbox__prev{left:3vw;}
.lightbox__next{right:3vw;}
.lightbox__count{
position:absolute;left:50%;bottom:24px;transform:translateX(-50%);
font-family:var(--mono);font-size:.74rem;letter-spacing:.06em;color:var(--sage-light);
}
@media (max-width:640px){
.lightbox__prev,.lightbox__next{width:44px;height:44px;font-size:1.4rem;}
.lightbox__prev{left:2vw;}
.lightbox__next{right:2vw;}
}
</style>
</head>
<body>
<nav class="nav" id="nav">
<a href="#hero" class="nav__logo">Lesní zátiší<span>Hotel · Adršpach</span></a>
<ul class="nav__links">
<li><a href="#hero"><?= htmlspecialchars($t['nav_domu']) ?></a></li>
<li><a href="#o-hotelu"><?= htmlspecialchars($t['nav_ohotelu']) ?></a></li>
<li><a href="#okoli"><?= htmlspecialchars($t['nav_okoli']) ?></a></li>
<li><a href="#pokoje"><?= htmlspecialchars($t['nav_pokoje']) ?></a></li>
<li><a href="#cenik"><?= htmlspecialchars($t['nav_cenik']) ?></a></li>
<li><a href="#kontakt"><?= htmlspecialchars($t['nav_kontakt']) ?></a></li>
</ul>
<div class="nav__right">
<span class="nav__phone">+420 777 172 786</span>
<div class="nav__langs">
<a class="<?= $lang === 'cs' ? 'active' : '' ?>" href="<?= lang_href($lang, 'cs') ?>">CS</a>
<a class="<?= $lang === 'en' ? 'active' : '' ?>" href="<?= lang_href($lang, 'en') ?>">EN</a>
<a class="<?= $lang === 'de' ? 'active' : '' ?>" href="<?= lang_href($lang, 'de') ?>">DE</a>
</div>
<button class="nav__burger" aria-label="Menu"><span></span><span></span><span></span></button>
</div>
</nav>
<!-- ================= HERO ================= -->
<header class="hero" id="hero">
<div class="hero__mist"></div>
<div class="hero__content">
<h1><?= htmlspecialchars(S($sekce, 'hero', 'nadpis', $lang)) ?></h1>
<p class="hero__sub"><?= htmlspecialchars(S($sekce, 'hero', 'text', $lang)) ?></p>
<div class="hero__cta">
<a href="#pokoje" class="btn btn--primary"><?= htmlspecialchars($t['hero_cta_rooms']) ?></a>
<a href="#okoli" class="btn btn--ghost"><?= htmlspecialchars($t['hero_cta_trip']) ?></a>
</div>
</div>
<div class="hero__marker">50°36'54.777″N · 16°7'11.26″E — Dolní Adršpach</div>
<div class="hero__scroll"><i></i><span><?= htmlspecialchars($t['hero_scroll']) ?></span></div>
<div class="hero__rocks" id="heroRocks">
<svg class="layer-back" data-speed="0.15" viewBox="0 0 1600 500" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
<path fill="#3a4734" d="M0,500 L0,420 L60,400 L90,360 L130,390 L170,330 L210,360 L250,300 L300,330 L350,290 L400,320 L460,270 L520,310 L580,280 L650,320 L720,290 L800,330 L880,300 L960,340 L1040,310 L1120,350 L1200,320 L1280,360 L1360,330 L1440,370 L1520,340 L1600,380 L1600,500 Z"/>
</svg>
<svg class="layer-mid" data-speed="0.32" viewBox="0 0 1600 500" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
<path fill="#2B3527" d="M0,500 L0,400 L45,370 L70,410 L110,330 L140,360 L180,280 L210,310 L260,250 L300,290 L350,230 L390,270 L430,210 L470,250 L520,200 L570,240 L630,190 L680,230 L740,210 L800,250 L860,200 L920,240 L990,210 L1050,250 L1110,220 L1180,260 L1250,230 L1320,270 L1390,240 L1460,280 L1530,250 L1600,290 L1600,500 Z"/>
</svg>
<svg class="layer-front" data-speed="0.5" viewBox="0 0 1600 500" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
<path fill="#1F2620" d="M0,500 L0,440 L35,420 L55,460 L85,400 L100,430 L125,370 L150,400 L175,340 L195,260 L210,300 L235,230 L255,270 L280,180 L300,220 L325,150 L345,200 L370,140 L395,190 L420,120 L445,170 L470,110 L495,160 L525,100 L545,150 L575,90 L600,140 L630,170 L660,130 L690,180 L725,150 L760,200 L800,160 L840,210 L880,170 L920,220 L965,180 L1005,230 L1050,190 L1095,240 L1140,200 L1185,250 L1235,210 L1280,260 L1330,220 L1380,270 L1430,230 L1480,280 L1530,240 L1575,290 L1600,310 L1600,500 Z"/>
</svg>
</div>
</header>
<!-- ================= O HOTELU ================= -->
<section class="section--light" id="o-hotelu">
<div class="wrap about reveal">
<div class="about__text">
<div class="eyebrow"><?= htmlspecialchars($t['about_eyebrow']) ?></div>
<h2 class="section-title"><?= htmlspecialchars(S($sekce, 'o_hotelu', 'nadpis', $lang)) ?></h2>
<?= render_paragraphs(S($sekce, 'o_hotelu', 'text', $lang)) ?>
<div class="about__stats">
<div><strong>7</strong><span><?= htmlspecialchars($t['about_stat1']) ?></span></div>
<div><strong>20</strong><span><?= htmlspecialchars($t['about_stat2']) ?></span></div>
<div><strong>11–22</strong><span><?= htmlspecialchars($t['about_stat3']) ?></span></div>
<div><strong>0 m</strong><span><?= htmlspecialchars($t['about_stat4']) ?></span></div>
</div>
</div>
<div class="about__visual"<?php if ($fotkyHotel): ?> style="background-image:url('<?= $assetBase ?>uploads/fotky/<?= htmlspecialchars($fotkyHotel[0]['nazev_souboru']) ?>');"<?php endif; ?>>
<?php if (!$fotkyHotel): ?>
<svg viewBox="0 0 600 500" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
<path fill="#1F2620" opacity="0.8" d="M0,500 L0,300 L40,280 L70,320 L100,260 L140,300 L180,220 L220,260 L260,180 L300,230 L350,160 L400,210 L450,170 L500,220 L550,190 L600,230 L600,500 Z"/>
</svg>
<?php endif; ?>
</div>
</div>
<?php if (count($fotkyHotel) > 1): ?>
<div class="wrap reveal">
<div class="photo-gallery">
<?php foreach (array_slice($fotkyHotel, 1) as $f): ?>
<a href="<?= $assetBase ?>uploads/fotky/<?= htmlspecialchars($f['nazev_souboru']) ?>" target="_blank" rel="noopener">
<img src="<?= $assetBase ?>uploads/fotky/<?= htmlspecialchars($f['nazev_souboru']) ?>" alt="" loading="lazy">
</a>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
</section>
<!-- ================= V OKOLÍ ================= -->
<section class="section--dark okoli" id="okoli">
<div class="wrap reveal">
<div class="surroundings__head">
<div class="eyebrow"><?= htmlspecialchars($t['okoli_eyebrow']) ?></div>
<h2 class="section-title"><?= htmlspecialchars(S($sekce, 'okoli_uvod', 'nadpis', $lang)) ?></h2>
<p><?= htmlspecialchars(S($sekce, 'okoli_uvod', 'text', $lang)) ?></p>
</div>
</div>
<div class="tower-grid">
<?php foreach ($okoli as $card): ?>
<div class="tower-card">
<div class="stat"><?= htmlspecialchars($card['hodnota']) ?></div>
<h3><?= htmlspecialchars($card['nazev_' . $lang]) ?></h3>
<p><?= htmlspecialchars($card['popis_' . $lang]) ?></p>
</div>
<?php endforeach; ?>
</div>
<?php if (!empty($sekce['okoli_dale'])): ?>
<div class="okoli__further reveal">
<strong><?= htmlspecialchars($t['okoli_further_label']) ?></strong>
<?= htmlspecialchars(S($sekce, 'okoli_dale', 'text', $lang)) ?>
</div>
<?php endif; ?>
<?php if ($fotkyOkoli): ?>
<div class="wrap reveal">
<div class="photo-gallery">
<?php foreach ($fotkyOkoli as $f): ?>
<a href="<?= $assetBase ?>uploads/fotky/<?= htmlspecialchars($f['nazev_souboru']) ?>" target="_blank" rel="noopener">
<img src="<?= $assetBase ?>uploads/fotky/<?= htmlspecialchars($f['nazev_souboru']) ?>" alt="" loading="lazy">
</a>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
</section>
<!-- ================= POKOJE ================= -->
<section class="section--light" id="pokoje">
<div class="wrap">
<div class="rooms__head reveal">
<div class="eyebrow"><?= htmlspecialchars($t['pokoje_eyebrow']) ?></div>
<h2 class="section-title"><?= htmlspecialchars(S($sekce, 'pokoje_info', 'nadpis', $lang)) ?></h2>
</div>
<div class="rooms__text reveal">
<?= render_paragraphs(S($sekce, 'pokoje_info', 'text', $lang)) ?>
</div>
<?php if ($fotkyPokoje): ?>
<div class="photo-gallery reveal">
<?php foreach ($fotkyPokoje as $f): ?>
<a href="<?= $assetBase ?>uploads/fotky/<?= htmlspecialchars($f['nazev_souboru']) ?>" target="_blank" rel="noopener">
<img src="<?= $assetBase ?>uploads/fotky/<?= htmlspecialchars($f['nazev_souboru']) ?>" alt="" loading="lazy">
</a>
<?php endforeach; ?>
</div>
<?php endif; ?>
<div class="reveal" style="margin-top:2.6rem;">
<a href="#cenik" class="btn btn--primary"><?= htmlspecialchars($t['pokoje_cta']) ?></a>
</div>
</div>
</section>
<!-- ================= STRAVOVÁNÍ ================= -->
<section class="dining">
<div class="wrap reveal">
<div class="dining__head">
<div>
<div class="eyebrow" style="color:var(--charcoal-moss);"><?= htmlspecialchars($t['dining_eyebrow']) ?></div>
<h2><?= htmlspecialchars(S($sekce, 'stravovani', 'nadpis', $lang)) ?></h2>
</div>
<p><?= htmlspecialchars(S($sekce, 'stravovani', 'text', $lang)) ?></p>
</div>
<?php if ($fotkyRestaurace): ?>
<div class="photo-gallery">
<?php foreach ($fotkyRestaurace as $f): ?>
<a href="<?= $assetBase ?>uploads/fotky/<?= htmlspecialchars($f['nazev_souboru']) ?>" target="_blank" rel="noopener">
<img src="<?= $assetBase ?>uploads/fotky/<?= htmlspecialchars($f['nazev_souboru']) ?>" alt="" loading="lazy">
</a>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</section>
<!-- ================= CENÍK A STORNO ================= -->
<section class="section--dark" id="cenik">
<div class="wrap reveal">
<div class="cenik__head">
<div class="eyebrow"><?= htmlspecialchars($t['cenik_eyebrow']) ?></div>
<h2 class="section-title"><?= htmlspecialchars(S($sekce, 'cenik_info', 'nadpis', $lang)) ?></h2>
</div>
<div class="cenik__tabs" role="tablist">
<button class="cenik__tab active" data-target="panel-cenik"><?= htmlspecialchars($t['tab_cenik']) ?></button>
<button class="cenik__tab" data-target="panel-storno"><?= htmlspecialchars($t['tab_storno']) ?></button>
</div>
<div class="cenik__panels">
<div class="cenik__panel active" id="panel-cenik">
<p class="cenik__note"><?= htmlspecialchars(S($sekce, 'cenik_info', 'text', $lang)) ?></p>
<table class="price-table">
<tbody>
<?php foreach ($cenik as $c): ?>
<tr>
<td><?= htmlspecialchars($c['nazev_' . $lang]) ?></td>
<td><?= number_format((float) $c['castka'], 0, ',', ' ') ?> <?= htmlspecialchars($c['mena']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php if ($doplnky): ?>
<h3 style="font-family:var(--display);text-transform:uppercase;letter-spacing:-0.01em;font-size:1.1rem;color:var(--limestone);margin:2.4rem 0 1.2rem;padding-top:2rem;border-top:1px solid rgba(237,232,221,.1);">
<?= htmlspecialchars($t['doplnky_title']) ?>
</h3>
<table class="price-table">
<tbody>
<?php foreach ($doplnky as $d): ?>
<tr>
<td>
<?= htmlspecialchars($d['nazev_' . $lang]) ?>
<span style="color:var(--sage-light);font-size:.78rem;"> — <?= htmlspecialchars($t['uctovani_' . $d['typ_uctovani']] ?? $d['typ_uctovani']) ?></span>
</td>
<td><?= number_format((float) $d['cena'], 0, ',', ' ') ?> Kč</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
</div>
<div class="cenik__panel" id="panel-storno">
<ul class="storno-list">
<?php foreach ($storno as $s): ?>
<li><?= render_paragraphs($s['text_' . $lang]) ?></li>
<?php endforeach; ?>
</ul>
</div>
</div>
</div>
</section>
<!-- ================= KONTAKT / FOOTER ================= -->
<section class="section--dark" id="kontakt">
<div class="wrap reveal">
<div class="eyebrow"><?= htmlspecialchars($t['kontakt_eyebrow']) ?></div>
<h2 class="section-title"><?= htmlspecialchars($t['kontakt_title']) ?></h2>
<div class="contact">
<div class="contact__block">
<div class="eyebrow"><?= htmlspecialchars($t['contact_address_label']) ?></div>
<p>Hotel Lesní zátiší<br>Dolní Adršpach 121<br>549 51 Adršpach</p>
<div class="contact__gps">50°36'54.777″N, 16°7'11.26″E</div>
<a class="contact__map-link" href="https://www.google.com/maps/search/?api=1&query=50.615216,16.119794" target="_blank" rel="noopener"><?= htmlspecialchars($t['contact_maplink']) ?></a>
</div>
<div class="contact__block">
<div class="eyebrow"><?= htmlspecialchars($t['contact_reach_label']) ?></div>
<p><a href="tel:+420777172786">+420 777 172 786</a></p>
<p><a href="mailto:lesni.zatisi@email.cz">lesni.zatisi@email.cz</a></p>
</div>
<div class="contact__block">
<div class="eyebrow"><?= htmlspecialchars($t['contact_reception_label']) ?></div>
<p><?= htmlspecialchars($t['contact_reception_hours']) ?></p>
<p><?= htmlspecialchars($t['contact_restaurant_hours']) ?></p>
</div>
</div>
<div class="contact__form-wrap reveal">
<?php if (($_GET['kontakt'] ?? '') === 'ok'): ?>
<div class="contact__form-msg contact__form-msg--ok"><?= htmlspecialchars($t['contact_form_success']) ?></div>
<?php elseif (($_GET['kontakt'] ?? '') === 'chyba'): ?>
<div class="contact__form-msg contact__form-msg--err"><?= htmlspecialchars($t['contact_form_error']) ?></div>
<?php endif; ?>
<form method="post" action="<?= $assetBase ?>kontakt-odeslat.php" class="contact__form">
<input type="hidden" name="lang" value="<?= htmlspecialchars($lang) ?>">
<input type="text" name="web" class="hp-field" tabindex="-1" autocomplete="off">
<div class="contact__form-row">
<div class="field">
<label for="cf_jmeno"><?= htmlspecialchars($t['contact_form_name']) ?> *</label>
<input type="text" id="cf_jmeno" name="jmeno" required>
</div>
<div class="field">
<label for="cf_email"><?= htmlspecialchars($t['contact_form_email']) ?> *</label>
<input type="email" id="cf_email" name="email" required>
</div>
</div>
<div class="contact__form-row">
<div class="field">
<label for="cf_telefon"><?= htmlspecialchars($t['contact_form_phone']) ?></label>
<input type="tel" id="cf_telefon" name="telefon">
</div>
<div class="field">
<label for="cf_predmet"><?= htmlspecialchars($t['contact_form_subject']) ?></label>
<input type="text" id="cf_predmet" name="predmet">
</div>
</div>
<div class="field">
<label for="cf_zprava"><?= htmlspecialchars($t['contact_form_message']) ?></label>
<textarea id="cf_zprava" name="zprava" rows="5"></textarea>
</div>
<button type="submit" class="btn btn--primary"><?= htmlspecialchars($t['contact_form_submit']) ?></button>
</form>
</div>
<div class="footer-bottom">
<span>© <?= date('Y') ?> Hotel Lesní zátiší — Adršpach</span>
<span><?= $t['footer_credit'] ?></span>
</div>
</div>
</section>
<div class="lightbox" id="lightbox">
<button class="lightbox__close" aria-label="Zavřít" type="button">✕</button>
<button class="lightbox__prev" aria-label="Předchozí fotka" type="button">‹</button>
<img class="lightbox__img" src="" alt="">
<button class="lightbox__next" aria-label="Další fotka" type="button">›</button>
<div class="lightbox__count"></div>
</div>
<script>
const nav = document.getElementById('nav');
window.addEventListener('scroll', () => {
nav.classList.toggle('is-scrolled', window.scrollY > 60);
}, { passive: true });
const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const revealEls = document.querySelectorAll('.reveal');
if (reduceMotion) {
revealEls.forEach(el => el.classList.add('is-visible'));
} else {
const io = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('is-visible');
io.unobserve(entry.target);
}
});
}, { threshold: 0.15 });
revealEls.forEach(el => io.observe(el));
}
if (!reduceMotion) {
const layers = document.querySelectorAll('#heroRocks svg');
window.addEventListener('scroll', () => {
const y = window.scrollY;
layers.forEach(layer => {
const speed = parseFloat(layer.dataset.speed || 0.2);
layer.style.transform = `translateY(${y * speed * 0.25}px)`;
});
}, { passive: true });
}
document.querySelector('.nav__burger').addEventListener('click', () => {
const links = document.querySelector('.nav__links');
links.style.display = links.style.display === 'flex' ? 'none' : 'flex';
});
document.querySelectorAll('.cenik__tab').forEach(tab => {
tab.addEventListener('click', () => {
document.querySelectorAll('.cenik__tab').forEach(t => t.classList.remove('active'));
document.querySelectorAll('.cenik__panel').forEach(p => p.classList.remove('active'));
tab.classList.add('active');
document.getElementById(tab.dataset.target).classList.add('active');
});
});
// ============== Lightbox — prohlížení fotek bez opouštění stránky ==============
(function () {
const lightbox = document.getElementById('lightbox');
if (!lightbox) return;
const lbImg = lightbox.querySelector('.lightbox__img');
const lbCount = lightbox.querySelector('.lightbox__count');
const btnClose = lightbox.querySelector('.lightbox__close');
const btnPrev = lightbox.querySelector('.lightbox__prev');
const btnNext = lightbox.querySelector('.lightbox__next');
let group = [];
let index = 0;
function render() {
lbImg.src = group[index].href;
const multi = group.length > 1;
btnPrev.style.display = multi ? 'flex' : 'none';
btnNext.style.display = multi ? 'flex' : 'none';
lbCount.textContent = multi ? (index + 1) + ' / ' + group.length : '';
}
function open(items, i) {
group = items;
index = i;
render();
lightbox.classList.add('is-open');
document.body.style.overflow = 'hidden';
}
function close() {
lightbox.classList.remove('is-open');
document.body.style.overflow = '';
}
function go(delta) {
index = (index + delta + group.length) % group.length;
render();
}
document.querySelectorAll('.photo-gallery').forEach(function (gallery) {
const items = Array.from(gallery.querySelectorAll('a'));
items.forEach(function (a, i) {
a.addEventListener('click', function (e) {
e.preventDefault();
open(items, i);
});
});
});
btnClose.addEventListener('click', close);
btnPrev.addEventListener('click', function () { go(-1); });
btnNext.addEventListener('click', function () { go(1); });
lightbox.addEventListener('click', function (e) {
if (e.target === lightbox) close();
});
document.addEventListener('keydown', function (e) {
if (!lightbox.classList.contains('is-open')) return;
if (e.key === 'Escape') close();
if (e.key === 'ArrowLeft') go(-1);
if (e.key === 'ArrowRight') go(1);
});
// Swipe doleva/doprava na mobilu
let touchStartX = null;
lightbox.addEventListener('touchstart', function (e) {
touchStartX = e.touches[0].clientX;
}, { passive: true });
lightbox.addEventListener('touchend', function (e) {
if (touchStartX === null) return;
const dx = e.changedTouches[0].clientX - touchStartX;
if (Math.abs(dx) > 40) {
go(dx > 0 ? -1 : 1);
}
touchStartX = null;
}, { passive: true });
})();
</script>
</body>
</html>