const { useState, useEffect, useRef, createContext, useContext } = React;

// Image sources — use base64 data URLs if injected (standalone build), else file paths (dev)
const IMG = (typeof window !== 'undefined' && window.__IMG) || {
  portada: 'https://images.unsplash.com/photo-1502672260266-1c1ef2d93688?auto=format&fit=crop&w=1400&q=75',
  sala: 'https://images.unsplash.com/photo-1586023492125-27b2c045efd7?auto=format&fit=crop&w=1200&q=75',
  recamara: 'https://images.unsplash.com/photo-1505693416388-ac5ce068fe85?auto=format&fit=crop&w=1200&q=75',
};

// ===================== Audio player (mp3 loop with fade) =====================
class AudioPlayer {
  constructor(src) {
    this.src = src;
    this.audio = null;
    this.targetGain = 0.55;
    this.fadeTimer = null;
    this.playing = false;
  }
  _init() {
    this.audio = new Audio(this.src);
    this.audio.loop = true;
    this.audio.preload = 'auto';
    this.audio.volume = 0;
    // Load eagerly
    try { this.audio.load(); } catch (e) {}
  }
  _fadeTo(target, ms) {
    if (!this.audio) return;
    if (this.fadeTimer) clearInterval(this.fadeTimer);
    const start = this.audio.volume;
    const steps = Math.max(1, Math.round(ms / 60));
    let i = 0;
    this.fadeTimer = setInterval(() => {
      i++;
      const t = i / steps;
      const v = start + (target - start) * t;
      try { this.audio.volume = Math.max(0, Math.min(1, v)); } catch (e) {}
      if (i >= steps) {
        clearInterval(this.fadeTimer);
        this.fadeTimer = null;
        if (target === 0) {
          try { this.audio.pause(); } catch (e) {}
        }
      }
    }, 60);
  }
  play() {
    if (!this.audio) this._init();
    this.playing = true;
    const p = this.audio.play();
    if (p && typeof p.catch === 'function') {
      p.catch(() => { /* autoplay blocked, will retry on next gesture */ });
    }
    this._fadeTo(this.targetGain, 2500);
  }
  stop() {
    this.playing = false;
    if (!this.audio) return;
    this._fadeTo(0, 1200);
  }
}
let _player = null;
const getPlayer = () => _player || (_player = new AudioPlayer('audio/piano.mp3'));
const getPiano = getPlayer; // alias for any old references

// Shared audio state so multiple toggles stay in sync.
// Default: music ON (so the icon shows 'playing' from the start). It
// actually starts the moment the user performs any tap — browsers require
// a user gesture before audio can begin.
const _audioSubs = new Set();
const audioState = {
  isOn: (() => {
    try { return sessionStorage.getItem('cm_audio') !== '0'; } catch (e) { return true; }
  })(),
};
const setAudioOn = (on) => {
  if (audioState.isOn === on) return;
  audioState.isOn = on;
  _audioSubs.forEach((fn) => fn(on));
};
const startAudio = () => {
  getPiano().play();
  setAudioOn(true);
  try { sessionStorage.setItem('cm_audio', '1'); } catch (e) {}
};
const stopAudio = () => {
  getPiano().stop();
  setAudioOn(false);
  try { sessionStorage.setItem('cm_audio', '0'); } catch (e) {}
};

function SoundToggle({ tone = "light" }) {
  const [on, setOn] = useState(audioState.isOn);
  useEffect(() => {
    _audioSubs.add(setOn);
    return () => { _audioSubs.delete(setOn); };
  }, []);
  const toggle = () => {
    if (audioState.isOn) stopAudio(); else startAudio();
  };
  const fg = on ? "#B85440" : (tone === "dark" ? "#F5EFE3" : "#6B6155");
  const bg = on ? "rgba(184,84,64,0.14)" : (tone === "dark" ? "rgba(245,239,227,0.18)" : "rgba(42,37,32,0.08)");
  return (
    <button
      onClick={toggle}
      aria-label={on ? "Pausar música" : "Activar música"}
      title={on ? "Pausar música" : "Activar música"}
      style={{
        width: 34, height: 34, border: "none", borderRadius: 100,
        background: bg, color: fg, cursor: "pointer",
        display: "inline-flex", alignItems: "center", justifyContent: "center",
        flexShrink: 0,
        transition: "all 0.25s",
      }}
    >
      {on ? (
        // Playing: music note with subtle bob animation
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
          <path d="M8 17 V 6 L 19 4 V 15">
            <animateTransform attributeName="transform" type="translate" dur="2.4s" repeatCount="indefinite" values="0 0; 0 -0.6; 0 0" />
          </path>
          <circle cx="6" cy="17" r="2.2" fill="currentColor" stroke="none" />
          <circle cx="17" cy="15" r="2.2" fill="currentColor" stroke="none" />
        </svg>
      ) : (
        // Muted: speaker icon with slash
        <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round">
          <path d="M8 17 V 6 L 19 4 V 15" />
          <circle cx="6" cy="17" r="2.2" fill="currentColor" stroke="none" />
          <circle cx="17" cy="15" r="2.2" fill="currentColor" stroke="none" />
          <line x1="3" y1="3" x2="21" y2="21" stroke="currentColor" strokeWidth="1.7" opacity="0.55" />
        </svg>
      )}
    </button>
  );
}


// ===================== i18n =====================
const LangCtx = createContext({ lang: "es", setLang: () => {} });
const useLang = () => useContext(LangCtx);
const tr = (val, lang) => (typeof val === "string" ? val : val?.[lang] ?? "");

