<script>
/* ============================================================
   KEYHOST_CONFIG — single place to manage images & links.
   Edit values here only; nothing else in the file needs touching
   to swap an image or update a link.
   ============================================================ */
window.KEYHOST_CONFIG = {
  // Logo is set directly on the <img class="logo-img"> tags in the header
  // and footer (search for "keyhost-logo-navy.png") — edit the src there.
  images: {
    hero: "https://stay.keyhost.online/wp-content/uploads/2026/07/airport-transfer-Keyhost.jpeg",
    cities: {
      telaviv:  "https://stay.keyhost.online/wp-content/uploads/2026/07/1.jpg",
      jerusalem: "https://stay.keyhost.online/wp-content/uploads/2026/07/1-1.webp",
      herzliya: "https://stay.keyhost.online/wp-content/uploads/2026/07/1-2.webp",
      netanya:  "",
      haifa:    "",
      caesarea: "https://stay.keyhost.online/wp-content/uploads/2026/07/1-3.webp",
      eilat:    "",
      nazareth: "https://stay.keyhost.online/wp-content/uploads/2026/07/1.webp"
    }
  },
  links: {
    siteHome: "https://keyhost.online",
    // Full destination guide on the public site, per city.
    // Leave empty to hide the "Read the full guide" button for that city.
    // Downloadable guide PDFs (Download Monitor links), per city, per language.
    // Same pattern as KEYHOST_DOWNLOAD_LINKS used on the public site.
    // Leave a value empty to hide the download button for that city/language.
    cityGuideDownloads: {
      telaviv:   { en: "https://stay.keyhost.online/wp-content/uploads/2026/07/keyhost_telaviv_guide_en.pdf", fr: "https://stay.keyhost.online/wp-content/uploads/2026/07/keyhost_telaviv_guide_fr.pdf" },
      jerusalem: { en: "https://stay.keyhost.online/wp-content/uploads/2026/07/keyhost_jerusalem_guide_en.pdf", fr: "https://stay.keyhost.online/wp-content/uploads/2026/07/keyhost_jerusalem_guide_fr.pdf" },
      herzliya:  { en: "https://stay.keyhost.online/wp-content/uploads/2026/07/keyhost_herzliya_guide_en.pdf", fr: "https://stay.keyhost.online/wp-content/uploads/2026/07/keyhost_herzliya_guide_fr.pdf" },
      netanya:   { en: "", fr: "" },
      haifa:     { en: "", fr: "" },
      caesarea:  { en: "https://stay.keyhost.online/wp-content/uploads/2026/07/keyhost_caesarea_guide_en.pdf", fr: "https://stay.keyhost.online/wp-content/uploads/2026/07/keyhost_caesarea_guide_fr.pdf" },
      eilat:     { en: "", fr: "" },
      nazareth:  { en: "https://stay.keyhost.online/wp-content/uploads/2026/07/keyhost_nazareth_guide_en.pdf", fr: "https://stay.keyhost.online/wp-content/uploads/2026/07/keyhost_nazareth_guide_fr.pdf" }
    }
  },
  contact: {
    phoneDisplay: "+972 53 58 78 284",
    phoneHref: "+972535878284",
    whatsappHref: "https://wa.me/972535878284",
    email: "contact@keyhost.online"
  },
  // Analytics — leave ga4Id empty to disable tracking entirely (no script is
  // loaded and no request is made if this is blank). Fill in a real GA4
  // Measurement ID (format "G-XXXXXXXXXX") to turn it on.
  analytics: {
    ga4Id: ""
  },
  // PWA "Add to home screen" icons — square PNG, ideally 192x192 and 512x512.
  // Falls back to the horizontal logo below if left empty (works, but a
  // proper square icon looks better on a home screen).
  pwa: {
    icon192: "https://stay.keyhost.online/wp-content/uploads/2026/07/keyhost-192-x-192-px.png",
    icon512: "https://stay.keyhost.online/wp-content/uploads/2026/07/keyhost-512-x-512-px.png"
  },
  // Currency converter — LIVE by default (fetches ECB rates from api.frankfurter.dev,
  // free, no API key, refreshed once/day by that service). The values below are
  // only a fallback used if the live fetch fails (offline, API down, etc).
  // Update them occasionally so the fallback stays roughly accurate.
  currency: {
    updated: "2026-07",
    ilsToEur: 0.26,
    ilsToUsd: 0.27
  }
};
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="noindex, nofollow">
<title>KeyHost — Your Stay Companion</title>

<!-- PWA — "Add to home screen". manifest.json is a separate file, deploy it
     alongside this page at the site root (or update the href below to its
     actual path). Icons are pulled from KEYHOST_CONFIG.pwa via JS below. -->
<link rel="manifest" href="/manifest.json">
<meta name="theme-color" content="#0D1B2A">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="KeyHost">
<link rel="apple-touch-icon" id="appleTouchIcon" href="https://stay.keyhost.online/wp-content/uploads/2026/07/keyhost-192-x-192-px.png">

<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=DM+Serif+Display&family=Manrope:wght@400;500;600;700;800&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">

<!-- Analytics — GA4 only loads if window.KEYHOST_CONFIG.analytics.ga4Id is
     set (see KEYHOST_CONFIG at the top of this file). Nothing is sent
     otherwise: no script tag is injected, no request is made. -->
<script>
(function () {
  var id = (window.KEYHOST_CONFIG && window.KEYHOST_CONFIG.analytics && window.KEYHOST_CONFIG.analytics.ga4Id) || '';
  if (!id) return;
  var s = document.createElement('script');
  s.async = true;
  s.src = 'https://www.googletagmanager.com/gtag/js?id=' + id;
  document.head.appendChild(s);
  window.dataLayer = window.dataLayer || [];
  function gtag() { dataLayer.push(arguments); }
  window.gtag = gtag;
  gtag('js', new Date());
  gtag('config', id);
})();
</script>
<style>
:root {
  --kh-navy:       #0D1B2A;
  --kh-navy-deep:  #081420;
  --kh-surface-1:  #16283C;
  --kh-surface-2:  #1C3049;
  --kh-accent:     #4C8CFF;
  --kh-text:       #F9F8F6;
  --kh-text-soft:  rgba(249,248,246,.72);
  --kh-text-faint: rgba(249,248,246,.48);
  --kh-border:     rgba(249,248,246,.12);
  --kh-border-soft: rgba(249,248,246,.08);
  --kh-stone-warm: #E8E0D5;
  --font-display:  'DM Serif Display', Georgia, serif;
  --font-heading:  'Manrope', system-ui, sans-serif;
  --font-body:     'Inter', system-ui, sans-serif;
  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
  --space-6: 24px; --space-8: 32px; --space-16: 64px; --space-20: 80px;
  --radius-sm: 4px; --radius: 8px; --radius-lg: 12px; --radius-xl: 16px; --radius-full: 100px;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 84px; }
/* Safety net: no single element should ever be able to push the whole page into
   horizontal overflow (this is what caused the v4 mis-centering bug — a flex row
   that refused to shrink below its content width). Belt-and-suspenders. */
html, body { max-width: 100%; overflow-x: hidden; }
/* Disable the WordPress admin toolbar so the KeyHost header sits at the true top of the viewport. */
#wpadminbar { display: none !important; }
html { margin-top: 0 !important; }
body { margin-top: 0 !important; }
body {
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.65;
  color: var(--kh-text-soft);
  background: var(--kh-navy);
  padding-top: 84px; /* offsets the fixed header (position:fixed, no longer in flow) */
}

/* ---------- Header ---------- */
.app-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  height: 84px;
  background: rgba(13,27,42,.92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--kh-border-soft);
  display: flex; align-items: center;
}
.header-inner {
  width: 100%; max-width: 720px; margin: 0 auto; padding: 0 var(--space-4);
  display: flex; align-items: center; justify-content: space-between;
}
.logo { display: flex; align-items: center; gap: var(--space-2); text-decoration: none; }
.logo-img { height: 64px; width: auto; display: block; }
.app-footer .logo-img { height: 48px; }
.logo-tag { font-family: var(--font-body); font-weight: 600; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--kh-text-faint); }
.lang-toggle {
  display: flex; border: 1px solid var(--kh-border); border-radius: var(--radius-full);
  overflow: hidden; background: var(--kh-surface-1);
}
.lang-btn {
  border: none; background: transparent; cursor: pointer;
  font-family: var(--font-heading); font-weight: 600; font-size: 13px;
  color: var(--kh-text-soft); padding: 6px 14px; border-radius: var(--radius-full);
  transition: background .15s, color .15s;
}
.lang-btn.active { background: var(--kh-accent); color: var(--kh-text); }

/* ---------- Layout ---------- */
.container { max-width: 720px; margin: 0 auto; padding: 0 var(--space-4); }
section { padding: var(--space-16) 0; }

/* ---------- Hero ---------- */
.hero { padding: var(--space-16) 0 var(--space-8); }
.hero h1 {
  font-family: var(--font-display); font-weight: 400;
  font-size: clamp(48px, 8vw, 60px);
  line-height: 1.15; letter-spacing: -0.02em; color: var(--kh-text);
}
.hero h1 .accent-word { font-style: italic; color: var(--kh-stone-warm); }
.hero .hero-sub {
  margin-top: var(--space-4); font-size: 16px; color: var(--kh-text-soft); max-width: 520px;
}
.hero-media {
  margin-top: var(--space-8);
  aspect-ratio: 16 / 9;
  background: var(--kh-surface-1);
  border: 1px solid var(--kh-border);
  border-radius: var(--radius-lg);
  display: flex; align-items: center; justify-content: center;
  color: var(--kh-text-faint);
  font-family: var(--font-body); font-weight: 600; font-size: 11px;
  letter-spacing: 0.08em; text-transform: uppercase;
}
.hero-anchors { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-6); }
.anchor-chip {
  text-decoration: none;
  font-family: var(--font-heading); font-weight: 600; font-size: 14px;
  color: var(--kh-navy);
  background: var(--kh-stone-warm);
  border: 1.5px solid var(--kh-stone-warm); border-radius: var(--radius-full);
  padding: 9px 20px;
  transition: background .15s, color .15s, border-color .15s;
}
.anchor-chip:hover { background: var(--kh-accent); border-color: var(--kh-accent); color: var(--kh-text); }
.install-app-btn { appearance: none; -webkit-appearance: none; font: inherit; }

