);
}
// ─── Footer ────────────────────────────────────────────────────────────────
function Footer() {
const { t, lang, navigate } = useApp();
const yr = new Date().getFullYear();
return (
);
}
// ─── Placeholder image ─────────────────────────────────────────────────────
// Neutral, on-palette tonal panels — used everywhere a hotel photo would go.
function PH({ tone = "warm", label, ratio = "4/3", style = {}, children, icon }) {
return (
{icon &&
{icon}
}
{label &&
{label}
}
{children}
);
}
function Photo({ src, alt = "", ratio = "4/3", style = {}, children, objectPosition = "center" }) {
// Serve a WebP sibling (~60% smaller) when the browser supports it; the
// original .jpg stays as the fallback. Every photo on the site renders
// through this component, so this is the single place the swap is needed.
const webp = /\.jpe?g$/i.test(src) ? src.replace(/\.jpe?g$/i, ".webp") : null;
return (
{webp && }
{children}
);
}
// Each room's photos live in images/rooms//01.jpg, 02.jpg, ...
// To add a photo: drop the next-numbered file in the folder and bump the count here.
window.ROOM_SLUGS = ["standard-1", "standard-2", "comfort-1", "comfort-2"];
window.ROOM_PHOTO_COUNTS = [4, 2, 2, 6];
window.slugFor = (idx) => window.ROOM_SLUGS[idx] || window.ROOM_SLUGS[0];
window.photosFor = (idx) => {
const n = window.ROOM_PHOTO_COUNTS[idx] || 0;
const slug = window.slugFor(idx);
return Array.from({ length: n }, (_, i) => `images/rooms/${slug}/${String(i + 1).padStart(2, "0")}.jpg`);
};
window.roomImg = (idx) => window.photosFor(idx)[0] || "";
// ─── Path-based routing (real, crawlable URLs instead of #fragments) ─────────
// Single source of truth mapping a page key (+params) <-> URL path. Used by the
// router in app.jsx, the nav links below, applySeo, and the prerender build.
window.SITE_ORIGIN = "https://longstreet.pl";
window.LANGS = ["pl", "en"]; // pl = root paths, en = /en/* paths
window.DEFAULT_LANG = "pl";
window.pathToRoute = function (pathname) {
let parts = (pathname || "/").replace(/^\/+|\/+$/g, "").split("/").filter(Boolean);
let lang = window.DEFAULT_LANG;
if (parts[0] === "en") { lang = "en"; parts = parts.slice(1); }
const base = { lang, params: {} };
if (!parts.length) return { ...base, page: "home" };
if (parts[0] === "rooms" && parts[1]) {
const idx = window.ROOM_SLUGS.indexOf(parts[1]);
return { ...base, page: "room-detail", params: { roomIdx: idx >= 0 ? idx : 0 } };
}
const known = { rooms: "rooms", gallery: "gallery", contact: "contact", reservation: "reservation" };
return { ...base, page: known[parts[0]] || "home" };
};
window.routeToPath = function (page, params, lang) {
const p = params || {};
const prefix = lang === "en" ? "/en" : "";
let sub;
switch (page) {
case "rooms": sub = "/rooms"; break;
case "room-detail": sub = "/rooms/" + (window.ROOM_SLUGS[p.roomIdx] || window.ROOM_SLUGS[0]); break;
case "gallery": sub = "/gallery"; break;
case "contact": sub = "/contact"; break;
case "reservation": sub = "/reservation"; break;
default: sub = "";
}
return (prefix + sub) || "/"; // "/en"+"" -> "/en"; ""+"" -> "/"
};
// Every real route the site exposes (drives the sitemap + prerender build).
window.SITE_ROUTES = ["home", "rooms", "gallery", "contact", "reservation"]
.map((pg) => ({ page: pg, params: {} }))
.concat(window.ROOM_SLUGS.map((_, i) => ({ page: "room-detail", params: { roomIdx: i } })));
// ─── Icons ─────────────────────────────────────────────────────────────────
const Ic = {
arrow: (p = {}) => (
),
arrowL: (p = {}) => (
),
arrowDown: (p = {}) => (
),
bed: (p = {}) => (
),
ruler: (p = {}) => (
),
user: (p = {}) => (
),
window: (p = {}) => (
),
wifi: (p = {}) => (
),
coffee: (p = {}) => (
),
bath: (p = {}) => (
),
key: (p = {}) => (
),
leaf: (p = {}) => (
),
fork: (p = {}) => (
),
book: (p = {}) => (
),
pin: (p = {}) => (
),
calendar: (p = {}) => (
),
check: (p = {}) => (
),
star: (p = {}) => (
),
close: (p = {}) => (
),
diamond: (p = {}) => (
),
};
// ─── Decorative serif diamond divider ──────────────────────────────────────
function Divider() {
return (