// ===================== DATA =====================
const DATA = {
  property: {
    name: "Villa Coralina",
    tagline: {
      es: "Apartamento sereno · Carolina",
      en: "A serene apartment · Carolina",
    },
    host: "Sofía",
    welcome: {
      es: "¡Bienvenidos a Villa Coralina! Gracias por escoger mi hogar para su estadía en Puerto Rico. Estamos a minutos del aeropuerto y de las playas de Isla Verde, pero en una zona tranquila donde podrán descansar. Cualquier cosa que necesiten — antes, durante o después de la estadía — me escriben por WhatsApp y estoy pendiente.",
      en: "Welcome to Villa Coralina! Thank you for choosing my home for your stay in Puerto Rico. We're minutes from the airport and the Isla Verde beaches, but tucked into a quiet area where you can actually rest. Anything you need — before, during, or after your stay — message me on WhatsApp and I'll get back to you.",
    },
    wifi: { name: "VillaCoralina-Guest", password: "Bienvenido2026" },
    checkin: { es: "3:00 PM", en: "3:00 PM" },
    checkout: { es: "Antes de las 11:00 AM", en: "Before 11:00 AM" },
    access: {
      es: "El código de entrada se enviará por Airbnb antes de tu llegada. La caja de claves está al lado de la puerta del garaje.",
      en: "Your entry code will be sent through Airbnb before your arrival. The lockbox is next to the garage door.",
    },
    parking: {
      es: "Dentro de la marquesina o frente al portón de acceso. Incluido.",
      en: "Inside the carport or in front of the access gate. Included.",
    },
    whatsapp: "+1 787 555 0142",
    address: "Carolina, Puerto Rico",
    mapPin: "https://www.google.com/maps/search/?api=1&query=Carolina+Puerto+Rico",
    listingUrl: "https://www.airbnb.com",
    coords: "18.38° N, 65.96° W",
    rooms: { es: "2 habitaciones", en: "2 bedrooms" },
    capacity: 4,
  },

  rules: [
    { icon: "✓", es: "Mantener el hogar limpio durante la estadía", en: "Keep the home tidy during your stay" },
    { icon: "✕", es: "Prohibido fumar dentro del apartamento", en: "No smoking inside the apartment" },
    { icon: "✓", es: "Mascotas bienvenidas — con permiso previo", en: "Pets welcome — with prior permission" },
    { icon: "⏵", es: "Mascotas fuera de los muebles, por favor", en: "Pets off the furniture, please" },
    { icon: "✕", es: "No fiestas ni eventos", en: "No parties or events" },
    { icon: "⏵", es: "Silencio entre 10 PM y 8 AM", en: "Quiet hours 10 PM – 8 AM" },
  ],

  amenities: [
    { icon: "❄", es: "Aire acondicionado", en: "Air conditioning" },
    { icon: "◉", es: "Cocina completa", en: "Full kitchen" },
    { icon: "▣", es: "Microondas", en: "Microwave" },
    { icon: "☕", es: "Cafetera", en: "Coffee maker" },
    { icon: "▭", es: "Smart TV con Netflix", en: "Smart TV with Netflix" },
    { icon: "◍", es: "Balcón", en: "Balcony" },
    { icon: "⌂", es: "Parking incluido", en: "Parking included" },
    { icon: "❒", es: "2 habitaciones · hasta 4 personas", en: "2 bedrooms · sleeps 4" },
  ],

  food: [
    {
      name: "Kasalta",
      mapq: "Kasalta, Calle McLeary, Ocean Park, San Juan, PR",
      type: { es: "Panadería · café cubano", en: "Bakery · Cuban café" },
      dist: { es: "10 min", en: "10 min" },
      price: "$$",
      note: {
        es: "Una institución. Sándwich cubano y media noche; café puertorriqueño excelente. Obama almorzó aquí en 2011.",
        en: "An institution. Cuban sandwich and Medianoche; excellent Puerto Rican coffee. Obama lunched here in 2011.",
      },
    },
    {
      name: "El Pescador",
      mapq: "El Pescador Seafood Restaurant Piñones Loíza PR",
      type: { es: "Mariscos · Piñones", en: "Seafood · Piñones" },
      dist: { es: "12 min", en: "12 min" },
      price: "$$",
      note: {
        es: "Mofongo de chillo, pulpo guisado, vista al mar. Ir antes de las 7 PM.",
        en: "Red snapper mofongo, stewed octopus, ocean view. Go before 7 PM.",
      },
    },
    {
      name: "Ceviche House",
      mapq: "Ceviche House, Isla Verde, Carolina, PR",
      type: { es: "Peruano · Isla Verde", en: "Peruvian · Isla Verde" },
      dist: { es: "8 min", en: "8 min" },
      price: "$$",
      note: { es: "Reservar — siempre lleno. El ceviche mixto es lo mejor.", en: "Make a reservation — always packed. Mixed ceviche is the move." },
    },
    {
      name: "Metropol",
      mapq: "Metropol Restaurant, Isla Verde, Carolina, PR",
      type: { es: "Cubano clásico", en: "Cuban classic" },
      dist: { es: "10 min", en: "10 min" },
      price: "$$",
      note: { es: "Pollo relleno de mofongo, frijoles negros. Porciones generosas.", en: "Mofongo-stuffed chicken, black beans. Generous portions." },
    },
    {
      name: "Bebos Café",
      mapq: "Bebos Café, Isla Verde, Carolina, PR",
      type: { es: "Criollo típico", en: "Typical Puerto Rican" },
      dist: { es: "7 min", en: "7 min" },
      price: "$",
      note: { es: "Desayuno boricua de verdad: mallorca, tripleta, jugo de china.", en: "Real Puerto Rican breakfast: mallorca, tripleta, fresh orange juice." },
    },
    {
      name: "Kioskos de Piñones",
      mapq: "Kioskos de Piñones, Loíza, PR",
      type: { es: "Frituras frente al mar", en: "Fritters by the sea" },
      dist: { es: "15 min", en: "15 min" },
      price: "$",
      note: { es: "Alcapurrias, bacalaítos, empanadillas de jueyes. Llevar efectivo.", en: "Alcapurrias, bacalaítos, crab empanadillas. Bring cash." },
    },
  ],

  beaches: [
    {
      name: { es: "Playa Isla Verde", en: "Isla Verde Beach" },
      mapq: "Balneario de Carolina Isla Verde Beach, Carolina, PR",
      dist: { es: "10 min en carro", en: "10 min by car" },
      note: { es: "Arena blanca, aguas turquesa. Concesiones de sillas y kayak.", en: "White sand, turquoise water. Chair and kayak rentals available." },
    },
    {
      name: { es: "Balneario de Carolina", en: "Carolina Public Beach" },
      mapq: "Balneario de Carolina, Av. Los Gobernadores, Carolina, PR",
      dist: { es: "12 min", en: "12 min" },
      note: { es: "Más tranquila, palmeras y baños públicos. $5 parking.", en: "Quieter, palm trees and public restrooms. $5 parking." },
    },
    {
      name: { es: "Piñones", en: "Piñones" },
      mapq: "Piñones Beach, Loíza, PR",
      dist: { es: "15 min", en: "15 min" },
      note: { es: "Playa abierta y ruta de bicicleta entre cocoteros. Perfecta para atardecer.", en: "Open beach with a bike trail through palm groves. Perfect for sunset." },
    },
    {
      name: { es: "Ocean Park", en: "Ocean Park" },
      mapq: "Ocean Park Beach, San Juan, PR",
      dist: { es: "18 min", en: "18 min" },
      note: { es: "Ambiente local, viento bueno para kitesurf.", en: "Local vibe, great wind for kitesurfing." },
    },
  ],

  activities: [
    {
      name: { es: "Viejo San Juan", en: "Old San Juan" },
      mapq: "Old San Juan, Puerto Rico",
      dist: { es: "20 min en Uber", en: "20 min by Uber" },
      note: { es: "Calles adoquinadas, El Morro, Castillo San Cristóbal. Mejor de mañana o al atardecer.", en: "Cobblestone streets, El Morro, Castillo San Cristóbal. Best in morning or at sunset." },
    },
    {
      name: { es: "El Yunque (bosque tropical)", en: "El Yunque rainforest" },
      mapq: "El Yunque National Forest, Puerto Rico",
      dist: { es: "40 min", en: "40 min" },
      note: { es: "Único bosque tropical del sistema federal de EE.UU. Reservar con anticipación en recreation.gov.", en: "The only tropical rainforest in the U.S. Forest System. Book ahead at recreation.gov." },
    },
    {
      name: { es: "Bahía Bioluminiscente (Fajardo)", en: "Bioluminescent Bay (Fajardo)" },
      mapq: "Laguna Grande Bioluminescent Bay, Fajardo, PR",
      dist: { es: "1 hr", en: "1 hr" },
      note: { es: "Tour de kayak nocturno cuando hay luna nueva. Mágico.", en: "Nighttime kayak tour during new moon. Magical." },
    },
    {
      name: { es: "Ruta de bicicleta de Piñones", en: "Piñones bike trail" },
      mapq: "Paseo Piñones boardwalk, Loíza, PR",
      dist: { es: "15 min", en: "15 min" },
      note: { es: "11 km de boardwalk entre el mar y el manglar. Alquiler en COPI Bikes ($15/día).", en: "11 km boardwalk between sea and mangroves. Rent at COPI Bikes ($15/day)." },
    },
    {
      name: { es: "Casa Bacardí (Cataño)", en: "Casa Bacardí (Cataño)" },
      mapq: "Casa Bacardi, Cataño, PR",
      dist: { es: "35 min", en: "35 min" },
      note: { es: "Tour de la destilería con cata. Llegar en ferry desde San Juan es la mejor forma.", en: "Distillery tour with tasting. Taking the ferry from San Juan is the best way to arrive." },
    },
    {
      name: { es: "Catamarán a Icacos / Palomino", en: "Catamaran to Icacos / Palomino" },
      mapq: "Puerto del Rey Marina, Fajardo, PR",
      dist: { es: "1 hr al puerto", en: "1 hr to port" },
      note: { es: "Día de snorkel en cayos desiertos. Operadores: East Island, Erin Go Bragh.", en: "Day of snorkeling at deserted cays. Operators: East Island, Erin Go Bragh." },
    },
  ],

  essentials: [
    { name: "Supermercado Econo", mapq: "Econo Supermarket Carolina PR", dist: { es: "5 min", en: "5 min" }, note: { es: "Lo más cercano y completo. 7 AM – 10 PM.", en: "Closest full supermarket. 7 AM – 10 PM." } },
    { name: "Walgreens", mapq: "Walgreens Carolina PR", dist: { es: "6 min", en: "6 min" }, note: { es: "Farmacia 24 horas para emergencias.", en: "24-hour pharmacy for emergencies." } },
    { name: "Plaza Carolina", mapq: "Plaza Carolina Mall, Carolina, PR", dist: { es: "10 min", en: "10 min" }, note: { es: "Centro comercial: cines, food court, tiendas.", en: "Mall: movies, food court, shops." } },
    { name: "Banco Popular (ATM)", mapq: "Banco Popular Carolina PR", dist: { es: "5 min", en: "5 min" }, note: { es: "Cajero automático 24 hrs dentro del Econo.", en: "24-hour ATM inside the Econo." } },
  ],

  nightlife: [
    {
      name: { es: "La Placita de Santurce", en: "La Placita de Santurce" },
      dist: { es: "20 min", en: "20 min" },
      mapq: "La Placita de Santurce, San Juan, Puerto Rico",
      note: { es: "El epicentro de la noche en San Juan. De día plaza de mercado, de noche bares y música por todas las calles. Muy popular los fines de semana.", en: "The heart of San Juan nightlife. A market square by day, bars and music spill into the streets at night. Very popular on weekends." },
    },
    {
      name: { es: "Calle Cerra, Santurce", en: "Calle Cerra, Santurce" },
      dist: { es: "20 min", en: "20 min" },
      mapq: "Calle Cerra, Santurce, San Juan, Puerto Rico",
      note: { es: "Zona de arte urbano, cervecerías artesanales y ambiente alternativo. Murales increíbles.", en: "Street-art district with craft breweries and an alternative vibe. Incredible murals." },
    },
    {
      name: { es: "Isla Verde", en: "Isla Verde" },
      dist: { es: "10 min", en: "10 min" },
      mapq: "Isla Verde, Carolina, Puerto Rico",
      note: { es: "Bares de hotel, lounges frente al mar y casinos. Lo más cercano al apartamento.", en: "Hotel bars, beachfront lounges, and casinos. The closest option to the apartment." },
    },
    {
      name: { es: "Brava (Hotel El San Juan)", en: "Brava (El San Juan Hotel)" },
      dist: { es: "10 min", en: "10 min" },
      mapq: "Brava Club El San Juan Hotel, Isla Verde, Carolina, Puerto Rico",
      note: { es: "Club nocturno elegante dentro del hotel El San Juan, en Santurce/Isla Verde. Código de vestimenta — vístanse bien.", en: "Upscale nightclub inside El San Juan Hotel. Dress code applies — dress sharp." },
    },
    {
      name: { es: "Viejo San Juan", en: "Old San Juan" },
      dist: { es: "20 min", en: "20 min" },
      mapq: "Calle San Sebastián, Old San Juan, Puerto Rico",
      note: { es: "Bares, música en vivo y ambiente turístico entre calles adoquinadas. La Calle San Sebastián es la más animada.", en: "Bars, live music, and a lively tourist scene on cobblestone streets. Calle San Sebastián is the liveliest." },
    },
  ],

  transport: [
    { name: "Uber / Lyft", note: { es: "Disponibles 24/7. Al aeropuerto SJU: ~$10. Al Viejo San Juan: ~$18.", en: "Available 24/7. To SJU airport: ~$10. To Old San Juan: ~$18." } },
    { name: { es: "Aeropuerto SJU", en: "SJU Airport" }, note: { es: "10 minutos en carro. Vuelos domésticos e internacionales.", en: "10 min by car. Domestic and international flights." } },
    { name: { es: "Alquiler de carro", en: "Car rental" }, note: { es: "Recomendado si planean visitar El Yunque o Fajardo. Hertz, Enterprise y Charlie Car Rental tienen oficinas en el aeropuerto.", en: "Recommended if visiting El Yunque or Fajardo. Hertz, Enterprise, and Charlie Car Rental are at the airport." } },
    { name: { es: "Alquiler de bicicleta", en: "Bike rental" }, note: { es: "COPI Bikes en Piñones, $15/día. Ideal para la boardwalk.", en: "COPI Bikes in Piñones, $15/day. Ideal for the boardwalk." } },
  ],

  tips: [
    {
      es: "Evita manejar entre 4 y 6 PM — el tráfico de Puerto Rico es real, especialmente hacia el aeropuerto.",
      en: "Avoid driving 4–6 PM — Puerto Rico traffic is real, especially toward the airport.",
    },
    {
      es: "Para el Viejo San Juan, usa Uber. Estacionarse es difícil y caro; el viaje es corto.",
      en: "For Old San Juan, use Uber. Parking is hard and expensive; the ride is short.",
    },
    {
      es: "El agua del grifo es potable, pero muchos prefieren agua embotellada. Hay galón de agua en la cocina.",
      en: "Tap water is drinkable, but most prefer bottled. There's a jug of water in the kitchen.",
    },
    {
      es: "Propina en restaurantes: 15–20 %. En los kioskos de Piñones no se espera.",
      en: "Tipping in restaurants: 15–20%. At Piñones kiosks it's not expected.",
    },
    {
      es: "Trae efectivo para kioskos, food trucks y propinas. Casi todo lo demás acepta tarjeta.",
      en: "Bring cash for kiosks, food trucks, and tips. Almost everything else takes cards.",
    },
    {
      es: "El mejor atardecer del área se ve desde la boardwalk de Piñones o el Paseo La Princesa en el Viejo San Juan.",
      en: "Best sunset in the area: Piñones boardwalk or Paseo La Princesa in Old San Juan.",
    },
    {
      es: "Si llueve un rato, espera 20 minutos. Aquí el sol vuelve rápido.",
      en: "If it rains, wait 20 minutes. The sun comes back fast here.",
    },
  ],

  emergency: [
    { label: { es: "Emergencias generales", en: "General emergencies" }, number: "911" },
    { label: { es: "Anfitrión · Sofía", en: "Host · Sofía" }, number: "+1 787 555 0142" },
    { label: { es: "Policía Carolina", en: "Carolina Police" }, number: "787 757 2020" },
    { label: { es: "Hospital UPR Carolina", en: "UPR Carolina Hospital" }, number: "787 757 1800" },
    { label: { es: "Aeropuerto SJU", en: "SJU Airport" }, number: "787 289 7240" },
  ],
};