/* ---------- Section headings ---------- */
.section-label {
  font-family: var(--font-body); font-weight: 600; font-size: 11px;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--kh-text-faint);
  margin-bottom: var(--space-2);
}
h2 {
  font-family: var(--font-heading); font-weight: 700; font-size: 28px;
  line-height: 1.2; letter-spacing: -0.02em; color: var(--kh-text);
  margin-bottom: var(--space-6);
}
h3 { font-family: var(--font-heading); font-weight: 600; font-size: 18px; line-height: 1.4; color: var(--kh-text); }

/* ---------- Infos pratiques ---------- */
.essentials { background: var(--kh-navy-deep); }
.cards-grid { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: var(--space-4); }
@media (max-width: 640px) { .cards-grid { grid-template-columns: minmax(0,1fr); } }
.card {
  background: var(--kh-surface-1);
  border: 1px solid var(--kh-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}
.card-icon { margin-bottom: var(--space-3); }
.card-icon svg { width: 24px; height: 24px; stroke: var(--kh-accent); stroke-width: 1.5; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.card h3 { margin-bottom: var(--space-2); }
.card ul { list-style: none; }
.card li { padding: var(--space-1) 0; font-size: 15px; color: var(--kh-text-soft); }
.card li strong { font-weight: 500; color: var(--kh-text); }
.card a { color: var(--kh-accent); text-decoration: none; font-weight: 500; }
.card a:hover { text-decoration: underline; }
.card .caption { font-size: 13px; color: var(--kh-text-faint); margin-top: var(--space-2); }

/* ---------- Currency converter ---------- */
.converter-row { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-3); }
.converter-row input {
  flex: 1; min-width: 0; font-family: var(--font-body); font-size: 15px; color: var(--kh-text);
  background: var(--kh-navy); border: 1px solid var(--kh-border);
  border-radius: var(--radius-sm); padding: 8px var(--space-3); outline: none;
  transition: border-color .15s;
}
.converter-row input:focus { border-color: var(--kh-accent); }
.converter-unit { font-family: var(--font-heading); font-weight: 600; color: var(--kh-text-faint); }
.converter-result { font-family: var(--font-heading); font-weight: 600; font-size: 15px; color: var(--kh-text); padding: 2px 0; flex: 1; }
.converter-select {
  min-width: 0; max-width: 40%;
  font-family: var(--font-heading); font-weight: 600; font-size: 13px; color: var(--kh-text);
  background: var(--kh-surface-2); border: 1px solid var(--kh-border);
  border-radius: var(--radius-sm); padding: 8px 10px; outline: none; cursor: pointer;
  transition: border-color .15s;
}
.converter-select:focus { border-color: var(--kh-accent); }
.converter-swap {
  display: block; margin: 2px auto var(--space-2); width: 32px; height: 32px;
  border-radius: var(--radius-full); border: 1px solid var(--kh-border); background: var(--kh-surface-2);
  color: var(--kh-accent); font-size: 15px; cursor: pointer; transition: background .15s;
}
.converter-swap:hover { background: var(--kh-surface-1); }

/* ---------- Guide de ville ---------- */
.city-selector {
  display: flex; flex-wrap: wrap; gap: var(--space-2);
  margin-bottom: var(--space-6);
}
.city-pill {
  border: 1px solid var(--kh-border); background: var(--kh-surface-1);
  border-radius: var(--radius-full); padding: 8px 18px; cursor: pointer;
  font-family: var(--font-heading); font-weight: 600; font-size: 14px; color: var(--kh-text-soft);
  transition: background .15s, color .15s, border-color .15s;
}
.city-pill.active { background: var(--kh-accent); border-color: var(--kh-accent); color: var(--kh-text); }
.city-intro { margin-bottom: var(--space-6); max-width: 560px; color: var(--kh-text-soft); }
.weather-display { display: flex; align-items: center; gap: var(--space-4); }
.weather-display svg { width: 56px; height: 56px; stroke: var(--kh-accent); fill: none; stroke-width: 1.2; flex: 0 0 auto; }
.weather-temp { font-family: var(--font-heading); font-weight: 700; font-size: 32px; color: var(--kh-text); }
.weather-display .weather-loading, .weather-display .weather-error { font-family: var(--font-heading); font-weight: 600; font-size: 15px; color: var(--kh-text-faint); }
.shabbat-display { display: flex; flex-direction: column; gap: var(--space-2); }
.shabbat-row { font-size: 15px; color: var(--kh-text-soft); }
.shabbat-row strong { color: var(--kh-text); font-weight: 600; }
.shabbat-display .shabbat-loading, .shabbat-display .shabbat-error { font-family: var(--font-heading); font-weight: 600; font-size: 15px; color: var(--kh-text-faint); }

/* ---------- Concierge ---------- */
.concierge-body { font-size: 15px; color: var(--kh-text-soft); margin-bottom: var(--space-4); }
.card .btn-whatsapp {
  display: inline-flex; align-items: center; gap: var(--space-2);
  text-decoration: none; font-family: var(--font-heading); font-weight: 600; font-size: 14px;
  color: var(--kh-text); background: var(--kh-accent); border-radius: var(--radius-full);
  padding: 9px 18px; transition: opacity .15s;
}
.btn-whatsapp:hover { opacity: .9; }
.btn-whatsapp svg { width: 16px; height: 16px; stroke: var(--kh-text); fill: none; stroke-width: 1.8; }
.guide-media {
  aspect-ratio: 16 / 9; background: var(--kh-surface-1); border: 1px solid var(--kh-border); border-radius: var(--radius-lg);
  display: flex; align-items: center; justify-content: center;
  color: var(--kh-text-faint); font-weight: 600; font-size: 11px;
  letter-spacing: 0.08em; text-transform: uppercase;
  margin-bottom: var(--space-6);
}
.guide-blocks { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: var(--space-4); }
@media (max-width: 640px) { .guide-blocks { grid-template-columns: minmax(0,1fr); } }
.guide-block {
  background: var(--kh-surface-1); border: 1px solid var(--kh-border);
  border-radius: var(--radius-lg); padding: var(--space-6);
}
.guide-block h3 { margin-bottom: var(--space-2); font-size: 16px; }
.guide-block ul { list-style: none; }
.guide-block li { padding: var(--space-1) 0; font-size: 15px; color: var(--kh-text-soft); }
.guide-tip {
  grid-column: 1 / -1;
  background: var(--kh-surface-2); border: 1px solid var(--kh-border);
}
.guide-tip p { font-size: 15px; color: var(--kh-text-soft); }

/* ---------- FAQ ---------- */
.faq-item {
  border: 1px solid var(--kh-border); border-radius: var(--radius-lg);
  background: var(--kh-surface-1); margin-bottom: var(--space-3); overflow: hidden;
}
.faq-question {
  width: 100%; text-align: left; background: none; border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  font-family: var(--font-heading); font-weight: 600; font-size: 15px; color: var(--kh-text);
}
.faq-question .chevron { flex: 0 0 auto; width: 18px; height: 18px; stroke: var(--kh-text-faint); stroke-width: 2; fill: none; transition: transform .2s; }
.faq-item.open .chevron { transform: rotate(180deg); }
.faq-answer {
  max-height: 0; overflow: hidden; transition: max-height .2s ease;
  padding: 0 var(--space-6);
}
.faq-item.open .faq-answer { padding: 0 var(--space-6) var(--space-4); }
.faq-answer p { font-size: 15px; color: var(--kh-text-soft); }

/* ---------- Contact ---------- */
.contact { background: var(--kh-navy-deep); }
.contact-card {
  background: var(--kh-surface-1); border: 1px solid var(--kh-border);
  border-radius: var(--radius-lg);
  padding: var(--space-8);
}
.contact-sub { margin-bottom: var(--space-6); max-width: 520px; color: var(--kh-text-soft); }
.form-field { margin-bottom: var(--space-4); }
.form-field label {
  display: block; font-family: var(--font-body); font-weight: 600; font-size: 11px;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--kh-text-faint);
  margin-bottom: var(--space-2);
}
.form-field input, .form-field textarea {
  width: 100%; font-family: var(--font-body); font-size: 15px; color: var(--kh-text);
  background: var(--kh-navy); border: 1px solid var(--kh-border);
  border-radius: var(--radius-sm); padding: 12px var(--space-4);
  outline: none; transition: border-color .15s;
}
.form-field input::placeholder, .form-field textarea::placeholder { color: var(--kh-text-faint); }
.form-field input:focus, .form-field textarea:focus { border-color: var(--kh-accent); }
.form-field textarea { min-height: 120px; resize: vertical; }
.btn-submit {
  display: inline-block; border: none; cursor: pointer;
  background: var(--kh-accent); color: var(--kh-text);
  font-family: var(--font-heading); font-weight: 600; font-size: 14px;
  border-radius: var(--radius-full); padding: 13px 32px;
  transition: opacity .15s;
}
.btn-submit:hover { opacity: .9; }
.form-note { font-size: 13px; color: var(--kh-text-faint); margin-top: var(--space-3); }
.form-success {
  display: none;
  min-height: 320px;
  flex-direction: column; align-items: center; justify-content: center; text-align: center;
  gap: var(--space-2);
  font-size: 16px; color: var(--kh-text-soft);
}
.form-success.visible { display: flex; }
.form-success strong { font-size: 20px; color: #5FD68B; font-weight: 700; }

/* ---------- Footer ---------- */
.app-footer { background: var(--kh-navy-deep); border-top: 1px solid var(--kh-border-soft); color: var(--kh-text-soft); padding: var(--space-16) 0; }
.app-footer .logo-name { color: var(--kh-text); }
.footer-grid { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-6); align-items: flex-start; }
.footer-contact { font-size: 15px; line-height: 2; }
.footer-contact a { color: var(--kh-text-soft); text-decoration: none; }
.footer-contact a:hover { color: var(--kh-text); text-decoration: underline; }
.footer-caption { margin-top: var(--space-8); font-size: 13px; color: var(--kh-text-faint); }