// ===================== Labels (UI strings) =====================
const L = {
  guideKicker: { es: "GUÍA DEL HUÉSPED · CAROLINA, PR", en: "GUEST GUIDE · CAROLINA, PR" },
  coverLead: {
    es: "Todo lo que necesitas saber sobre tu estadía y el área. Léelo despacio — está hecho para ti.",
    en: "Everything you need to know about your stay and the area. Take your time — it's made for you.",
  },
  openGuide: { es: "Abrir la guía", en: "Open the guide" },
  edition: { es: "EDICIÓN 2026", en: "2026 EDITION" },
  vol: { es: "VOL. 01", en: "VOL. 01" },
  back: { es: "PORTADA", en: "COVER" },

  // Sections
  sec_inicio: { es: "Inicio", en: "Welcome" },
  sec_apto: { es: "Apartamento", en: "Apartment" },
  sec_area: { es: "El Área", en: "The Area" },
  sec_comer: { es: "Comer", en: "Eat" },
  sec_playas: { es: "Playas", en: "Beaches" },
  sec_hacer: { es: "Qué Hacer", en: "Do" },
  sec_noche: { es: "Vida Nocturna", en: "Nightlife" },
  sec_transporte: { es: "Transporte", en: "Transport" },
  sec_tips: { es: "Tips", en: "Tips" },
  sec_contacto: { es: "Contacto", en: "Contact" },

  k_bienvenida: { es: "Bienvenida", en: "Welcome" },
  k_tuHogar: { es: "Tu hogar", en: "Your home" },
  k_barrio: { es: "El barrio", en: "The neighborhood" },
  k_sabores: { es: "Sabores", en: "Flavors" },
  k_marCaribe: { es: "Mar Caribe", en: "Caribbean Sea" },
  k_aventura: { es: "Aventura", en: "Adventure" },
  k_noche: { es: "Después del atardecer", en: "After dark" },
  k_moverse: { es: "Moverse", en: "Getting around" },
  k_local: { es: "De local", en: "Local know-how" },
  k_aqui: { es: "Estamos aquí", en: "We're here" },

  h_inicio: { es: "¡Hola, qué bueno verlos!", en: "Hello — glad you're here!" },
  h_apto: { es: "El apartamento", en: "The apartment" },
  h_area: { es: "Carolina y alrededores", en: "Carolina and around" },
  h_comer: { es: "Dónde comer", en: "Where to eat" },
  h_playas: { es: "Las playas", en: "The beaches" },
  h_hacer: { es: "Qué hacer", en: "What to do" },
  h_noche: { es: "Salir de noche", en: "A night out" },
  h_transporte: { es: "Cómo llegar a todo", en: "Getting to everything" },
  h_tips: { es: "Tips de la casa", en: "House tips" },
  h_contacto: { es: "Cualquier cosa, escribe", en: "Anything you need, write" },

  nocheLead: {
    es: "Las mejores zonas para salir, todas seguras, turísticas y accesibles desde el apartamento. Toca cualquiera para abrir el mapa.",
    en: "The best areas for a night out — all safe, touristy, and easy to reach from the apartment. Tap any to open the map.",
  },

  datosRapidos: { es: "DATOS RÁPIDOS", en: "QUICK FACTS" },
  checkin: { es: "Check-in", en: "Check-in" },
  checkout: { es: "Check-out", en: "Check-out" },
  acceso: { es: "Acceso", en: "Access" },
  parking: { es: "Parking", en: "Parking" },
  direccion: { es: "Dirección", en: "Address" },
  coordenadas: { es: "Coordenadas", en: "Coordinates" },

  wifi: { es: "WIFI", en: "WIFI" },
  copy: { es: "Copiar contraseña", en: "Copy password" },
  copied: { es: "✓ Copiado", en: "✓ Copied" },

  reglas: { es: "Reglas de la casa", en: "House rules" },
  amenidades: { es: "Lo que tienes", en: "What you have" },

  esencial: { es: "Lo esencial cerca", en: "Essentials nearby" },
  areaIntro: {
    es: "Estás en Carolina — una zona residencial tranquila, a minutos del aeropuerto y de las mejores playas urbanas de la isla. Todo importante queda a 10-20 minutos.",
    en: "You're in Carolina — a quiet residential area minutes from the airport and the island's best urban beaches. Everything important is 10-20 minutes away.",
  },
  comerLead: {
    es: "Mis lugares favoritos, ordenados por distancia al apartamento.",
    en: "My favorite spots, sorted by distance from the apartment.",
  },
  playasLead: {
    es: "Trae bloqueador, agua y una toalla. El sol caribeño no perdona.",
    en: "Bring sunscreen, water, and a towel. The Caribbean sun doesn't joke around.",
  },
  hacerLead: {
    es: "Si solo tienes unos días, escoge dos — y guarda tiempo para descansar también.",
    en: "If you only have a few days, pick two — and save time to just rest too.",
  },
  distancias: { es: "DISTANCIAS DESDE EL APARTAMENTO", en: "DISTANCES FROM THE APARTMENT" },
  whatsappCta: { es: "Escríbeme por WhatsApp", en: "Message me on WhatsApp" },
  whatsappSub: { es: "MENSAJE DIRECTO", en: "DIRECT MESSAGE" },
  numImportantes: { es: "Números importantes", en: "Important numbers" },
  gracias: { es: "Gracias por venir.", en: "Thank you for coming." },
  reseña: { es: "Si todo salió bien, una reseña ayuda mucho.", en: "If everything went well, a review means a lot." },
  porConfigurar: { es: "(por configurar)", en: "(coming soon)" },
};

const t = (key, lang) => tr(L[key], lang) || key;

const SECTIONS = [
  { id: "inicio", labelKey: "sec_inicio" },
  { id: "apto", labelKey: "sec_apto" },
  { id: "area", labelKey: "sec_area" },
  { id: "comer", labelKey: "sec_comer" },
  { id: "playas", labelKey: "sec_playas" },
  { id: "hacer", labelKey: "sec_hacer" },
  { id: "noche", labelKey: "sec_noche" },
  { id: "transporte", labelKey: "sec_transporte" },
  { id: "tips", labelKey: "sec_tips" },
  { id: "contacto", labelKey: "sec_contacto" },
];

// ===================== Shared UI =====================
function Photo({ src, alt, h = 220 }) {
  return (
    <div style={{ height: h, overflow: "hidden", borderRadius: 4, background: "#E8DDC4" }}>
      <img src={src} alt={alt} style={{ width: "100%", height: "100%", objectFit: "cover", display: "block" }} />
    </div>
  );
}

// Build a Google Maps search URL from a place name or address
function mapsUrl(query) {
  return "https://www.google.com/maps/search/?api=1&query=" + encodeURIComponent(query);
}

// Small inline "open in maps" pin link
function MapPin({ query, url, label }) {
  const { lang } = useLang();
  const href = url || mapsUrl(query);
  return (
    <a
      href={href}
      target="_blank"
      rel="noopener noreferrer"
      onClick={(e) => e.stopPropagation()}
      style={{
        display: "inline-flex",
        alignItems: "center",
        gap: 5,
        fontFamily: "'JetBrains Mono', monospace",
        fontSize: 10,
        letterSpacing: "0.08em",
        color: "#B85440",
        textDecoration: "none",
        whiteSpace: "nowrap",
      }}
    >
      <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
        <path d="M21 10c0 7-9 12-9 12s-9-5-9-12a9 9 0 0 1 18 0Z" />
        <circle cx="12" cy="10" r="3" />
      </svg>
      {label || (lang === "es" ? "Mapa" : "Map")}
    </a>
  );
}