/* ---------- Back to top ---------- */
.back-to-top {
  position: fixed; bottom: 20px; left: 50%; z-index: 200;
  width: 40px; height: 40px; border-radius: var(--radius-full); border: none; cursor: pointer;
  background: rgba(13,27,42,.72); backdrop-filter: blur(8px); box-shadow: 0 4px 14px rgba(0,0,0,.3);
  display: flex; align-items: center; justify-content: center;
  opacity: 0; pointer-events: none; transform: translate(-50%, 8px);
  transition: opacity .2s, transform .2s;
}
.back-to-top.visible { opacity: 1; pointer-events: auto; transform: translate(-50%, 0); }
.back-to-top svg { width: 18px; height: 18px; stroke: #FFFFFF; stroke-width: 2; fill: none; stroke-linecap: round; stroke-linejoin: round; }
</style>
</head>
<body>

<!-- ================= HEADER ================= -->
<header class="app-header">
  <div class="header-inner">
    <a class="logo" href="#">
      <img class="logo-img" src="https://stay.keyhost.online/wp-content/uploads/2026/07/KH-long-white-transparent-scaled.png" alt="KeyHost">
    </a>
    <div class="lang-toggle" role="group" aria-label="Language">
      <button class="lang-btn active" data-lang="en">EN</button>
      <button class="lang-btn" data-lang="fr">FR</button>
    </div>
  </div>
</header>

<!-- ================= HERO ================= -->
<div class="hero">
  <div class="container">
    <h1><span data-i18n="heroTitleMain">Welcome to your</span> <span class="accent-word" data-i18n="heroTitleAccent">stay</span></h1>
    <p class="hero-sub" data-i18n="heroSub">Everything you need during your KeyHost stay in Israel — practical essentials, city guides and a direct line to our team, 7 days a week.</p>
    <div class="hero-anchors">
      <a class="anchor-chip" href="#essentials" data-i18n="anchorEssentials">Essentials</a>
      <a class="anchor-chip" href="#guide" data-i18n="anchorGuide">City guide</a>
      <a class="anchor-chip" href="#concierge" data-i18n="anchorConcierge">Concierge</a>
      <a class="anchor-chip" href="#faq" data-i18n="anchorFaq">FAQ</a>
      <a class="anchor-chip" href="#contact" data-i18n="anchorContact">Contact us</a>
      <button type="button" id="installAppBtn" class="anchor-chip install-app-btn" style="display:none;">Install app</button>
    </div>
    <div class="hero-media" id="heroMedia" data-i18n="mediaPlaceholder">Image 16:9 — architecture / lumière naturelle</div>
  </div>
</div>

<!-- ================= INFOS PRATIQUES ================= -->
<section class="essentials" id="essentials">
  <div class="container">
    <div class="section-label" data-i18n="essentialsLabel">During your stay</div>
    <h2 data-i18n="essentialsTitle">The essentials</h2>
    <div class="cards-grid">

      <div class="card">
        <div class="card-icon"><svg viewBox="0 0 24 24"><path d="M3 21h18"/><path d="M9 8h1"/><path d="M9 12h1"/><path d="M9 16h1"/><path d="M14 8h1"/><path d="M14 12h1"/><path d="M14 16h1"/><path d="M5 21V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v16"/></svg></div>
        <h3 data-i18n="arrivalTitle">Arrival & departure</h3>
        <ul>
          <li data-i18n="arrival1">Your check-in and check-out times are in your booking confirmation.</li>
          <li data-i18n="arrival2">Key handover is arranged directly with our team before your arrival.</li>
          <li data-i18n="arrival3">Running late? Let us know — we adapt.</li>
        </ul>
      </div>

      <div class="card">
        <div class="card-icon"><svg viewBox="0 0 24 24"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 16.92z"/></svg></div>
        <h3 data-i18n="emergencyTitle">Assistance & emergencies</h3>
        <ul>
          <li><strong data-i18n="emergencyKh">KeyHost, 7 days a week:</strong><br><a href="tel:+972535878284" data-contact="phone">+972 53 58 78 284</a> · <a href="https://wa.me/972535878284" data-contact="whatsapp">WhatsApp</a></li>
          <li data-i18n="emergencyNumbers">National numbers: Police 100 · Ambulance 101 · Fire 102</li>
        </ul>
      </div>

      <div class="card">
        <div class="card-icon"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><path d="M12 8v4l2 2"/></svg></div>
        <h3 data-i18n="knowTitle">Good to know</h3>
        <ul>
          <li data-i18n="know1">Currency: shekel (₪). Cards accepted almost everywhere.</li>
          <li data-i18n="know2">Power: 230V, type C / H plugs.</li>
          <li data-i18n="know3">Tap water is safe to drink.</li>
          <li data-i18n="know4">Taxis: use the Gett app — fixed prices, no haggling.</li>
          <li data-i18n="know5">Tipping: 10–12% in restaurants.</li>
        </ul>
      </div>

      <div class="card">
        <div class="card-icon"><svg viewBox="0 0 24 24"><path d="M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9z"/></svg></div>
        <h3 data-i18n="shabbatTitle">Shabbat</h3>
        <ul>
          <li data-i18n="shabbat1">From Friday sunset to Saturday nightfall, most shops and public transport pause.</li>
          <li data-i18n="shabbat2">Plan groceries and travel ahead — or simply enjoy the calm like the locals do.</li>
        </ul>
        <p class="caption" data-i18n="shabbat3">Tel Aviv stays livelier than most cities; Jerusalem observes it fully.</p>
      </div>

      <div class="card">
        <div class="card-icon"><svg viewBox="0 0 24 24"><path d="M20 6 9 17l-5-5"/></svg></div>
        <h3 data-i18n="departureTitle">Before you leave</h3>
        <ul>
          <li data-i18n="departure1">Close all windows and lock the door.</li>
          <li data-i18n="departure2">Turn off the AC and lights.</li>
          <li data-i18n="departure3">Take the trash out to the building's bin area.</li>
          <li data-i18n="departure4">Leave the keys as arranged with our team.</li>
        </ul>
      </div>

      <div class="card">
        <div class="card-icon"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M14.5 9.5a2.5 2.5 0 0 0-2.5-1.5h-.5a2 2 0 0 0 0 4h1a2 2 0 0 1 0 4h-.5a2.5 2.5 0 0 1-2.5-1.5"/><path d="M12 6.5v1"/><path d="M12 16.5v1"/></svg></div>
        <h3 data-i18n="currencyTitle">Currency converter</h3>
        <div class="converter">
          <div class="converter-row">
            <input type="number" id="convAmount" value="100" min="0" step="1" inputmode="decimal" aria-label="Amount">
            <select id="convFrom" class="converter-select" aria-label="From currency">
              <option value="ILS">₪ ILS</option>
              <option value="EUR">€ EUR</option>
              <option value="USD">$ USD</option>
            </select>
          </div>
          <button type="button" class="converter-swap" id="convSwap" aria-label="Swap currencies" title="Swap">⇅</button>
          <div class="converter-row">
            <div class="converter-result" id="convResult">≈ —</div>
            <select id="convTo" class="converter-select" aria-label="To currency">
              <option value="EUR" selected>€ EUR</option>
              <option value="ILS">₪ ILS</option>
              <option value="USD">$ USD</option>
            </select>
          </div>
          <p class="caption" id="convMeta">Live rate (ECB, via frankfurter.dev) — not for exact transactions.</p>
        </div>
      </div>

    </div>
  </div>
</section>

<!-- ================= GUIDE DE VILLE ================= -->
<section id="guide">
  <div class="container">
    <div class="section-label" data-i18n="guideLabel">Explore</div>
    <h2 data-i18n="guideTitle">Your city guide</h2>

    <p data-i18n="cityPrompt" style="font-family:var(--font-heading);font-weight:600;font-size:14px;color:var(--kh-text);margin-bottom:var(--space-3);">Pick your city below:</p>
    <div class="city-selector" id="citySelector" role="tablist"></div>

    <p class="city-intro" id="cityIntro"></p>
    <div class="guide-media" id="cityMedia"></div>

    <div class="guide-blocks">
      <div class="guide-block">
        <h3 data-i18n="weatherTitle">Current weather</h3>
        <div class="weather-display" id="cityWeather"></div>
      </div>
      <div class="guide-block">
        <h3 data-i18n="shabbatTimesTitle">Shabbat this week</h3>
        <div class="shabbat-display" id="cityShabbat"></div>
      </div>
      <div class="guide-block">
        <h3 data-i18n="seeTitle">Must see</h3>
        <ul id="citySee"></ul>
      </div>
      <div class="guide-block">
        <h3 data-i18n="eatTitle">Where to eat</h3>
        <ul id="cityEat"></ul>
      </div>
      <div class="guide-block">
        <h3 data-i18n="moveTitle">Getting around</h3>
        <ul id="cityMove"></ul>
      </div>
      <div class="guide-block guide-tip">
        <h3 data-i18n="tipTitle">KeyHost tip</h3>
        <p id="cityTip"></p>
      </div>
    </div>

    <div style="margin-top:var(--space-6);">
      <a id="cityGuideDownload" class="anchor-chip" style="display:none;" target="_blank" rel="noopener" data-i18n="downloadGuideBtn">Download the guide (PDF)</a>
    </div>
  </div>
</section>

<!-- ================= CONCIERGE ================= -->
<section id="concierge">
  <div class="container">
    <div class="section-label" data-i18n="conciergeLabel">Add to your stay</div>
    <h2 data-i18n="conciergeTitle">Concierge services</h2>
    <p class="city-intro" data-i18n="conciergeIntro">Order any of these directly on WhatsApp — we confirm availability and pricing.</p>
    <div class="cards-grid" id="conciergeGrid"></div>
  </div>
</section>

<!-- ================= FAQ ================= -->
<section class="essentials" id="faq">
  <div class="container">
    <div class="section-label" data-i18n="faqLabel">Common questions</div>
    <h2 data-i18n="faqTitle">FAQ</h2>
    <div id="faqList"></div>
  </div>
</section>

<!-- ================= CONTACT ================= -->
<section class="contact" id="contact">
  <div class="container">
    <div class="section-label" data-i18n="contactLabel">We're here</div>
    <h2 data-i18n="contactTitle">Contact KeyHost</h2>
    <div class="contact-card">
      <p class="contact-sub" data-i18n="contactSub">A question, a request, something not working? Write to us — our team answers by email or phone, 7 days a week.</p>
      <form id="contactForm">
        <input type="hidden" name="source" value="app">
        <!-- Honeypot anti-spam — real visitors never see or fill this field
             (off-screen, not display:none so basic bots can't detect and skip
             it via computed style). The WPCode PHP handler checks this field
             first: if it's non-empty, it silently returns a fake success
             without sending any email. See brief section 10. -->
        <div style="position:absolute; left:-9999px; top:-9999px;" aria-hidden="true">
          <label for="f-website">Website</label>
          <input type="text" id="f-website" name="website" tabindex="-1" autocomplete="off">
        </div>
        <div id="contactFormFields">
          <div class="form-field">
            <label for="f-name" data-i18n="fieldName">Your name</label>
            <input type="text" id="f-name" name="name" autocomplete="name" required>
          </div>
          <div class="form-field">
            <label for="f-email" data-i18n="fieldEmail">Your email</label>
            <input type="email" id="f-email" name="email" autocomplete="email" required placeholder="name@email.com">
          </div>
          <div class="form-field">
            <label for="f-phone" data-i18n="fieldPhone">Your phone</label>
            <input type="tel" id="f-phone" name="phone" autocomplete="tel" required placeholder="+972 5X XXX XXXX">
          </div>
          <div class="form-field">
            <label for="f-property" data-i18n="fieldProperty">Your apartment (address or name)</label>
            <input type="text" id="f-property" name="property" autocomplete="off" required>
          </div>
          <div class="form-field">
            <label for="f-message" data-i18n="fieldMessage">Your message</label>
            <textarea id="f-message" name="message" required></textarea>
          </div>
          <button type="submit" class="btn-submit" data-i18n="submitBtn">Send message</button>
          <p class="form-note" data-i18n="formNote">Your message goes straight to our team — we usually reply within a few hours.</p>
        </div>
        <div class="form-success" id="formSuccess">
          <strong data-i18n="successStrong">Message sent.</strong><br>
          <span data-i18n="successText">Our team will get back to you shortly.</span>
        </div>
        <p class="form-note" id="formError" style="display:none;color:#F09595;margin-top:var(--space-3);" data-i18n="formError">Something went wrong. Please try again or contact us directly by phone.</p>
      </form>
    </div>
  </div>
</section>

<!-- ================= FOOTER ================= -->
<footer class="app-footer">
  <div class="container">
    <div class="footer-grid">
      <div>
        <a class="logo" href="#">
          <img class="logo-img" src="https://stay.keyhost.online/wp-content/uploads/2026/07/KH-long-white-transparent-scaled.png" alt="KeyHost">
        </a>
      </div>
      <div class="footer-contact">
        <a href="tel:+972535878284" data-contact="phone">+972 53 58 78 284</a><br>
        <a href="mailto:contact@keyhost.online" data-contact="email">contact@keyhost.online</a><br>
        <a href="https://keyhost.online" data-i18n="footerSite">keyhost.online — our properties & services</a>
      </div>
    </div>
    <p class="footer-caption" data-i18n="footerCaption">KeyHost — Short-term rental management · Tel Aviv, Jerusalem, Herzliya, Netanya, Haifa, Caesarea, Eilat</p>
  </div>
</footer>

<!-- Back to top — self-contained (this page has no theme header/footer to
     inherit the site-wide scroll-to-top snippet from). -->
<button type="button" id="backToTop" class="back-to-top" aria-label="Back to top" title="Back to top">
  <svg viewBox="0 0 24 24"><path d="M12 19V5"/><path d="m5 12 7-7 7 7"/></svg>
</button>

<script>
/* =============== I18N =============== */
const I18N = {
  en: {
    logoTag: "Traveler",
    heroTitleMain: "Welcome to your",
    heroTitleAccent: "stay",
    heroSub: "Everything you need during your KeyHost stay in Israel — practical essentials, city guides and a direct line to our team, 7 days a week.",
    anchorEssentials: "Essentials", anchorGuide: "City guide", anchorConcierge: "Concierge", anchorFaq: "FAQ", anchorContact: "Contact us",
    installAppBtn: "Install app", addToHomeScreenBtn: "Add to Home Screen", addToHomeScreenHint: "Tap the Share icon, then \"Add to Home Screen\".",
    downloadGuideBtn: "Download the guide (PDF) ↓",
    faqLabel: "Common questions", faqTitle: "FAQ",
    mediaPlaceholder: "16:9 image — architecture / natural light",
    essentialsLabel: "During your stay", essentialsTitle: "The essentials",
    arrivalTitle: "Arrival & departure",
    arrival1: "Your check-in and check-out times are in your booking confirmation.",
    arrival2: "Key handover is arranged directly with our team before your arrival.",
    arrival3: "Running late? Let us know — we adapt.",
    emergencyTitle: "Assistance & emergencies",
    emergencyKh: "KeyHost, 7 days a week:",
    emergencyNumbers: "National numbers: Police 100 · Ambulance 101 · Fire 102",
    knowTitle: "Good to know",
    know1: "Currency: shekel (₪). Cards accepted almost everywhere.",
    know2: "Power: 230V, type C / H plugs.",
    know3: "Tap water is safe to drink.",
    know4: "Taxis: use the Gett app — fixed prices, no haggling.",
    know5: "Tipping: 10–12% in restaurants.",
    shabbatTitle: "Shabbat",
    shabbat1: "From Friday sunset to Saturday nightfall, most shops and public transport pause.",
    shabbat2: "Plan groceries and travel ahead — or simply enjoy the calm like the locals do.",
    shabbat3: "Tel Aviv stays livelier than most cities; Jerusalem observes it fully.",
    departureTitle: "Before you leave",
    departure1: "Close all windows and lock the door.",
    departure2: "Turn off the AC and lights.",
    departure3: "Take the trash out to the building's bin area.",
    departure4: "Leave the keys as arranged with our team.",
    currencyTitle: "Currency converter", currencyCaptionLive: "Live rate (ECB, via frankfurter.dev) — not for exact transactions.", currencyCaptionOffline: "Offline rate, may be a few days old — not for exact transactions.",
    weatherLoading: "Loading weather…", weatherError: "Weather unavailable right now.", weatherTitle: "Current weather",
    shabbatTimesTitle: "Shabbat this week", shabbatLoading: "Loading times…", shabbatError: "Times unavailable right now.", candleLighting: "Candle lighting", havdalah: "Havdalah",
    conciergeLabel: "Add to your stay", conciergeTitle: "Concierge services", conciergeIntro: "Order any of these directly on WhatsApp — we confirm availability and pricing.", conciergeCta: "Ask us on WhatsApp", conciergeMsgPrefix: "Hi KeyHost! I'd like to request:", conciergeMsgSuffix: "Could you share availability and pricing? My apartment:",
    guideLabel: "Explore", guideTitle: "Your city guide",
    cityPrompt: "Pick your city below:",
    seeTitle: "Must see", eatTitle: "Where to eat", moveTitle: "Getting around", tipTitle: "KeyHost tip",
    contactLabel: "We're here", contactTitle: "Contact KeyHost",
    contactSub: "A question, a request, something not working? Write to us — our team answers by email or phone, 7 days a week.",
    fieldName: "Your name", fieldEmail: "Your email", fieldPhone: "Your phone",
    fieldProperty: "Your apartment (address or name)", fieldMessage: "Your message",
    submitBtn: "Send message",
    formNote: "Your message goes straight to our team — we usually reply within a few hours.",
    successStrong: "Message sent.", successText: "Our team will get back to you shortly.",
    formError: "Something went wrong. Please try again or contact us directly by phone.",
    footerSite: "keyhost.online — our properties & services",
    footerCaption: "KeyHost — Short-term rental management · Tel Aviv, Jerusalem, Herzliya, Netanya, Haifa, Caesarea, Eilat"
  },
  fr: {
    logoTag: "Voyageur",
    heroTitleMain: "Bienvenue pour votre",
    heroTitleAccent: "séjour",
    heroSub: "Tout ce qu'il vous faut pendant votre séjour KeyHost en Israël — les essentiels pratiques, les guides de ville et un lien direct avec notre équipe, 7 jours sur 7.",
    anchorEssentials: "Essentiels", anchorGuide: "Guide de ville", anchorConcierge: "Conciergerie", anchorFaq: "FAQ", anchorContact: "Nous contacter",
    installAppBtn: "Installer l'app", addToHomeScreenBtn: "Sur l'écran d'accueil", addToHomeScreenHint: "Appuyez sur l'icône Partager, puis « Sur l'écran d'accueil ».",
    downloadGuideBtn: "Télécharger le guide (PDF) ↓",
    faqLabel: "Questions fréquentes", faqTitle: "FAQ",
    mediaPlaceholder: "Image 16:9 — architecture / lumière naturelle",
    essentialsLabel: "Pendant votre séjour", essentialsTitle: "Les essentiels",
    arrivalTitle: "Arrivée & départ",
    arrival1: "Vos horaires de check-in et check-out figurent dans votre confirmation de réservation.",
    arrival2: "La remise des clés s'organise directement avec notre équipe avant votre arrivée.",
    arrival3: "En retard ? Prévenez-nous — on s'adapte.",
    emergencyTitle: "Assistance & urgences",
    emergencyKh: "KeyHost, 7j/7 :",
    emergencyNumbers: "Numéros nationaux : Police 100 · Ambulance 101 · Pompiers 102",
    knowTitle: "Bon à savoir",
    know1: "Monnaie : le shekel (₪). Carte acceptée presque partout.",
    know2: "Électricité : 230V, prises type C / H.",
    know3: "L'eau du robinet est potable.",
    know4: "Taxis : utilisez l'app Gett — prix fixes, sans négociation.",
    know5: "Pourboire : 10–12% au restaurant.",
    shabbatTitle: "Shabbat",
    shabbat1: "Du vendredi au coucher du soleil jusqu'au samedi soir, la plupart des commerces et transports publics font une pause.",
    shabbat2: "Anticipez courses et déplacements — ou profitez du calme, comme les locaux.",
    shabbat3: "Tel Aviv reste plus animée que la moyenne ; Jérusalem l'observe pleinement.",
    departureTitle: "Avant de partir",
    departure1: "Fermez toutes les fenêtres et verrouillez la porte.",
    departure2: "Éteignez la climatisation et les lumières.",
    departure3: "Sortez les poubelles à l'endroit prévu dans l'immeuble.",
    departure4: "Laissez les clés selon ce qui a été convenu avec notre équipe.",
    currencyTitle: "Convertisseur de devise", currencyCaptionLive: "Taux en direct (BCE, via frankfurter.dev) — non contractuel.", currencyCaptionOffline: "Taux hors-ligne, possiblement daté de quelques jours — non contractuel.",
    weatherLoading: "Chargement de la météo…", weatherError: "Météo indisponible pour le moment.", weatherTitle: "Météo actuelle",
    shabbatTimesTitle: "Shabbat cette semaine", shabbatLoading: "Chargement des horaires…", shabbatError: "Horaires indisponibles pour le moment.", candleLighting: "Allumage des bougies", havdalah: "Havdala",
    conciergeLabel: "En plus de votre séjour", conciergeTitle: "Services de conciergerie", conciergeIntro: "Commandez directement sur WhatsApp — on vous confirme la disponibilité et le tarif.", conciergeCta: "Nous demander sur WhatsApp", conciergeMsgPrefix: "Bonjour KeyHost ! Je souhaiterais demander :", conciergeMsgSuffix: "Pouvez-vous m'indiquer la disponibilité et le tarif ? Mon logement :",
    guideLabel: "Explorer", guideTitle: "Votre guide de ville",
    cityPrompt: "Choisissez votre ville ci-dessous :",
    seeTitle: "À ne pas manquer", eatTitle: "Où manger", moveTitle: "Se déplacer", tipTitle: "Le conseil KeyHost",
    contactLabel: "On est là", contactTitle: "Contacter KeyHost",
    contactSub: "Une question, une demande, quelque chose qui ne fonctionne pas ? Écrivez-nous — notre équipe répond par email ou téléphone, 7j/7.",
    fieldName: "Votre nom", fieldEmail: "Votre email", fieldPhone: "Votre téléphone",
    fieldProperty: "Votre logement (adresse ou nom)", fieldMessage: "Votre message",
    submitBtn: "Envoyer le message",
    formNote: "Votre message part directement vers notre équipe — réponse en général sous quelques heures.",
    successStrong: "Message envoyé.", successText: "Notre équipe revient vers vous rapidement.",
    formError: "Une erreur est survenue. Réessayez ou contactez-nous directement par téléphone.",
    footerSite: "keyhost.online — nos logements & services",
    footerCaption: "KeyHost — Gestion de locations courte durée · Tel Aviv, Jérusalem, Herzliya, Netanya, Haïfa, Césarée, Eilat"
  }
};

/* =============== CITY COORDINATES (for weather) =============== */
/* Open-Meteo — free, no API key required, CORS-friendly for a static page. */
const CITY_COORDS = {
  telaviv:  { lat: 32.0853, lon: 34.7818 },
  jerusalem:{ lat: 31.7683, lon: 35.2137 },
  herzliya: { lat: 32.1624, lon: 34.8447 },
  netanya:  { lat: 32.3226, lon: 34.8533 },
  haifa:    { lat: 32.7940, lon: 34.9896 },
  caesarea: { lat: 32.5000, lon: 34.9000 },
  eilat:    { lat: 29.5581, lon: 34.9482 },
  nazareth: { lat: 32.7021, lon: 35.2978 }
};

/* =============== CITY GUIDES =============== */
const CITIES = {
  telaviv: {
    name: { en: "Tel Aviv", fr: "Tel Aviv" },
    intro: {
      en: "The city that never pauses — 14 km of beaches, world-class food and a café culture that runs from sunrise to well past midnight.",
      fr: "La ville qui ne s'arrête jamais — 14 km de plages, une scène culinaire de classe mondiale et une culture café du lever du soleil à bien après minuit."
    },
    see: {
      en: ["The beach promenade (Tayelet), from the port to Jaffa", "Old Jaffa — alleys, flea market, harbor", "Carmel Market & the Neve Tzedek quarter", "Bauhaus architecture on Rothschild Boulevard"],
      fr: ["La promenade du bord de mer (Tayelet), du port à Jaffa", "Vieux Jaffa — ruelles, marché aux puces, port", "Marché Carmel & le quartier de Neve Tzedek", "Architecture Bauhaus sur le boulevard Rothschild"]
    },
    eat: {
      en: ["Sarona Market — covered gourmet hall", "Falafel & hummus around Carmel Market", "Jaffa's port restaurants at sunset"],
      fr: ["Sarona Market — halle gourmande couverte", "Falafels & houmous autour du marché Carmel", "Les restaurants du port de Jaffa au coucher du soleil"]
    },
    move: {
      en: ["Rental bikes & e-scooters along the seafront", "Light rail (Red Line) crosses the city", "Gett for taxis — avoid driving downtown"],
      fr: ["Vélos & trottinettes en libre-service le long du front de mer", "Le tramway (ligne rouge) traverse la ville", "Gett pour les taxis — évitez de conduire dans le centre"]
    },
    tip: {
      en: "Sunday is a regular working day here. For a quieter beach, walk 10 minutes north of the marina.",
      fr: "Le dimanche est un jour ouvré normal ici. Pour une plage plus calme, marchez 10 minutes au nord de la marina."
    }
  },
  jerusalem: {
    name: { en: "Jerusalem", fr: "Jérusalem" },
    intro: {
      en: "Three thousand years of history in golden stone — holy sites, vibrant markets and viewpoints you will not forget.",
      fr: "Trois mille ans d'histoire dans la pierre dorée — lieux saints, marchés vibrants et points de vue inoubliables."
    },
    see: {
      en: ["The Old City & the Western Wall", "Mahane Yehuda market — by day and by night", "Mount of Olives viewpoint at sunrise", "Yad Vashem memorial"],
      fr: ["La Vieille Ville & le mur Occidental", "Le marché Mahane Yehuda — de jour comme de nuit", "Le point de vue du mont des Oliviers au lever du soleil", "Le mémorial Yad Vashem"]
    },
    eat: {
      en: ["Mahane Yehuda stalls — sabich, knafeh, fresh juice", "First Station complex for family dinners", "Old City hummus institutions"],
      fr: ["Les étals de Mahane Yehuda — sabich, knafeh, jus frais", "Le complexe First Station pour dîner en famille", "Les institutions du houmous de la Vieille Ville"]
    },
    move: {
      en: ["Light rail along Jaffa Street", "The Old City is walking-only — wear good shoes", "Fast train to Tel Aviv in ~35 minutes"],
      fr: ["Le tramway le long de la rue de Jaffa", "La Vieille Ville se parcourt à pied — prévoyez de bonnes chaussures", "Train rapide vers Tel Aviv en ~35 minutes"]
    },
    tip: {
      en: "Dress modestly for holy sites (covered shoulders and knees). Everything closes for Shabbat — plan your Friday.",
      fr: "Tenue sobre pour les lieux saints (épaules et genoux couverts). Tout ferme pendant Shabbat — anticipez votre vendredi."
    }
  },
  herzliya: {
    name: { en: "Herzliya", fr: "Herzliya" },
    intro: {
      en: "The elegant seaside address just north of Tel Aviv — marina, wide beaches and a relaxed residential pace.",
      fr: "L'adresse balnéaire élégante juste au nord de Tel Aviv — marina, larges plages et rythme résidentiel apaisé."
    },
    see: {
      en: ["Herzliya Marina — the largest in Israel", "Acadia beach", "Apollonia National Park — crusader fortress on the cliff"],
      fr: ["La marina d'Herzliya — la plus grande d'Israël", "La plage Acadia", "Le parc national d'Apollonia — forteresse croisée sur la falaise"]
    },
    eat: {
      en: ["Marina waterfront restaurants", "Beach cafés along Acadia", "Herzliya Pituach's restaurant row"],
      fr: ["Les restaurants du front de mer de la marina", "Les cafés de plage le long d'Acadia", "La rangée de restaurants d'Herzliya Pituach"]
    },
    move: {
      en: ["Gett taxis for short hops", "Train station connects to Tel Aviv in ~15 minutes", "Sea-front promenade walkable end to end"],
      fr: ["Taxis Gett pour les petits trajets", "La gare relie Tel Aviv en ~15 minutes", "La promenade du bord de mer se fait à pied d'un bout à l'autre"]
    },
    tip: {
      en: "Sunset drinks at the marina, then dinner on the boardwalk — book ahead on Thursday and Friday evenings.",
      fr: "Apéritif au coucher du soleil à la marina, puis dîner sur la promenade — réservez le jeudi et le vendredi soir."
    }
  },
  netanya: {
    name: { en: "Netanya", fr: "Netanya" },
    intro: {
      en: "Fourteen kilometers of cliff-top coastline, a lively French-speaking community and some of the country's finest beaches.",
      fr: "Quatorze kilomètres de littoral en haut de falaise, une communauté francophone animée et parmi les plus belles plages du pays."
    },
    see: {
      en: ["The cliff-top promenade and its glass elevator to Sironit beach", "Independence Square (Kikar HaAtsmaut)", "Poleg nature reserve, south of the city"],
      fr: ["La promenade en haut de falaise et son ascenseur vitré vers la plage Sironit", "La place de l'Indépendance (Kikar HaAtsmaut)", "La réserve naturelle de Poleg, au sud de la ville"]
    },
    eat: {
      en: ["Cafés and terraces around Independence Square", "Beachfront restaurants at Sironit", "Friday-morning market food stalls"],
      fr: ["Cafés et terrasses autour de la place de l'Indépendance", "Les restaurants de bord de mer à Sironit", "Les étals du marché du vendredi matin"]
    },
    move: {
      en: ["The free beach elevator saves the cliff climb", "Local buses cover the center; Gett elsewhere", "Train to Tel Aviv in ~30 minutes"],
      fr: ["L'ascenseur gratuit de la plage évite la montée de la falaise", "Les bus locaux couvrent le centre ; Gett ailleurs", "Train vers Tel Aviv en ~30 minutes"]
    },
    tip: {
      en: "Watch the paragliders launch from the cliffs in the late afternoon — the promenade view is the show.",
      fr: "Regardez les parapentes s'élancer des falaises en fin d'après-midi — la promenade offre le meilleur spectacle."
    }
  },
  haifa: {
    name: { en: "Haifa", fr: "Haïfa" },
    intro: {
      en: "A city built on a mountain over the sea — the Bahá'í Gardens cascade, mixed neighborhoods and northern Israel at your doorstep.",
      fr: "Une ville bâtie sur une montagne au-dessus de la mer — la cascade des jardins Bahá'í, des quartiers mixtes et le nord d'Israël à votre porte."
    },
    see: {
      en: ["The Bahá'í Gardens — 19 terraces down Mount Carmel", "The German Colony at the foot of the gardens", "Stella Maris & the Carmelite monastery viewpoint"],
      fr: ["Les jardins Bahá'í — 19 terrasses descendant le mont Carmel", "La Colonie allemande au pied des jardins", "Stella Maris & le point de vue du monastère des Carmélites"]
    },
    eat: {
      en: ["Wadi Nisnas — legendary street food and falafel", "German Colony terraces along Ben Gurion Avenue", "Downtown's new café scene"],
      fr: ["Wadi Nisnas — street food et falafels légendaires", "Les terrasses de la Colonie allemande sur l'avenue Ben Gourion", "La nouvelle scène café du centre-ville"]
    },
    move: {
      en: ["The Carmelit — Israel's only underground funicular", "Metronit rapid buses along the bay", "Cable car from Bat Galim up to Stella Maris"],
      fr: ["Le Carmelit — l'unique funiculaire souterrain d'Israël", "Les bus rapides Metronit le long de la baie", "Le téléphérique de Bat Galim jusqu'à Stella Maris"]
    },
    tip: {
      en: "Haifa is one of the few cities with (limited) public transport on Shabbat — a good base for weekend trips to the Galilee and Akko.",
      fr: "Haïfa est l'une des rares villes avec des transports publics (limités) pendant Shabbat — une bonne base pour des excursions en Galilée et à Akko le week-end."
    }
  },
  caesarea: {
    name: { en: "Caesarea", fr: "Césarée" },
    intro: {
      en: "Herod's ancient harbor turned exclusive seaside village — Roman ruins, a working port and golf-green calm.",
      fr: "L'ancien port d'Hérode devenu village balnéaire exclusif — ruines romaines, port vivant et calme des greens de golf."
    },
    see: {
      en: ["Caesarea National Park — Roman theatre and hippodrome", "The ancient harbor and its ramparts", "The Roman aqueduct on the beach"],
      fr: ["Le parc national de Césarée — théâtre romain et hippodrome", "Le port antique et ses remparts", "L'aqueduc romain sur la plage"]
    },
    eat: {
      en: ["Harbor restaurants inside the ancient port", "Seafood with a view of the ramparts", "Picnic on Aqueduct beach"],
      fr: ["Les restaurants du port antique", "Poissons et fruits de mer avec vue sur les remparts", "Pique-nique sur la plage de l'Aqueduc"]
    },
    move: {
      en: ["A car is the practical option here", "Gett works, with a short wait", "Train station at Binyamina, ~10 minutes away"],
      fr: ["La voiture est l'option pratique ici", "Gett fonctionne, avec un peu d'attente", "Gare de Binyamina à ~10 minutes"]
    },
    tip: {
      en: "Come to Aqueduct beach an hour before sunset — Roman arches, golden light, hardly anyone around.",
      fr: "Venez à la plage de l'Aqueduc une heure avant le coucher du soleil — arches romaines, lumière dorée, presque personne."
    }
  },
  nazareth: {
    name: { en: "Nazareth", fr: "Nazareth" },
    intro: {
      en: "The largest Arab city in Israel and Jesus's childhood home — an Old City of stone alleys, a lively souk and one of Christianity's most important churches.",
      fr: "La plus grande ville arabe d'Israël, où Jésus a grandi — une vieille ville de ruelles en pierre, un souk animé et l'une des églises les plus importantes de la chrétienté."
    },
    see: {
      en: ["The Basilica of the Annunciation — built 1960-1969 over the site of Mary's home, free entry", "The Old City souk (market) — Nazareth's signature experience", "St. Joseph's Church, steps from the Basilica", "Nazareth Village — a living-history recreation of first-century Nazareth"],
      fr: ["La basilique de l'Annonciation — construite entre 1960 et 1969 sur le site présumé de la maison de Marie, entrée gratuite", "Le souk de la vieille ville — l'expérience incontournable de Nazareth", "L'église Saint-Joseph, à quelques pas de la basilique", "Nazareth Village — une reconstitution vivante de la Nazareth du 1er siècle"]
    },
    eat: {
      en: ["Souk stalls for kanafeh and fresh produce", "Old City hummus and grilled meat institutions", "Cafés around the Basilica square"],
      fr: ["Les étals du souk pour le kanafeh et les produits frais", "Les institutions du houmous et des grillades de la vieille ville", "Les cafés autour de la place de la basilique"]
    },
    move: {
      en: ["Buses connect Nazareth to Tel Aviv, Jerusalem, Haifa and Akko", "The Old City is walking-only — narrow stone alleys", "Taxis and Gett cover the modern town"],
      fr: ["Des bus relient Nazareth à Tel Aviv, Jérusalem, Haïfa et Akko", "La vieille ville se parcourt à pied — ruelles étroites en pierre", "Taxis et Gett couvrent la ville moderne"]
    },
    tip: {
      en: "The Basilica closes on Sundays for some sections — check hours before you plan your visit around it.",
      fr: "La basilique ferme certaines sections le dimanche — vérifiez les horaires avant d'organiser votre visite autour d'elle."
    }
  },
  eilat: {
    name: { en: "Eilat", fr: "Eilat" },
    intro: {
      en: "The Red Sea resort at Israel's southern tip — coral reefs, desert mountains and 360 days of sunshine, tax free.",
      fr: "La station balnéaire de la mer Rouge à la pointe sud d'Israël — récifs coralliens, montagnes du désert et 360 jours de soleil, hors taxes."
    },
    see: {
      en: ["Coral Beach nature reserve — snorkel straight from the shore", "The Underwater Observatory", "Timna Park's desert landscapes, 25 minutes north"],
      fr: ["La réserve naturelle de Coral Beach — snorkeling depuis le rivage", "L'Observatoire sous-marin", "Les paysages désertiques du parc de Timna, à 25 minutes au nord"]
    },
    eat: {
      en: ["Marina boardwalk restaurants", "Fish restaurants near the port", "Ice cream on the promenade — it's always the season"],
      fr: ["Les restaurants de la promenade de la marina", "Les restaurants de poisson près du port", "Une glace sur la promenade — c'est toujours la saison"]
    },
    move: {
      en: ["The hotel area is entirely walkable", "Taxis are short and cheap", "Rent a car for Timna and the desert"],
      fr: ["Le quartier des hôtels se fait entièrement à pied", "Les taxis sont courts et bon marché", "Louez une voiture pour Timna et le désert"]
    },
    tip: {
      en: "Eilat is VAT-free — shopping is ~17% cheaper. Snorkel early morning for the calmest water and the most fish.",
      fr: "Eilat est hors TVA — le shopping y est ~17% moins cher. Snorkeling tôt le matin pour une eau calme et un maximum de poissons."
    }
  }
};

/* =============== FAQ =============== */
const FAQS = [
  {
    q: { en: "What time is check-in and check-out?", fr: "Quels sont les horaires de check-in et check-out ?" },
    a: { en: "Standard check-in is from 3pm, check-out by 11am. Exact times are confirmed in your booking.", fr: "Le check-in standard est à partir de 15h, le check-out avant 11h. Les horaires exacts sont confirmés dans votre réservation." }
  },
  {
    q: { en: "Can I get early check-in or late check-out?", fr: "Puis-je avoir un check-in anticipé ou un check-out tardif ?" },
    a: { en: "Often yes, subject to the next booking. Ask our team a few days before your stay.", fr: "Souvent oui, selon la réservation suivante. Demandez à notre équipe quelques jours avant votre séjour." }
  },
  {
    q: { en: "Is Wi-Fi included?", fr: "Le wifi est-il inclus ?" },
    a: { en: "Yes, Wi-Fi is included in every KeyHost apartment. Network details are provided on-site.", fr: "Oui, le wifi est inclus dans tous les logements KeyHost. Les identifiants sont indiqués sur place." }
  },
  {
    q: { en: "Something isn't working — what do I do?", fr: "Quelque chose ne fonctionne pas, que faire ?" },
    a: { en: "Contact us directly using the form below or by phone — we're available 7 days a week and respond quickly.", fr: "Contactez-nous directement via le formulaire ci-dessous ou par téléphone — nous sommes disponibles 7j/7 et répondons rapidement." }
  },
  {
    q: { en: "Can I bring extra guests?", fr: "Puis-je accueillir des invités supplémentaires ?" },
    a: { en: "Only guests listed on the booking may stay overnight. Let us know in advance if your group changes.", fr: "Seules les personnes indiquées sur la réservation peuvent dormir sur place. Prévenez-nous en avance si votre groupe change." }
  },
  {
    q: { en: "Are pets allowed?", fr: "Les animaux sont-ils acceptés ?" },
    a: { en: "It depends on the apartment. Check your booking confirmation or ask our team.", fr: "Cela dépend du logement. Vérifiez votre confirmation de réservation ou contactez notre équipe." }
  },
  {
    q: { en: "Is parking available?", fr: "Y a-t-il un parking disponible ?" },
    a: { en: "It depends on the apartment and the city. Ask our team for options near your address.", fr: "Cela dépend du logement et de la ville. Demandez à notre équipe les options près de votre adresse." }
  },
  {
    q: { en: "Do you speak my language?", fr: "Parlez-vous ma langue ?" },
    a: { en: "Our team communicates in English, French and Hebrew. Write to us — we'll make it work.", fr: "Notre équipe communique en anglais, français et hébreu. Écrivez-nous — on s'arrange." }
  }
];

/* =============== CONCIERGE SERVICES =============== */
/* Same 7 add-on services as the public concierge page — kept in sync manually. */
const CONCIERGE_SERVICES = [
  {
    id: 'transfer',
    icon: '<path d="M3 13l2-5a2 2 0 0 1 2-1h10a2 2 0 0 1 2 1l2 5"/><path d="M3 13h18v4a1 1 0 0 1-1 1h-1a1 1 0 0 1-1-1v-1H6v1a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1z"/><circle cx="7" cy="17" r="1"/><circle cx="17" cy="17" r="1"/>',
    en: { title: "Private Driver", body: "Airport run, a day trip, or just getting around — a private driver, on call." },
    fr: { title: "Chauffeur privé", body: "Aéroport, excursion ou simple trajet — un chauffeur privé, à la demande." }
  },
  {
    id: 'tours',
    icon: '<path d="M9 3 3 5v16l6-2 6 2 6-2V3l-6 2-6-2z"/><path d="M9 3v16"/><path d="M15 5v16"/>',
    en: { title: "Private Tours", body: "A private guide, handpicked for your interests — half-day or full day." },
    fr: { title: "Visites privées", body: "Un guide privé, choisi selon vos envies — demi-journée ou journée complète." }
  },
  {
    id: 'grocery',
    icon: '<path d="M6 8h12l-1 12H7z"/><path d="M9 8V6a3 3 0 0 1 6 0v2"/>',
    en: { title: "Grocery Stocking", body: "Fridge stocked before you arrive — coffee, fruit, bread, and your list." },
    fr: { title: "Courses avant arrivée", body: "Le frigo est plein à votre arrivée — café, fruits, pain, et votre liste." }
  },
  {
    id: 'babysitting',
    icon: '<path d="M12 21s-7-4.35-9.5-8.5C1 9 2 5 6 5c2 0 3.5 1.5 4 2.5.5-1 2-2.5 4-2.5 4 0 5 4 3.5 7.5C19 16.65 12 21 12 21z"/>',
    en: { title: "Babysitting", body: "A trusted, vetted sitter for an evening out or a bit of time to yourselves." },
    fr: { title: "Baby-sitting", body: "Une garde de confiance, pour une soirée ou un moment de répit." }
  },
  {
    id: 'sim',
    icon: '<path d="M2 8.5a16 16 0 0 1 20 0"/><path d="M5 12a11 11 0 0 1 14 0"/><path d="M8.5 15.5a6 6 0 0 1 7 0"/><circle cx="12" cy="19" r="1"/>',
    en: { title: "SIM & Connectivity", body: "Israeli SIM or eSIM with unlimited data, ready when you land." },
    fr: { title: "SIM & connectivité", body: "Carte SIM israélienne ou eSIM data illimitée, prête à votre arrivée." }
  },
  {
    id: 'chef',
    icon: '<path d="M7 3v6a2 2 0 0 0 4 0V3"/><path d="M9 9v12"/><path d="M17 3c-1.5 0-3 1.5-3 4s1.5 5 3 5 3-2 3-5-1.5-4-3-4z"/><path d="M17 12v9"/>',
    en: { title: "Private Chef", body: "The chef cooks in your kitchen — menu built around your dietary needs." },
    fr: { title: "Chef privé", body: "Le chef cuisine chez vous — menu adapté à vos préférences alimentaires." }
  },
  {
    id: 'wellness',
    icon: '<path d="M12 3c-4 0-8 3-8 9 0 4 3 8 8 9 5-1 8-5 8-9 0-6-4-9-8-9z"/><path d="M12 3v18"/>',
    en: { title: "Massage / Personal Trainer", body: "A massage therapist or personal trainer comes to your apartment, on your schedule." },
    fr: { title: "Massage / Coach sportif", body: "Un masseur ou un coach sportif se déplace chez vous, selon votre emploi du temps." }
  }
];

/* =============== STATE & RENDER =============== */
let lang = 'en';
let city = 'telaviv';

function renderI18n() {
  document.documentElement.lang = lang;
  document.querySelectorAll('[data-i18n]').forEach(el => {
    const key = el.getAttribute('data-i18n');
    if (I18N[lang][key]) el.textContent = I18N[lang][key];
  });
  document.querySelectorAll('.lang-btn').forEach(b =>
    b.classList.toggle('active', b.dataset.lang === lang));
}

function renderCitySelector() {
  const sel = document.getElementById('citySelector');
  sel.innerHTML = '';
  Object.keys(CITIES).forEach(key => {
    const btn = document.createElement('button');
    btn.className = 'city-pill' + (key === city ? ' active' : '');
    btn.setAttribute('role', 'tab');
    btn.textContent = CITIES[key].name[lang];
    btn.addEventListener('click', () => { city = key; renderCity(); renderCitySelector(); });
    sel.appendChild(btn);
  });
}

/* Weather — Open-Meteo, no API key needed (safe to call from a static page;
   a keyed provider like OpenWeatherMap would expose the key client-side). */
const weatherCache = {};

function displayWeather(w) {
  const el = document.getElementById('cityWeather');
  if (!el) return;
  el.innerHTML =
    '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="5"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/></svg>' +
    '<span class="weather-temp">' + w.temp + '°C</span>';
}

function renderCityWeather() {
  const el = document.getElementById('cityWeather');
  if (!el) return;
  if (weatherCache[city]) { displayWeather(weatherCache[city]); return; }
  const coords = CITY_COORDS[city];
  if (!coords) { el.innerHTML = ''; return; }
  el.innerHTML = '<span class="weather-loading">' + I18N[lang].weatherLoading + '</span>';
  fetch(`https://api.open-meteo.com/v1/forecast?latitude=${coords.lat}&longitude=${coords.lon}&current=temperature_2m`)
    .then(r => { if (!r.ok) throw new Error('weather request failed'); return r.json(); })
    .then(data => {
      const temp = data && data.current ? Math.round(data.current.temperature_2m) : null;
      if (temp === null) throw new Error('no temperature in response');
      weatherCache[city] = { temp };
      displayWeather(weatherCache[city]);
    })
    .catch(() => { el.innerHTML = '<span class="weather-error">' + I18N[lang].weatherError + '</span>'; });
}

/* Shabbat times — Hebcal API (free, no key). Candle-lighting / Havdalah times
   are a halachic calculation with real consequences if wrong, so this uses
   Hebcal's official calculation for the city's coordinates rather than a
   hand-rolled sunset formula. Cached per city; the underlying week only
   changes at Saturday nightfall, which is an acceptable edge case for a
   short-stay companion. */
const shabbatCache = {};

function displayShabbat(s) {
  const el = document.getElementById('cityShabbat');
  if (!el) return;
  el.innerHTML =
    '<span class="shabbat-row"><strong>' + I18N[lang].candleLighting + ':</strong> ' + s.candles + '</span>' +
    '<span class="shabbat-row"><strong>' + I18N[lang].havdalah + ':</strong> ' + s.havdalah + '</span>';
}

function renderCityShabbat() {
  const el = document.getElementById('cityShabbat');
  if (!el) return;
  if (shabbatCache[city]) { displayShabbat(shabbatCache[city]); return; }
  const coords = CITY_COORDS[city];
  if (!coords) { el.innerHTML = ''; return; }
  el.innerHTML = '<span class="shabbat-loading">' + I18N[lang].shabbatLoading + '</span>';
  fetch(`https://www.hebcal.com/shabbat?cfg=json&geo=pos&latitude=${coords.lat}&longitude=${coords.lon}&tzid=Asia/Jerusalem&M=on`)
    .then(r => { if (!r.ok) throw new Error('shabbat request failed'); return r.json(); })
    .then(data => {
      const items = data.items || [];
      const candlesItem = items.find(i => i.category === 'candles');
      const havdalahItem = items.find(i => i.category === 'havdalah');
      if (!candlesItem) throw new Error('no candle-lighting time in response');
      const fmt = iso => new Date(iso).toLocaleTimeString(lang === 'fr' ? 'fr-FR' : 'en-GB', { hour: '2-digit', minute: '2-digit' });
      shabbatCache[city] = {
        candles: fmt(candlesItem.date),
        havdalah: havdalahItem ? fmt(havdalahItem.date) : '—'
      };
      displayShabbat(shabbatCache[city]);
    })
    .catch(() => { el.innerHTML = '<span class="shabbat-error">' + I18N[lang].shabbatError + '</span>'; });
}

function renderCity() {
  const c = CITIES[city];
  document.getElementById('cityIntro').textContent = c.intro[lang];
  renderCityWeather();
  renderCityShabbat();

  const cfg = window.KEYHOST_CONFIG || {};
  const cityImg = cfg.images && cfg.images.cities ? cfg.images.cities[city] : '';
  const mediaEl = document.getElementById('cityMedia');
  if (cityImg) {
    mediaEl.style.background = `url("${cityImg}") center/cover no-repeat`;
    mediaEl.textContent = '';
  } else {
    mediaEl.style.background = '';
    mediaEl.textContent = c.name[lang] + ' — ' + I18N[lang].mediaPlaceholder;
  }

  const fill = (id, items) => {
    const ul = document.getElementById(id);
    ul.innerHTML = '';
    items.forEach(t => { const li = document.createElement('li'); li.textContent = t; ul.appendChild(li); });
  };
  fill('citySee', c.see[lang]);
  fill('cityEat', c.eat[lang]);
  fill('cityMove', c.move[lang]);
  document.getElementById('cityTip').textContent = c.tip[lang];

  const downloadLink = document.getElementById('cityGuideDownload');
  const dl = cfg.links && cfg.links.cityGuideDownloads && cfg.links.cityGuideDownloads[city]
    ? cfg.links.cityGuideDownloads[city][lang] : '';
  if (dl) {
    downloadLink.href = dl;
    downloadLink.style.display = 'inline-block';
  } else {
    downloadLink.style.display = 'none';
  }
}

function renderHero() {
  const cfg = window.KEYHOST_CONFIG || {};
  const heroEl = document.getElementById('heroMedia');
  if (cfg.images && cfg.images.hero) {
    heroEl.style.background = `url("${cfg.images.hero}") center/cover no-repeat`;
    heroEl.textContent = '';
  }
}

function renderFaq() {
  const list = document.getElementById('faqList');
  list.innerHTML = '';
  FAQS.forEach((item, i) => {
    const wrap = document.createElement('div');
    wrap.className = 'faq-item';
    wrap.innerHTML = `
      <button class="faq-question" aria-expanded="false">
        <span>${item.q[lang]}</span>
        <svg class="chevron" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"/></svg>
      </button>
      <div class="faq-answer"><p>${item.a[lang]}</p></div>
    `;
    const btn = wrap.querySelector('.faq-question');
    const answer = wrap.querySelector('.faq-answer');
    btn.addEventListener('click', () => {
      const isOpen = wrap.classList.toggle('open');
      btn.setAttribute('aria-expanded', String(isOpen));
      answer.style.maxHeight = isOpen ? answer.scrollHeight + 'px' : '0';
    });
    list.appendChild(wrap);
  });
}

/* Concierge — each card links to WhatsApp with a pre-filled, localized message
   naming the requested service. Re-run on language switch so the message text
   stays in the active language. */
function renderConcierge() {
  const grid = document.getElementById('conciergeGrid');
  if (!grid) return;
  const cfg = (window.KEYHOST_CONFIG || {}).contact || {};
  const waNumber = (cfg.phoneHref || '').replace('+', '');
  grid.innerHTML = '';
  CONCIERGE_SERVICES.forEach(svc => {
    const t = svc[lang];
    const message = I18N[lang].conciergeMsgPrefix + ' ' + t.title + '. ' + I18N[lang].conciergeMsgSuffix;
    const waLink = 'https://wa.me/' + waNumber + '?text=' + encodeURIComponent(message);
    const card = document.createElement('div');
    card.className = 'card';
    card.innerHTML = `
      <div class="card-icon"><svg viewBox="0 0 24 24">${svc.icon}</svg></div>
      <h3>${t.title}</h3>
      <p class="concierge-body">${t.body}</p>
      <a class="btn-whatsapp" href="${waLink}" target="_blank" rel="noopener">
        <svg viewBox="0 0 24 24"><path d="M21 11.5a8.5 8.5 0 0 1-12.4 7.5L3 20l1.1-5.4A8.5 8.5 0 1 1 21 11.5z"/></svg>
        ${I18N[lang].conciergeCta}
      </a>
    `;
    grid.appendChild(card);
  });
}

function renderContactInfo() {
  const c = (window.KEYHOST_CONFIG || {}).contact || {};
  document.querySelectorAll('[data-contact="phone"]').forEach(el => {
    el.textContent = c.phoneDisplay || el.textContent;
    if (el.tagName === 'A') el.href = 'tel:' + (c.phoneHref || '');
  });
  document.querySelectorAll('[data-contact="whatsapp"]').forEach(el => { el.href = c.whatsappHref || el.href; });
  document.querySelectorAll('[data-contact="email"]').forEach(el => {
    el.textContent = c.email || el.textContent;
    if (el.tagName === 'A') el.href = 'mailto:' + (c.email || '');
  });
}

document.querySelectorAll('.lang-btn').forEach(btn => {
  btn.addEventListener('click', () => {
    lang = btn.dataset.lang;
    renderI18n(); renderCitySelector(); renderCity(); renderFaq(); updateCurrencyDisplay(); renderConcierge(); updateInstallButtonText();
  });
});

/* Contact form — real submission via WordPress admin-ajax.php.
   Requires a WPCode PHP snippet on THIS WordPress install (stay.keyhost.online)
   registering the "keyhost_contact" ajax action and echoing
   window.KEYHOST_AJAX_URL / window.KEYHOST_NONCE before this script runs.
   See chat for the exact PHP snippet to paste in WPCode. */
document.getElementById('contactForm').addEventListener('submit', async (e) => {
  e.preventDefault();
  const form = e.target;
  const submitBtn = form.querySelector('.btn-submit');
  const errorEl = document.getElementById('formError');
  errorEl.style.display = 'none';
  submitBtn.disabled = true;

  const ajaxUrl = window.KEYHOST_AJAX_URL || '/wp-admin/admin-ajax.php';
  const nonce = window.KEYHOST_NONCE || '';

  const data = new FormData();
  data.append('action', 'keyhost_contact');
  data.append('nonce', nonce);
  data.append('source', form.querySelector('[name="source"]').value);
  // Honeypot — must stay empty. The PHP handler rejects (silently) any
  // submission where this is filled in.
  data.append('website', form.querySelector('#f-website').value);
  data.append('name', form.querySelector('#f-name').value);
  data.append('email', form.querySelector('#f-email').value);
  data.append('phone', form.querySelector('#f-phone').value);
  data.append('property', form.querySelector('#f-property').value);
  data.append('message', form.querySelector('#f-message').value);

  try {
    const res = await fetch(ajaxUrl, { method: 'POST', body: data });
    const json = await res.json();
    if (!res.ok || !json.success) throw new Error('Request failed');
    document.getElementById('contactFormFields').style.display = 'none';
    document.getElementById('formSuccess').classList.add('visible');
  } catch (err) {
    errorEl.style.display = 'block';
    submitBtn.disabled = false;
  }
});

/* Currency converter — live ECB rates via api.frankfurter.dev (free, no key).
   Falls back to the static rates in KEYHOST_CONFIG.currency if the fetch fails
   (offline, API down, etc). Rates are fetched once per page load and cached;
   swapping/typing recomputes instantly from the cached rates. */
let currencyRates = null; // { ILS:1, EUR:.., USD:.. } — units of that currency per 1 ILS
let currencyIsLive = false;

async function loadCurrencyRates() {
  try {
    const res = await fetch('https://api.frankfurter.dev/v1/latest?base=ILS&symbols=EUR,USD');
    if (!res.ok) throw new Error('rate fetch failed');
    const data = await res.json();
    if (!data.rates || !data.rates.EUR || !data.rates.USD) throw new Error('missing rates');
    currencyRates = { ILS: 1, EUR: data.rates.EUR, USD: data.rates.USD };
    currencyIsLive = true;
  } catch (e) {
    const cfg = (window.KEYHOST_CONFIG && window.KEYHOST_CONFIG.currency) || {};
    currencyRates = { ILS: 1, EUR: cfg.ilsToEur || 0.26, USD: cfg.ilsToUsd || 0.27 };
    currencyIsLive = false;
  }
}

function updateCurrencyDisplay() {
  const amountEl = document.getElementById('convAmount');
  const fromEl = document.getElementById('convFrom');
  const toEl = document.getElementById('convTo');
  const resultEl = document.getElementById('convResult');
  const metaEl = document.getElementById('convMeta');
  if (!amountEl || !currencyRates) return;
  const amount = parseFloat(amountEl.value) || 0;
  const from = fromEl.value;
  const to = toEl.value;
  const inIls = amount / currencyRates[from];
  const result = inIls * currencyRates[to];
  resultEl.textContent = '≈ ' + result.toFixed(2) + ' ' + to;
  if (metaEl) metaEl.textContent = currencyIsLive ? I18N[lang].currencyCaptionLive : I18N[lang].currencyCaptionOffline;
}

function renderCurrency() {
  const amountEl = document.getElementById('convAmount');
  const fromEl = document.getElementById('convFrom');
  const toEl = document.getElementById('convTo');
  const swapEl = document.getElementById('convSwap');
  if (!amountEl) return;

  amountEl.addEventListener('input', updateCurrencyDisplay);
  fromEl.addEventListener('change', updateCurrencyDisplay);
  toEl.addEventListener('change', updateCurrencyDisplay);
  swapEl.addEventListener('click', () => {
    const f = fromEl.value;
    fromEl.value = toEl.value;
    toEl.value = f;
    updateCurrencyDisplay();
  });

  updateCurrencyDisplay();
  loadCurrencyRates().then(updateCurrencyDisplay);
}

/* PWA head tags — injected via JS instead of relying on the static <head>
   markup at the top of this file. WordPress pastes this whole file's markup
   as PAGE CONTENT inside the theme's own already-open <body>, which means
   this file's own <!DOCTYPE>/<html>/<head> block is nested illegally inside
   an already-open <body>. Per the HTML parsing spec, browsers silently drop
   <head>-only elements (<link>, most <meta>) when that happens — no error,
   they just never make it into the real DOM. That's why "no manifest
   detected" showed up in DevTools even though the file "looked" correct.
   document.head always resolves to the page's real <head> (the theme's),
   regardless of this nesting problem, so building these tags in JS is the
   reliable fix. Guards against duplicates in case the static tags DID make
   it into the DOM (e.g. when this file is opened standalone for preview). */
function injectHeadTags() {
  const cfg = (window.KEYHOST_CONFIG && window.KEYHOST_CONFIG.pwa) || {};

  if (!document.querySelector('link[rel="manifest"]')) {
    const link = document.createElement('link');
    link.rel = 'manifest';
    link.href = '/manifest.json';
    document.head.appendChild(link);
  }

  if (!document.querySelector('link[href*="fonts.googleapis.com/css2"]')) {
    const preconnect1 = document.createElement('link');
    preconnect1.rel = 'preconnect';
    preconnect1.href = 'https://fonts.googleapis.com';
    document.head.appendChild(preconnect1);

    const preconnect2 = document.createElement('link');
    preconnect2.rel = 'preconnect';
    preconnect2.href = 'https://fonts.gstatic.com';
    preconnect2.crossOrigin = 'anonymous';
    document.head.appendChild(preconnect2);

    const fontSheet = document.createElement('link');
    fontSheet.rel = 'stylesheet';
    fontSheet.href = 'https://fonts.googleapis.com/css2?family=DM+Serif+Display&family=Manrope:wght@400;500;600;700;800&family=Inter:wght@400;500;600&display=swap';
    document.head.appendChild(fontSheet);
  }

  if (cfg.icon192) {
    let appleIcon = document.querySelector('link[rel="apple-touch-icon"]');
    if (!appleIcon) {
      appleIcon = document.createElement('link');
      appleIcon.rel = 'apple-touch-icon';
      document.head.appendChild(appleIcon);
    }
    appleIcon.href = cfg.icon192;
  }

  const metas = [
    ['theme-color', '#0D1B2A'],
    ['apple-mobile-web-app-capable', 'yes'],
    ['apple-mobile-web-app-status-bar-style', 'black-translucent'],
    ['apple-mobile-web-app-title', 'KeyHost']
  ];
  metas.forEach(([name, content]) => {
    if (!document.querySelector(`meta[name="${name}"]`)) {
      const meta = document.createElement('meta');
      meta.name = name;
      meta.content = content;
      document.head.appendChild(meta);
    }
  });
}

/* Install app button — shows a real, visible button instead of relying on
   Chrome's small address-bar icon. On iOS Safari, beforeinstallprompt never
   fires (Apple platform limitation), so we show a Share-menu hint instead,
   detected via the iOS-only `navigator.standalone` property. */
let deferredInstallPrompt = null;

function updateInstallButtonText() {
  const btn = document.getElementById('installAppBtn');
  if (!btn || btn.style.display === 'none') return;
  btn.textContent = btn.dataset.mode === 'ios' ? I18N[lang].addToHomeScreenBtn : I18N[lang].installAppBtn;
}

function initInstallButton() {
  const btn = document.getElementById('installAppBtn');
  if (!btn) return;

  const isStandalone = window.matchMedia('(display-mode: standalone)').matches || navigator.standalone === true;
  if (isStandalone) return; // already installed — nothing to offer

  const isIOS = typeof navigator.standalone !== 'undefined';

  if (isIOS) {
    btn.dataset.mode = 'ios';
    btn.style.display = 'inline-block';
    updateInstallButtonText();
    btn.addEventListener('click', () => alert(I18N[lang].addToHomeScreenHint));
    return;
  }

  btn.dataset.mode = 'android';
  window.addEventListener('beforeinstallprompt', (e) => {
    e.preventDefault();
    deferredInstallPrompt = e;
    btn.style.display = 'inline-block';
    updateInstallButtonText();
  });

  btn.addEventListener('click', async () => {
    if (!deferredInstallPrompt) return;
    deferredInstallPrompt.prompt();
    await deferredInstallPrompt.userChoice;
    deferredInstallPrompt = null;
    btn.style.display = 'none';
  });

  window.addEventListener('appinstalled', () => { btn.style.display = 'none'; });
}

/* Back to top */
function initBackToTop() {
  const btn = document.getElementById('backToTop');
  if (!btn) return;
  window.addEventListener('scroll', () => {
    btn.classList.toggle('visible', window.scrollY > 500);
  }, { passive: true });
  btn.addEventListener('click', () => window.scrollTo({ top: 0, behavior: 'smooth' }));
}

/* Register the service worker (see sw.js) — required for Chrome's install
   prompt to appear. Without a registered service worker with a fetch
   handler, Chrome will never show the "Add to Home Screen" / install UI,
   regardless of how correct the manifest.json and icons are. iOS Safari has
   no automatic prompt at all (Apple platform limitation) — there, "Add to
   Home Screen" is always a manual step via the Share menu. */
function registerServiceWorker() {
  if (!('serviceWorker' in navigator)) return;
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js').catch(() => {});
  });
}

injectHeadTags(); renderI18n(); renderCitySelector(); renderCity(); renderHero(); renderFaq(); renderContactInfo(); renderCurrency(); initBackToTop(); initInstallButton(); renderConcierge(); registerServiceWorker();
</script>
</body>
</html>