function SectionHeader({ num, kicker, title }) {
  return (
    <div style={{ marginBottom: 28 }}>
      <div
        style={{
          display: "flex",
          alignItems: "center",
          gap: 10,
          fontFamily: "'JetBrains Mono', monospace",
          fontSize: 10,
          letterSpacing: "0.18em",
          textTransform: "uppercase",
          color: "#9C8A6E",
          marginBottom: 14,
        }}
      >
        <span>{num}</span>
        <span style={{ flex: 1, height: 1, background: "#D6C9AE" }}></span>
        <span>{kicker}</span>
      </div>
      <h2
        style={{
          fontFamily: "'DM Serif Display', serif",
          fontSize: 36,
          lineHeight: 1.05,
          color: "#2A2520",
          margin: 0,
          letterSpacing: "-0.01em",
        }}
      >
        {title}
      </h2>
    </div>
  );
}

function KV({ label, value, mono, last }) {
  return (
    <div
      style={{
        display: "flex",
        justifyContent: "space-between",
        alignItems: "flex-start",
        gap: 16,
        padding: "10px 0",
        borderBottom: last ? "none" : "1px dashed #E5DCC9",
      }}
    >
      <span style={{ fontSize: 13, color: "#6B6155", flexShrink: 0 }}>{label}</span>
      <span
        style={{
          fontSize: 13,
          color: "#2A2520",
          fontWeight: 600,
          textAlign: "right",
          fontFamily: mono ? "'JetBrains Mono', monospace" : "'Manrope', sans-serif",
          letterSpacing: mono ? "0.08em" : 0,
        }}
      >
        {value}
      </span>
    </div>
  );
}

function Row({ title, dist, note, price, last, mapQuery }) {
  return (
    <div style={{ padding: "16px 0", borderBottom: last ? "none" : "1px solid #E5DCC9" }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", gap: 12, marginBottom: 6 }}>
        <div style={{ fontWeight: 600, fontSize: 15, color: "#2A2520" }}>{title}</div>
        <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, color: "#9C8A6E", letterSpacing: "0.1em", whiteSpace: "nowrap" }}>
          {price && <span style={{ marginRight: 8, color: "#2F5D4F" }}>{price}</span>}
          {dist}
        </div>
      </div>
      <div style={{ fontSize: 13, color: "#6B6155", lineHeight: 1.55, marginBottom: mapQuery ? 8 : 0 }}>{note}</div>
      {mapQuery && <MapPin query={mapQuery} />}
    </div>
  );
}

function Divider() {
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 12, margin: "48px 0", color: "#D6C9AE" }}>
      <span style={{ flex: 1, height: 1, background: "#D6C9AE" }}></span>
      <span style={{ fontFamily: "'DM Serif Display', serif", fontSize: 18, color: "#B85440" }}>✦</span>
      <span style={{ flex: 1, height: 1, background: "#D6C9AE" }}></span>
    </div>
  );
}

function LangPill() {
  const { lang, setLang } = useLang();
  return (
    <div
      style={{
        display: "inline-flex",
        background: "rgba(42,37,32,0.08)",
        borderRadius: 100,
        padding: 3,
      }}
    >
      {["es", "en"].map((l) => (
        <button
          key={l}
          onClick={() => setLang(l)}
          style={{
            border: "none",
            background: lang === l ? "#2A2520" : "transparent",
            color: lang === l ? "#F5EFE3" : "#6B6155",
            fontFamily: "'JetBrains Mono', monospace",
            fontSize: 10,
            letterSpacing: "0.15em",
            padding: "6px 10px",
            borderRadius: 100,
            cursor: "pointer",
            fontWeight: 600,
          }}
        >
          {l.toUpperCase()}
        </button>
      ))}
    </div>
  );
}

// ===================== Sections =====================
function Cover({ onEnter }) {
  const { lang } = useLang();
  return (
    <section style={{ padding: 0, position: "relative", height: "100%", display: "flex", flexDirection: "column" }}>
      <div style={{ position: "relative", flex: "0 0 auto" }}>
        <Photo src={IMG.portada} alt="Villa Coralina" h={420} />
        <div
          style={{
            position: "absolute",
            inset: 0,
            background: "linear-gradient(180deg, transparent 50%, rgba(42,37,32,0.35) 100%)",
            pointerEvents: "none",
          }}
        ></div>
        <div style={{ position: "absolute", top: 18, right: 18, display: "flex", alignItems: "center", gap: 8 }}>
          <SoundToggle tone="dark" />
          <LangPill />
        </div>
      </div>

      <div style={{ padding: "28px 24px 24px", flex: 1, display: "flex", flexDirection: "column", background: "#F5EFE3" }}>
        <div
          style={{
            fontFamily: "'JetBrains Mono', monospace",
            fontSize: 10,
            letterSpacing: "0.2em",
            color: "#B85440",
            marginBottom: 18,
          }}
        >
          {t("guideKicker", lang)}
        </div>
        <h1
          style={{
            fontFamily: "'DM Serif Display', serif",
            fontSize: 56,
            lineHeight: 0.93,
            color: "#2A2520",
            margin: "0 0 14px",
            letterSpacing: "-0.025em",
          }}
        >
          Villa<br/>Coralina
        </h1>
        <p style={{ fontSize: 14, color: "#6B6155", margin: "0 0 28px", lineHeight: 1.5 }}>
          {t("coverLead", lang)}
        </p>
        <div style={{ marginTop: "auto" }}>
          <button
            onClick={onEnter}
            style={{
              width: "100%",
              padding: "18px",
              background: "#2A2520",
              color: "#F5EFE3",
              border: "none",
              borderRadius: 2,
              fontFamily: "'Manrope', sans-serif",
              fontWeight: 600,
              fontSize: 13,
              letterSpacing: "0.15em",
              textTransform: "uppercase",
              cursor: "pointer",
            }}
          >
            {t("openGuide", lang)} →
          </button>
          <div
            style={{
              marginTop: 16,
              display: "flex",
              justifyContent: "space-between",
              fontFamily: "'JetBrains Mono', monospace",
              fontSize: 10,
              letterSpacing: "0.1em",
              color: "#9C8A6E",
            }}
          >
            <span>{t("vol", lang)}</span>
            <span>{t("edition", lang)}</span>
            <span>SOFÍA</span>
          </div>
        </div>
      </div>
    </section>
  );
}

function Inicio() {
  const { lang } = useLang();
  return (
    <section>
      <SectionHeader num="01" kicker={t("k_bienvenida", lang)} title={t("h_inicio", lang)} />
      <p style={{ fontSize: 16, lineHeight: 1.65, color: "#3D362D", marginBottom: 28 }}>
        {tr(DATA.property.welcome, lang)}
      </p>
      <div
        style={{
          background: "#FBF7EE",
          border: "1px solid #E5DCC9",
          padding: "20px",
          marginBottom: 24,
        }}
      >
        <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: "0.15em", color: "#9C8A6E", marginBottom: 12 }}>
          {t("datosRapidos", lang)}
        </div>
        <KV label={t("checkin", lang)} value={tr(DATA.property.checkin, lang)} />
        <KV label={t("checkout", lang)} value={tr(DATA.property.checkout, lang)} />
        <KV label={t("acceso", lang)} value={tr(DATA.property.access, lang)} />
        <KV label={t("parking", lang)} value={tr(DATA.property.parking, lang)} />
        <div style={{ padding: "10px 0", borderBottom: "1px dashed #E5DCC9" }}>
          <div style={{ fontSize: 13, color: "#6B6155", marginBottom: 6 }}>{t("direccion", lang)}</div>
          <a
            href={DATA.property.mapPin}
            target="_blank"
            rel="noopener noreferrer"
            style={{ fontSize: 14, color: "#2A2520", fontWeight: 600, textDecoration: "none", lineHeight: 1.45, display: "block" }}
          >
            {DATA.property.address}
          </a>
          <div style={{ marginTop: 8 }}>
            <MapPin url={DATA.property.mapPin} label={lang === "es" ? "Abrir ubicación exacta" : "Open exact location"} />
          </div>
        </div>
        <KV label={t("coordenadas", lang)} value={DATA.property.coords} mono last />
      </div>
      <a
        href={DATA.property.mapPin}
        target="_blank"
        rel="noopener noreferrer"
        style={{
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          gap: 10,
          background: "#2F5D4F",
          color: "#F5EFE3",
          textDecoration: "none",
          padding: "16px 20px",
          marginBottom: 24,
          fontFamily: "'Manrope', sans-serif",
          fontWeight: 600,
          fontSize: 13,
          letterSpacing: "0.1em",
          textTransform: "uppercase",
        }}
      >
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M21 10c0 7-9 12-9 12s-9-5-9-12a9 9 0 0 1 18 0Z" />
          <circle cx="12" cy="10" r="3" />
        </svg>
        {lang === "es" ? "Cómo llegar" : "Get directions"}
      </a>
      <p style={{ fontStyle: "italic", color: "#6B6155", fontSize: 14, textAlign: "center", margin: "8px 0 0", fontFamily: "'DM Serif Display', serif" }}>
        — {DATA.property.host}
      </p>
    </section>
  );
}

function Apartamento() {
  const { lang } = useLang();
  const [copied, setCopied] = useState(false);
  const wifiReady = !DATA.property.wifi.password.startsWith("(");
  const copyWifi = () => {
    if (!wifiReady) return;
    navigator.clipboard?.writeText(DATA.property.wifi.password);
    setCopied(true);
    setTimeout(() => setCopied(false), 1800);
  };
  return (
    <section>
      <SectionHeader num="02" kicker={t("k_tuHogar", lang)} title={t("h_apto", lang)} />
      <Photo src={IMG.sala} alt="Sala" h={220} />
      <div style={{ height: 24 }} />

      {/* WiFi */}
      <div style={{ background: "#2A2520", color: "#F5EFE3", padding: "22px 20px", marginBottom: 28, borderRadius: 2 }}>
        <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: "0.2em", color: "#B85440", marginBottom: 14 }}>
          {t("wifi", lang)}
        </div>
        <div style={{ fontFamily: "'DM Serif Display', serif", fontSize: 22, marginBottom: 4 }}>
          {DATA.property.wifi.name}
        </div>
        <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 15, color: "#E8DDC4", marginBottom: 16, letterSpacing: "0.05em" }}>
          {DATA.property.wifi.password}
        </div>
        <button
          onClick={copyWifi}
          disabled={!wifiReady}
          style={{
            background: copied ? "#2F5D4F" : "transparent",
            color: "#F5EFE3",
            border: "1px solid #F5EFE3",
            padding: "10px 16px",
            fontSize: 11,
            letterSpacing: "0.15em",
            textTransform: "uppercase",
            fontFamily: "'Manrope', sans-serif",
            fontWeight: 600,
            cursor: wifiReady ? "pointer" : "not-allowed",
            opacity: wifiReady ? 1 : 0.5,
            transition: "all 0.2s",
            width: "100%",
          }}
        >
          {copied ? t("copied", lang) : t("copy", lang)}
        </button>
      </div>

      {/* Amenities */}
      <h3 style={{ fontFamily: "'DM Serif Display', serif", fontSize: 22, color: "#2A2520", margin: "0 0 16px" }}>
        {t("amenidades", lang)}
      </h3>
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "12px 18px", marginBottom: 32 }}>
        {DATA.amenities.map((a, i) => (
          <div key={i} style={{ display: "flex", alignItems: "center", gap: 10, fontSize: 13, color: "#3D362D" }}>
            <span style={{ color: "#B85440", fontSize: 16, width: 18, textAlign: "center" }}>{a.icon}</span>
            <span>{tr(a, lang)}</span>
          </div>
        ))}
      </div>

      {/* Rules */}
      <h3 style={{ fontFamily: "'DM Serif Display', serif", fontSize: 22, color: "#2A2520", margin: "0 0 14px" }}>
        {t("reglas", lang)}
      </h3>
      <div>
        {DATA.rules.map((r, i) => (
          <div key={i} style={{ display: "flex", gap: 14, padding: "12px 0", borderBottom: i === DATA.rules.length - 1 ? "none" : "1px solid #E5DCC9" }}>
            <span style={{ width: 20, color: r.icon === "✕" ? "#B85440" : r.icon === "✓" ? "#2F5D4F" : "#9C8A6E", fontWeight: 700 }}>{r.icon}</span>
            <span style={{ fontSize: 14, color: "#3D362D", lineHeight: 1.5 }}>{tr(r, lang)}</span>
          </div>
        ))}
      </div>
    </section>
  );
}

function Area() {
  const { lang } = useLang();
  return (
    <section>
      <SectionHeader num="03" kicker={t("k_barrio", lang)} title={t("h_area", lang)} />
      <Photo src={IMG.recamara} alt="Habitación" h={200} />
      <p style={{ fontSize: 15, lineHeight: 1.65, color: "#3D362D", margin: "20px 0 28px" }}>
        {t("areaIntro", lang)}
      </p>

      <h3 style={{ fontFamily: "'DM Serif Display', serif", fontSize: 22, color: "#2A2520", margin: "0 0 14px" }}>
        {t("esencial", lang)}
      </h3>
      {DATA.essentials.map((e, i) => (
        <Row key={i} title={tr(e.name, lang)} dist={tr(e.dist, lang)} note={tr(e.note, lang)} last={i === DATA.essentials.length - 1} mapQuery={e.mapq || (tr(e.name, lang) + " Carolina Puerto Rico")} />
      ))}
    </section>
  );
}

function Comer() {
  const { lang } = useLang();
  return (
    <section>
      <SectionHeader num="04" kicker={t("k_sabores", lang)} title={t("h_comer", lang)} />
      <p style={{ fontSize: 15, lineHeight: 1.65, color: "#3D362D", marginBottom: 24, fontStyle: "italic", fontFamily: "'DM Serif Display', serif" }}>
        {t("comerLead", lang)}
      </p>
      {DATA.food.map((f, i) => (
        <Row
          key={i}
          title={f.name}
          dist={tr(f.dist, lang)}
          note={`${tr(f.type, lang)} — ${tr(f.note, lang)}`}
          price={f.price}
          last={i === DATA.food.length - 1}
          mapQuery={f.mapq || (f.name + " Puerto Rico")}
        />
      ))}
    </section>
  );
}

function Playas() {
  const { lang } = useLang();
  return (
    <section>
      <SectionHeader num="05" kicker={t("k_marCaribe", lang)} title={t("h_playas", lang)} />
      <p style={{ fontSize: 14, color: "#6B6155", margin: "0 0 24px", fontStyle: "italic" }}>
        {t("playasLead", lang)}
      </p>
      {DATA.beaches.map((b, i) => (
        <Row key={i} title={tr(b.name, lang)} dist={tr(b.dist, lang)} note={tr(b.note, lang)} last={i === DATA.beaches.length - 1} mapQuery={b.mapq || (tr(b.name, lang) + " Puerto Rico")} />
      ))}
    </section>
  );
}

function Hacer() {
  const { lang } = useLang();
  return (
    <section>
      <SectionHeader num="06" kicker={t("k_aventura", lang)} title={t("h_hacer", lang)} />
      <p style={{ fontSize: 15, lineHeight: 1.65, color: "#3D362D", marginBottom: 24, fontStyle: "italic", fontFamily: "'DM Serif Display', serif" }}>
        {t("hacerLead", lang)}
      </p>
      {DATA.activities.map((a, i) => (
        <Row key={i} title={tr(a.name, lang)} dist={tr(a.dist, lang)} note={tr(a.note, lang)} last={i === DATA.activities.length - 1} mapQuery={a.mapq || (tr(a.name, lang) + " Puerto Rico")} />
      ))}
    </section>
  );
}

function Noche() {
  const { lang } = useLang();
  return (
    <section>
      <SectionHeader num="07" kicker={t("k_noche", lang)} title={t("h_noche", lang)} />
      <p style={{ fontSize: 15, lineHeight: 1.65, color: "#3D362D", marginBottom: 24, fontStyle: "italic", fontFamily: "'DM Serif Display', serif" }}>
        {t("nocheLead", lang)}
      </p>
      {DATA.nightlife.map((n, i) => (
        <Row key={i} title={tr(n.name, lang)} dist={tr(n.dist, lang)} note={tr(n.note, lang)} last={i === DATA.nightlife.length - 1} mapQuery={n.mapq} />
      ))}
    </section>
  );
}

function Transporte() {
  const { lang } = useLang();
  return (
    <section>
      <SectionHeader num="08" kicker={t("k_moverse", lang)} title={t("h_transporte", lang)} />
      <div style={{ background: "#FBF7EE", border: "1px solid #E5DCC9", padding: 20, marginBottom: 24 }}>
        <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: "0.15em", color: "#9C8A6E", marginBottom: 10 }}>
          {t("distancias", lang)}
        </div>
        <KV label={lang === "es" ? "Aeropuerto SJU" : "SJU Airport"} value={lang === "es" ? "10 min · ~$10 Uber" : "10 min · ~$10 Uber"} />
        <KV label={lang === "es" ? "Playa Isla Verde" : "Isla Verde Beach"} value="10 min" />
        <KV label={lang === "es" ? "Viejo San Juan" : "Old San Juan"} value="20 min · ~$18 Uber" />
        <KV label={lang === "es" ? "El Yunque" : "El Yunque"} value="40 min" />
        <KV label={lang === "es" ? "Fajardo / ferries" : "Fajardo / ferries"} value="55 min" last />
      </div>
      {DATA.transport.map((tx, i) => (
        <Row key={i} title={tr(tx.name, lang)} dist="" note={tr(tx.note, lang)} last={i === DATA.transport.length - 1} />
      ))}
    </section>
  );
}

function Tips() {
  const { lang } = useLang();
  return (
    <section>
      <SectionHeader num="09" kicker={t("k_local", lang)} title={t("h_tips", lang)} />
      {DATA.tips.map((tip, i) => (
        <div
          key={i}
          style={{
            display: "flex",
            gap: 16,
            padding: "16px 0",
            borderBottom: i === DATA.tips.length - 1 ? "none" : "1px solid #E5DCC9",
          }}
        >
          <span
            style={{
              fontFamily: "'JetBrains Mono', monospace",
              fontSize: 11,
              color: "#B85440",
              letterSpacing: "0.1em",
              flexShrink: 0,
              paddingTop: 2,
            }}
          >
            {String(i + 1).padStart(2, "0")}
          </span>
          <span style={{ fontSize: 14, color: "#3D362D", lineHeight: 1.6 }}>{tr(tip, lang)}</span>
        </div>
      ))}
    </section>
  );
}

function Contacto() {
  const { lang } = useLang();
  return (
    <section>
      <SectionHeader num="10" kicker={t("k_aqui", lang)} title={t("h_contacto", lang)} />
      <a
        href={`https://wa.me/${DATA.property.whatsapp.replace(/\D/g, "")}`}
        style={{
          display: "block",
          background: "#2F5D4F",
          color: "#F5EFE3",
          textDecoration: "none",
          padding: "22px 20px",
          textAlign: "center",
          marginBottom: 28,
        }}
      >
        <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: "0.2em", marginBottom: 8, opacity: 0.7 }}>
          {t("whatsappSub", lang)}
        </div>
        <div style={{ fontFamily: "'DM Serif Display', serif", fontSize: 24 }}>
          {t("whatsappCta", lang)}
        </div>
        <div style={{ fontSize: 13, marginTop: 6, opacity: 0.85 }}>
          {DATA.property.whatsapp}
        </div>
      </a>

      <h3 style={{ fontFamily: "'DM Serif Display', serif", fontSize: 22, color: "#2A2520", margin: "0 0 14px" }}>
        {t("numImportantes", lang)}
      </h3>
      {DATA.emergency.map((e, i) => (
        <a key={i} href={`tel:${e.number.replace(/\s/g, "")}`} style={{ textDecoration: "none", display: "block" }}>
          <div
            style={{
              display: "flex",
              justifyContent: "space-between",
              alignItems: "center",
              padding: "16px 0",
              borderBottom: i === DATA.emergency.length - 1 ? "none" : "1px solid #E5DCC9",
              gap: 12,
            }}
          >
            <div style={{ fontSize: 14, color: "#2A2520", fontWeight: 600 }}>{tr(e.label, lang)}</div>
            <div style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 13, color: "#B85440", whiteSpace: "nowrap" }}>{e.number}</div>
          </div>
        </a>
      ))}

      <div style={{ marginTop: 40, textAlign: "center", paddingTop: 32, borderTop: "1px solid #E5DCC9" }}>
        <div style={{ fontFamily: "'DM Serif Display', serif", fontSize: 28, color: "#2A2520", marginBottom: 8 }}>
          {t("gracias", lang)}
        </div>
        <div style={{ fontSize: 13, color: "#9C8A6E", fontStyle: "italic", marginBottom: 22 }}>
          {t("reseña", lang)}
        </div>
        <a
          href={DATA.property.listingUrl}
          target="_blank"
          rel="noopener noreferrer"
          style={{
            display: "inline-flex",
            alignItems: "center",
            justifyContent: "center",
            gap: 10,
            background: "#2A2520",
            color: "#F5EFE3",
            textDecoration: "none",
            padding: "15px 26px",
            fontFamily: "'Manrope', sans-serif",
            fontWeight: 600,
            fontSize: 13,
            letterSpacing: "0.1em",
            textTransform: "uppercase",
          }}
        >
          <svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="#FF5A5F" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M12 21s-6.5-5.2-9-9.3C1.4 8.9 2.6 5.5 6 5.5c2 0 3.2 1.3 4 2.6.8-1.3 2-2.6 4-2.6 3.4 0 4.6 3.4 3 6.2-2.5 4.1-9 9.3-9 9.3Z" fill="#FF5A5F" stroke="none" />
          </svg>
          {lang === "es" ? "Dejar una reseña en Airbnb" : "Leave a review on Airbnb"}
        </a>
      </div>
    </section>
  );
}

// ===================== App ====================
function App() {
  const [lang, setLang] = useState("en");
  const [view, setView] = useState("cover");
  const [active, setActive] = useState("inicio");
  const scrollRef = useRef(null);

  const scrollTo = (id) => {
    setActive(id);
    const el = document.getElementById(`section-${id}`);
    if (el && scrollRef.current) {
      scrollRef.current.scrollTo({ top: el.offsetTop - 70, behavior: "smooth" });
    }
  };

  useEffect(() => {
    if (view !== "guide") return;
    const onScroll = () => {
      if (!scrollRef.current) return;
      const scrollTop = scrollRef.current.scrollTop + 90;
      for (let i = SECTIONS.length - 1; i >= 0; i--) {
        const el = document.getElementById(`section-${SECTIONS[i].id}`);
        if (el && el.offsetTop <= scrollTop) {
          setActive(SECTIONS[i].id);
          break;
        }
      }
    };
    const sc = scrollRef.current;
    sc?.addEventListener("scroll", onScroll);
    return () => sc?.removeEventListener("scroll", onScroll);
  }, [view]);

  const ctxValue = { lang, setLang };

  if (view === "cover") {
    return (
      <LangCtx.Provider value={ctxValue}>
        <div className="phone">
          <Cover onEnter={() => {
            // Synchronously start audio in the user-gesture handler so
            // iOS Safari permits it. setTimeout would break the gesture chain.
            if (audioState.isOn) {
              getPiano().play();
            }
            setView("guide");
          }} />
        </div>
      </LangCtx.Provider>
    );
  }

  return (
    <LangCtx.Provider value={ctxValue}>
      <div className="phone">
        {/* Top bar */}
        <div
          style={{
            position: "sticky",
            top: 0,
            background: "rgba(245, 239, 227, 0.95)",
            backdropFilter: "blur(10px)",
            WebkitBackdropFilter: "blur(10px)",
            borderBottom: "1px solid #E5DCC9",
            padding: "12px 18px",
            display: "flex",
            alignItems: "center",
            justifyContent: "space-between",
            zIndex: 10,
            gap: 12,
          }}
        >
          <button
            onClick={() => setView("cover")}
            style={{ background: "none", border: "none", cursor: "pointer", padding: 0, fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: "0.15em", color: "#6B6155" }}
          >
            ← {t("back", lang)}
          </button>
          <div style={{ fontFamily: "'DM Serif Display', serif", fontSize: 17, color: "#2A2520" }}>
            Villa Coralina
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <SoundToggle />
            <LangPill />
          </div>
        </div>

        {/* Chapter nav */}
        <div
          style={{
            position: "sticky",
            top: 49,
            background: "rgba(245, 239, 227, 0.98)",
            backdropFilter: "blur(10px)",
            WebkitBackdropFilter: "blur(10px)",
            borderBottom: "1px solid #E5DCC9",
            padding: "10px 0",
            overflowX: "auto",
            zIndex: 9,
            whiteSpace: "nowrap",
            WebkitOverflowScrolling: "touch",
          }}
        >
          <div style={{ display: "inline-flex", gap: 4, padding: "0 16px" }}>
            {SECTIONS.map((s) => (
              <button
                key={s.id}
                onClick={() => scrollTo(s.id)}
                style={{
                  background: active === s.id ? "#2A2520" : "transparent",
                  color: active === s.id ? "#F5EFE3" : "#6B6155",
                  border: "none",
                  padding: "8px 14px",
                  fontFamily: "'Manrope', sans-serif",
                  fontSize: 12,
                  fontWeight: 600,
                  letterSpacing: "0.05em",
                  cursor: "pointer",
                  borderRadius: 20,
                  transition: "all 0.2s",
                }}
              >
                {t(s.labelKey, lang)}
              </button>
            ))}
          </div>
        </div>

        {/* Scrolling content */}
        <div ref={scrollRef} style={{ overflowY: "auto", flex: 1, scrollBehavior: "smooth" }}>
          <div style={{ padding: "32px 24px 80px" }}>
            <div id="section-inicio"><Inicio /></div>
            <Divider />
            <div id="section-apto"><Apartamento /></div>
            <Divider />
            <div id="section-area"><Area /></div>
            <Divider />
            <div id="section-comer"><Comer /></div>
            <Divider />
            <div id="section-playas"><Playas /></div>
            <Divider />
            <div id="section-hacer"><Hacer /></div>
            <Divider />
            <div id="section-noche"><Noche /></div>
            <Divider />
            <div id="section-transporte"><Transporte /></div>
            <Divider />
            <div id="section-tips"><Tips /></div>
            <Divider />
            <div id="section-contacto"><Contacto /></div>
          </div>
        </div>
      </div>
    </LangCtx.Provider>
  );
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
