// i18n.jsx — language switcher (EN/FR/DE/ES) + dictionary-based auto-translator.
// Strategy: the app re-mounts on language change (key={lang}) so the DOM is fresh
// English, then translateAll() rewrites text nodes + key attributes from the
// dictionary. A guarded MutationObserver re-applies after dynamic re-renders.

const LANGS = [['en', 'English'], ['fr', 'Français'], ['de', 'Deutsch'], ['es', 'Español']];

const T_DICT = {
  // chrome / cta
  "Register Interest": { fr: "Demander des informations", de: "Interesse anmelden", es: "Solicitar información" },
  "Why Dubai": { fr: "Pourquoi Dubaï", de: "Warum Dubai", es: "Por qué Dubái" },
  "The World's Smartest Place to Own.": { fr: "Le placement immobilier le plus malin au monde.", de: "Der klügste Ort der Welt für Wohneigentum.", es: "El lugar más inteligente del mundo para invertir." },
  "Dubai, in Five Numbers.": { fr: "Dubaï, en cinq chiffres.", de: "Dubai, in fünf Zahlen.", es: "Dubái, en cinco cifras." },
  "No annual property, income or capital-gains tax.": { fr: "Pas de taxe foncière annuelle, ni impôt sur le revenu ou les plus-values.", de: "Keine jährliche Grund-, Einkommen- oder Kapitalertragsteuer.", es: "Sin impuesto anual sobre la propiedad, la renta ni las plusvalías." },
  "Golden Visa on homes of AED 2M+.": { fr: "Golden Visa pour les biens à partir de 2 M AED.", de: "Golden Visa für Immobilien ab 2 Mio. AED.", es: "Golden Visa para viviendas desde 2 M AED." },
  "A leading Dubai developer. Recession-proof, risk-free investment.": { fr: "Un promoteur de premier plan à Dubaï. Un investissement anti-récession et sans risque.", de: "Ein führender Entwickler in Dubai. Rezessionssichere, risikofreie Investition.", es: "Un promotor líder en Dubái. Inversión a prueba de recesión y sin riesgo." },
  "Ranked among the world\u2019s safest cities.": { fr: "Classée parmi les villes les plus sûres au monde.", de: "Zählt zu den sichersten Städten der Welt.", es: "Entre las ciudades más seguras del mundo." },
  "Gross rental yields, among the world’s strongest.": { fr: "Rendements locatifs bruts, parmi les plus élevés au monde.", de: "Brutto-Mietrenditen, zu den höchsten weltweit zählend.", es: "Rentabilidad bruta del alquiler, entre las más altas del mundo." },
  "Golden Visa residency on homes of AED 2M+.": { fr: "Résidence Golden Visa pour les biens à partir de 2 M AED.", de: "Golden-Visa-Aufenthalt für Immobilien ab 2 Mio. AED.", es: "Residencia Golden Visa para viviendas desde 2 M AED." },
  "Golden Visa residency on homes of AED 2M+.": { fr: "Résidence Golden Visa pour les biens à partir de 2 M AED.", de: "Golden-Visa-Aufenthalt für Immobilien ab 2 Mio. AED.", es: "Residencia Golden Visa para viviendas desde 2 M AED." },
  "Freehold for all nationalities. RERA escrow protected.": { fr: "Pleine propriété pour toutes les nationalités. Protégée par séquestre RERA.", de: "Volleigentum für alle Nationalitäten. Durch RERA-Treuhand geschützt.", es: "Propiedad plena para todas las nacionalidades. Protegida por depósito RERA." },
  "From India, 7 from Europe. One of the world\u2019s safest cities.": { fr: "3 h de l'Inde, 7 de l'Europe. L'une des villes les plus sûres au monde.", de: "3 Std. von Indien, 7 von Europa. Eine der sichersten Städte der Welt.", es: "A 3 h de India, 7 de Europa. Una de las ciudades más seguras del mundo." },
  "Market figures: Dubai Land Department / published portal data, 2025. Indicative only, not financial advice.": { fr: "Données de marché : Dubai Land Department / portails publiés, 2025. Indicatif uniquement, pas un conseil financier.", de: "Marktdaten: Dubai Land Department / veröffentlichte Portaldaten, 2025. Nur indikativ, keine Finanzberatung.", es: "Datos de mercado: Dubai Land Department / portales publicados, 2025. Solo indicativo, no es asesoramiento financiero." },
  "Average rental yields, 2 to 3 times London or New York": { fr: "Rendements locatifs moyens, 2 à 3 fois Londres ou New York", de: "Durchschnittliche Mietrenditen, 2 bis 3 mal London oder New York", es: "Rentabilidad media del alquiler, 2 a 3 veces Londres o Nueva York" },
  "Dirham pegged to the US dollar — no FX risk": { fr: "Dirham indexé sur le dollar — sans risque de change", de: "Dirham an den US-Dollar gekoppelt — kein Wechselkursrisiko", es: "Dírham vinculado al dólar — sin riesgo cambiario" },
  "Golden Visa residency on AED 2M+ homes": { fr: "Golden Visa pour les biens à partir de 2 M AED", de: "Golden Visa für Immobilien ab 2 Mio. AED", es: "Golden Visa para viviendas desde 2 M AED" },
  "Freehold ownership, RERA escrow protected": { fr: "Pleine propriété, protégée par séquestre RERA", de: "Volleigentum, durch RERA-Treuhand geschützt", es: "Propiedad plena, protegida por depósito RERA" },
  "From Europe, in one of the world’s safest cities": { fr: "Depuis l'Europe, dans l'une des villes les plus sûres au monde", de: "Aus Europa erreichbar, in einer der sichersten Städte der Welt", es: "Desde Europa, en una de las ciudades más seguras del mundo" },
  "Indicative figures for information only. Not financial advice.": { fr: "Chiffres indicatifs à titre informatif. Pas un conseil financier.", de: "Indikative Angaben nur zur Information. Keine Finanzberatung.", es: "Cifras orientativas solo informativas. No constituyen asesoramiento financiero." },
  "View All Photos": { fr: "Voir toutes les photos", de: "Alle Fotos ansehen", es: "Ver todas las fotos" },
  "Do I pay tax on a Dubai property?": { fr: "Y a-t-il des impôts sur un bien à Dubaï ?", de: "Zahle ich Steuern auf eine Dubai-Immobilie?", es: "¿Pago impuestos por una propiedad en Dubái?" },
  "No. Dubai has no property tax, no tax on rental income, and no capital-gains tax for individual owners.": { fr: "Non. Dubaï n'applique ni taxe foncière, ni impôt sur les revenus locatifs, ni impôt sur les plus-values pour les particuliers.", de: "Nein. Dubai erhebt keine Grundsteuer, keine Steuer auf Mieteinnahmen und keine Kapitalertragsteuer für Privatpersonen.", es: "No. Dubái no aplica impuesto sobre la propiedad, ni sobre los ingresos por alquiler, ni sobre las plusvalías para particulares." },
  "Can buying get me residency?": { fr: "L'achat donne-t-il droit à la résidence ?", de: "Erhalte ich durch den Kauf einen Aufenthaltstitel?", es: "¿La compra da derecho a residencia?" },
  "Yes. A Dubai home worth AED 2M or more (including off-plan like Flare) qualifies you and your family for a 10-year renewable Golden Visa.": { fr: "Oui. Un bien à Dubaï d'au moins 2 M AED (y compris en off-plan comme Flare) vous donne droit, ainsi qu'à votre famille, à un Golden Visa de 10 ans renouvelable.", de: "Ja. Eine Dubai-Immobilie ab 2 Mio. AED (auch off-plan wie Flare) qualifiziert Sie und Ihre Familie für ein 10-jähriges, verlängerbares Golden Visa.", es: "Sí. Una vivienda en Dubái de 2 M AED o más (incluido off-plan como Flare) le da derecho, a usted y a su familia, a un Golden Visa de 10 años renovable." },
  "Can I buy from overseas?": { fr: "Puis-je acheter depuis l'étranger ?", de: "Kann ich aus dem Ausland kaufen?", es: "¿Puedo comprar desde el extranjero?" },
  "Yes. The full process (reservation, contracts and payments) can be completed remotely, and we guide you at every step.": { fr: "Oui. Tout le processus (réservation, contrats et paiements) peut se faire à distance, et nous vous accompagnons à chaque étape.", de: "Ja. Der gesamte Ablauf (Reservierung, Verträge und Zahlungen) kann aus der Ferne erfolgen, und wir begleiten Sie bei jedem Schritt.", es: "Sí. Todo el proceso (reserva, contratos y pagos) puede completarse a distancia, y le acompañamos en cada paso." },
  // hero
  "A landmark collection of residences, crafted by Binghatti on an easy": {
    fr: "Une collection de résidences d'exception signée Binghatti, avec un confortable",
    de: "Eine markante Residenzen-Kollektion von Binghatti, mit einem unkomplizierten",
    es: "Una destacada colección de residencias de Binghatti, con un cómodo" },
  "70/30 plan": { fr: "plan 70/30", de: "70/30-Plan", es: "plan 70/30" },
  "Starting price": { fr: "Prix de départ", de: "Startpreis", es: "Precio inicial" },
  "Studio to 4 BR": { fr: "Studio à 4 ch.", de: "Studio bis 4 Zi.", es: "Studio a 4 hab." },
  "Residences & retail": { fr: "Résidences et commerces", de: "Residenzen & Handel", es: "Residencias y comercios" },
  "Handover": { fr: "Livraison", de: "Übergabe", es: "Entrega" },
  // facts
  "Why Flare": { fr: "Pourquoi Flare", de: "Warum Flare", es: "Por qué Flare" },
  "A Community That Matters.": { fr: "Une communauté qui compte.", de: "Eine Gemeinschaft, die zählt.", es: "Una comunidad que importa." },
  "Iconic towers · 40 & 34 floors": { fr: "Tours emblématiques · 40 & 34 étages", de: "Markante Türme · 40 & 34 Etagen", es: "Torres icónicas · 40 y 34 plantas" },
  "Residences + 79 retail units": { fr: "Résidences + 79 commerces", de: "Residenzen + 79 Geschäfte", es: "Residencias + 79 locales" },
  "Easy payment plan*": { fr: "Plan de paiement facile*", de: "Einfacher Zahlungsplan*", es: "Plan de pago cómodo*" },
  "Minutes to Marina & Downtown": { fr: "À quelques minutes de Marina & Downtown", de: "Minuten zu Marina & Downtown", es: "A minutos de Marina y Downtown" },
  // unit mix
  "Choose your residence": { fr: "Choisissez votre résidence", de: "Wählen Sie Ihre Residenz", es: "Elija su residencia" },
  "From Studios to Four Bedroom Sky Homes": { fr: "Du studio aux appartements de quatre chambres", de: "Vom Studio bis zur Vier-Zimmer-Wohnung", es: "De estudios a viviendas de cuatro dormitorios" },
  "1 Bedroom": { fr: "1 chambre", de: "1 Schlafzimmer", es: "1 dormitorio" },
  "2 Bedroom": { fr: "2 chambres", de: "2 Schlafzimmer", es: "2 dormitorios" },
  "3 Bedroom": { fr: "3 chambres", de: "3 Schlafzimmer", es: "3 dormitorios" },
  "4 Bedroom": { fr: "4 chambres", de: "4 Schlafzimmer", es: "4 dormitorios" },
  "3 & 4 Bedroom": { fr: "3 & 4 chambres", de: "3 & 4 Schlafzimmer", es: "3 y 4 dormitorios" },
  "Price on request": { fr: "Prix sur demande", de: "Preis auf Anfrage", es: "Precio a consultar" },
  "Investor favourite": { fr: "Favori des investisseurs", de: "Investorenliebling", es: "Favorito de inversores" },
  "Balcony · skyline view": { fr: "Balcon · vue sur la skyline", de: "Balkon · Skyline-Blick", es: "Balcón · vista al skyline" },
  "Family ready": { fr: "Idéal en famille", de: "Familienfreundlich", es: "Ideal para familias" },
  "Sky terrace · pool": { fr: "Terrasse en hauteur · piscine", de: "Sky-Terrasse · Pool", es: "Terraza panorámica · piscina" },
  "Enquire": { fr: "Demander", de: "Anfragen", es: "Consultar" },
  "* Indicative starting prices. Confirm availability on enquiry.": { fr: "* Prix de départ indicatifs. Disponibilité à confirmer sur demande.", de: "* Indikative Startpreise. Verfügbarkeit auf Anfrage.", es: "* Precios iniciales orientativos. Disponibilidad a confirmar." },
  // amenities
  "Life at Flare": { fr: "La vie à Flare", de: "Leben in Flare", es: "La vida en Flare" },
  "Resort Amenities at Your Door.": { fr: "Des équipements de resort à votre porte.", de: "Resort-Annehmlichkeiten vor Ihrer Tür.", es: "Servicios de resort a su puerta." },
  "Artificial beach": { fr: "Plage artificielle", de: "Künstlicher Strand", es: "Playa artificial" },
  "Sand & pool deck": { fr: "Sable et terrasse piscine", de: "Sand & Pooldeck", es: "Arena y solárium" },
  "Private sky pools": { fr: "Piscines privées en hauteur", de: "Private Sky-Pools", es: "Piscinas privadas en altura" },
  "Sky-terrace homes": { fr: "Appartements avec terrasse", de: "Wohnungen mit Sky-Terrasse", es: "Viviendas con terraza" },
  "Gym & running lane": { fr: "Salle de sport et piste de course", de: "Fitness & Laufstrecke", es: "Gimnasio y pista de carrera" },
  "Wellness floor": { fr: "Étage bien-être", de: "Wellness-Etage", es: "Planta de bienestar" },
  "Paddle court": { fr: "Terrain de padel", de: "Padel-Platz", es: "Pista de pádel" },
  "Active living": { fr: "Vie active", de: "Aktives Leben", es: "Vida activa" },
  "Kids wet & dry play": { fr: "Aire de jeux enfants", de: "Kinder-Spielbereiche", es: "Zona de juegos infantil" },
  "Family zones": { fr: "Espaces famille", de: "Familienbereiche", es: "Zonas familiares" },
  "Luxury lobby": { fr: "Lobby de luxe", de: "Luxuriöse Lobby", es: "Vestíbulo de lujo" },
  "Signature arrival": { fr: "Arrivée signature", de: "Stilvoller Empfang", es: "Llegada de autor" },
  "Retail & shopping": { fr: "Commerces et boutiques", de: "Handel & Shopping", es: "Comercios y tiendas" },
  "79 units below": { fr: "79 commerces en contrebas", de: "79 Geschäfte darunter", es: "79 locales debajo" },
  "Skyline views": { fr: "Vues sur la skyline", de: "Skyline-Ausblicke", es: "Vistas al skyline" },
  "Burj on the horizon": { fr: "Burj à l'horizon", de: "Burj am Horizont", es: "Burj en el horizonte" },
  // floor plans
  "Layouts": { fr: "Plans", de: "Grundrisse", es: "Distribuciones" },
  "Floor Plans": { fr: "Plans d'étage", de: "Grundrisse", es: "Planos" },
  "Floor plans available on request": { fr: "Plans disponibles sur demande", de: "Grundrisse auf Anfrage", es: "Planos disponibles a petición" },
  "Tap to unlock": { fr: "Appuyez pour débloquer", de: "Zum Freischalten tippen", es: "Toque para desbloquear" },
  "Unlock floor plan": { fr: "Débloquer le plan", de: "Grundriss freischalten", es: "Desbloquear plano" },
  "Indicative layout. Request the full floor plan pack with sizes and the current price list.": { fr: "Plan indicatif. Demandez le dossier complet avec les surfaces et la liste de prix actuelle.", de: "Indikativer Grundriss. Fordern Sie das komplette Paket mit Flächen und aktueller Preisliste an.", es: "Distribución orientativa. Solicite el dossier completo con superficies y la lista de precios actual." },
  "Request Full Floor Plan": { fr: "Demander le plan complet", de: "Vollständigen Grundriss anfordern", es: "Solicitar plano completo" },
  // gallery
  "See it": { fr: "À découvrir", de: "Ansehen", es: "Descúbralo" },
  "The Gallery": { fr: "La galerie", de: "Die Galerie", es: "La galería" },
  "View image": { fr: "Voir l'image", de: "Bild ansehen", es: "Ver imagen" },
  // location
  "Where it is": { fr: "Emplacement", de: "Lage", es: "Ubicación" },
  "JVT. Central and Connected.": { fr: "JVT. Central et connecté.", de: "JVT. Zentral und vernetzt.", es: "JVT. Céntrico y conectado." },
  "Drive times indicative.": { fr: "Temps de trajet indicatifs.", de: "Fahrzeiten indikativ.", es: "Tiempos de trayecto orientativos." },
  // payment
  "Easy to own": { fr: "Facile à acquérir", de: "Einfach zu erwerben", es: "Fácil de adquirir" },
  "Built for Buyers and Investors": { fr: "Pensé pour acheteurs et investisseurs", de: "Für Käufer und Investoren gemacht", es: "Pensado para compradores e inversores" },
  "Book": { fr: "Réservation", de: "Buchung", es: "Reserva" },
  "Down payment": { fr: "Acompte", de: "Anzahlung", es: "Entrada" },
  "Build": { fr: "Construction", de: "Bau", es: "Construcción" },
  "During construction": { fr: "Pendant la construction", de: "Während des Baus", es: "Durante la construcción" },
  "On completion": { fr: "À la livraison", de: "Bei Fertigstellung", es: "A la entrega" },
  "Book Now": { fr: "Réserver", de: "Jetzt buchen", es: "Reservar ahora" },
  // faq
  "Good to know": { fr: "Bon à savoir", de: "Gut zu wissen", es: "Conviene saber" },
  "Questions, Answered": { fr: "Vos questions, nos réponses", de: "Fragen, beantwortet", es: "Preguntas, respondidas" },
  "What types of residences are available?": { fr: "Quels types de résidences sont disponibles ?", de: "Welche Wohnungstypen gibt es?", es: "¿Qué tipos de residencias hay disponibles?" },
  "Studios to four bedroom apartments across two towers, plus retail.": { fr: "Du studio à l'appartement de quatre chambres répartis sur deux tours, plus des commerces.", de: "Vom Studio bis zur Vier-Zimmer-Wohnung in zwei Türmen, dazu Handelsflächen.", es: "Desde estudios hasta apartamentos de cuatro dormitorios en dos torres, más comercios." },
  "Who is the developer?": { fr: "Qui est le promoteur ?", de: "Wer ist der Entwickler?", es: "¿Quién es el promotor?" },
  "Binghatti is one of Dubai's leading developers, known for its bold, sculptural towers and a portfolio of landmark residences across the city.": { fr: "Binghatti est l'un des principaux promoteurs de Dubaï, reconnu pour ses tours sculpturales audacieuses et un portefeuille de résidences emblématiques dans toute la ville.", de: "Binghatti ist einer der führenden Entwickler Dubais, bekannt für markante, skulpturale Türme und ein Portfolio prägender Residenzen in der ganzen Stadt.", es: "Binghatti es uno de los principales promotores de Dubái, reconocido por sus torres escultóricas y una cartera de residencias emblemáticas en toda la ciudad." },
  "What is the payment plan?": { fr: "Quel est le plan de paiement ?", de: "Wie sieht der Zahlungsplan aus?", es: "¿Cuál es el plan de pago?" },
  "70/30: 20% on booking, 50% during construction, 30% on handover.": { fr: "70/30 : 20 % à la réservation, 50 % pendant la construction, 30 % à la livraison.", de: "70/30: 20 % bei Buchung, 50 % während des Baus, 30 % bei Übergabe.", es: "70/30: 20 % en la reserva, 50 % durante la construcción, 30 % en la entrega." },
  "When is handover?": { fr: "Quand a lieu la livraison ?", de: "Wann ist die Übergabe?", es: "¿Cuándo es la entrega?" },
  "Targeted for Q2 2027. Indicative, confirmed at booking.": { fr: "Prévue pour le 2e trimestre 2027. Indicative, confirmée à la réservation.", de: "Geplant für Q2 2027. Indikativ, bestätigt bei Buchung.", es: "Prevista para el 2.º trimestre de 2027. Orientativa, se confirma en la reserva." },
  "Can foreign nationals buy?": { fr: "Les étrangers peuvent-ils acheter ?", de: "Können Ausländer kaufen?", es: "¿Pueden comprar extranjeros?" },
  "Yes. Flare is freehold, open to all nationalities.": { fr: "Oui. Flare est en pleine propriété, ouvert à toutes les nationalités.", de: "Ja. Flare ist Eigentum (Freehold), offen für alle Nationalitäten.", es: "Sí. Flare es en propiedad plena (freehold), abierto a todas las nacionalidades." },
  "What are the starting prices?": { fr: "Quels sont les prix de départ ?", de: "Wie hoch sind die Einstiegspreise?", es: "¿Cuáles son los precios iniciales?" },
  // final cta
  "Own a Piece of the Skyline.": { fr: "Possédez un morceau de la skyline.", de: "Sichern Sie sich ein Stück Skyline.", es: "Posea un trozo del skyline." },
  "Get the price list and floor plans on WhatsApp in minutes.": { fr: "Recevez la liste des prix et les plans sur WhatsApp en quelques minutes.", de: "Erhalten Sie Preisliste und Grundrisse in Minuten per WhatsApp.", es: "Reciba la lista de precios y los planos por WhatsApp en minutos." },
  "Chat on WhatsApp": { fr: "Discuter sur WhatsApp", de: "Auf WhatsApp chatten", es: "Chatear por WhatsApp" },
  // sticky
  "Call": { fr: "Appeler", de: "Anrufen", es: "Llamar" },
  // footer
  "Marketed by": { fr: "Commercialisé par", de: "Vermarktet von", es: "Comercializado por" },
  "Privacy Policy": { fr: "Politique de confidentialité", de: "Datenschutz", es: "Política de privacidad" },
  "Cookie Policy": { fr: "Politique de cookies", de: "Cookie-Richtlinie", es: "Política de cookies" },
  "Disclaimer": { fr: "Mentions légales", de: "Haftungsausschluss", es: "Aviso legal" },
  // cookie
  "We use cookies to improve your experience.": { fr: "Nous utilisons des cookies pour améliorer votre expérience.", de: "Wir verwenden Cookies, um Ihre Erfahrung zu verbessern.", es: "Usamos cookies para mejorar su experiencia." },
  "Learn more": { fr: "En savoir plus", de: "Mehr erfahren", es: "Más información" },
  "Accept": { fr: "Accepter", de: "Akzeptieren", es: "Aceptar" },
  // lead form
  "Get the price list & floor plans": { fr: "Recevez la liste des prix et les plans", de: "Preisliste & Grundrisse erhalten", es: "Reciba la lista de precios y los planos" },
  "Instant reply on WhatsApp. No spam.": { fr: "Réponse immédiate sur WhatsApp. Sans spam.", de: "Sofortige Antwort per WhatsApp. Kein Spam.", es: "Respuesta inmediata por WhatsApp. Sin spam." },
  "Full name": { fr: "Nom complet", de: "Vollständiger Name", es: "Nombre completo" },
  "Your name": { fr: "Votre nom", de: "Ihr Name", es: "Su nombre" },
  "Mobile number": { fr: "Numéro de mobile", de: "Mobilnummer", es: "Número de móvil" },
  "Email address": { fr: "Adresse e-mail", de: "E-Mail-Adresse", es: "Correo electrónico" },
  "Interested in": { fr: "Intéressé par", de: "Interesse an", es: "Interesado en" },
  "Select a residence": { fr: "Sélectionnez une résidence", de: "Residenz auswählen", es: "Seleccione una residencia" },
  "Send me the details": { fr: "Envoyez-moi les détails", de: "Senden Sie mir die Details", es: "Envíenme la información" },
  "Sending…": { fr: "Envoi…", de: "Senden…", es: "Enviando…" },
  "I agree to be contacted about this project.": { fr: "J'accepte d'être contacté au sujet de ce projet.", de: "Ich stimme zu, zu diesem Projekt kontaktiert zu werden.", es: "Acepto ser contactado sobre este proyecto." },
  "Search country": { fr: "Rechercher un pays", de: "Land suchen", es: "Buscar país" },
  "No match": { fr: "Aucun résultat", de: "Keine Treffer", es: "Sin coincidencias" },
  "Thank you": { fr: "Merci", de: "Danke", es: "Gracias" },
  "We'll send the price list and floor plans on WhatsApp shortly.": { fr: "Nous vous enverrons la liste des prix et les plans sur WhatsApp sous peu.", de: "Wir senden Ihnen in Kürze Preisliste und Grundrisse per WhatsApp.", es: "Le enviaremos la lista de precios y los planos por WhatsApp en breve." },
  "Chat now on WhatsApp": { fr: "Discuter maintenant sur WhatsApp", de: "Jetzt auf WhatsApp chatten", es: "Chatear ahora por WhatsApp" },
  // aria
  "Please enter your name": { fr: "Veuillez saisir votre nom", de: "Bitte geben Sie Ihren Namen ein", es: "Introduzca su nombre" },
  "Please enter a valid name": { fr: "Veuillez saisir un nom valide", de: "Bitte geben Sie einen gültigen Namen ein", es: "Introduzca un nombre válido" },
  "Enter a valid mobile number": { fr: "Saisissez un numéro de mobile valide", de: "Geben Sie eine gültige Mobilnummer ein", es: "Introduzca un número de móvil válido" },
  "Enter a valid email address": { fr: "Saisissez une adresse e-mail valide", de: "Geben Sie eine gültige E-Mail-Adresse ein", es: "Introduzca un correo electrónico válido" },
  "Please tick the box to continue": { fr: "Cochez la case pour continuer", de: "Bitte ankreuzen, um fortzufahren", es: "Marque la casilla para continuar" },
  "A 360° Walk Through Flare.": { fr: "Une visite à 360° de Flare.", de: "Ein 360°-Rundgang durch Flare.", es: "Un recorrido de 360° por Flare." },
  "Step inside": { fr: "Entrez", de: "Treten Sie ein", es: "Entre" },
  "Close": { fr: "Fermer", de: "Schließen", es: "Cerrar" },
  "Previous": { fr: "Précédent", de: "Zurück", es: "Anterior" },
  "Next": { fr: "Suivant", de: "Weiter", es: "Siguiente" },
};

const I18N_ATTRS = ['placeholder', 'aria-label', 'title'];
let _obs = null, _busy = false, _raf = 0;

function translateAll() {
  const lang = window.__lang || 'en';
  const root = document.getElementById('root');
  if (!root) return;
  _busy = true;
  if (_obs) _obs.disconnect();
  if (lang !== 'en') {
    const w = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null);
    const list = [];
    while (w.nextNode()) list.push(w.currentNode);
    for (const n of list) {
      const raw = n.nodeValue;
      if (!raw) continue;
      const key = raw.trim();
      if (!key) continue;
      const e = T_DICT[key];
      if (e && e[lang]) { const t = raw.replace(key, e[lang]); if (n.nodeValue !== t) n.nodeValue = t; }
    }
    root.querySelectorAll('[placeholder],[aria-label],[title]').forEach(el => {
      for (const a of I18N_ATTRS) {
        const raw = el.getAttribute(a);
        if (!raw) continue;
        const key = raw.trim();
        const e = T_DICT[key];
        if (e && e[lang]) { const t = raw.replace(key, e[lang]); if (raw !== t) el.setAttribute(a, t); }
      }
    });
  }
  if (_obs) _obs.observe(root, { childList: true, subtree: true, characterData: true, attributes: true, attributeFilter: I18N_ATTRS });
  _busy = false;
}

function scheduleTranslate() {
  if ((window.__lang || 'en') === 'en') return;
  if (_raf) cancelAnimationFrame(_raf);
  _raf = requestAnimationFrame(() => { _raf = 0; translateAll(); });
}

(function setupObserver() {
  const root = document.getElementById('root');
  if (!root) { setTimeout(setupObserver, 60); return; }
  _obs = new MutationObserver(() => { if (!_busy) scheduleTranslate(); });
  _obs.observe(root, { childList: true, subtree: true, characterData: true, attributes: true, attributeFilter: I18N_ATTRS });
})();

const LangCtx = React.createContext(['en', () => {}]);
function useLang() { return React.useContext(LangCtx); }

function LangSwitcher() {
  const [lang, setLang] = useLang();
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const onDoc = e => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', onDoc);
    return () => document.removeEventListener('mousedown', onDoc);
  }, []);
  const cur = LANGS.find(l => l[0] === lang) || LANGS[0];
  return (
    <div className="lg-cur lg-lang" ref={ref}>
      <button type="button" className="lg-cur-toggle" onClick={() => setOpen(o => !o)} aria-haspopup="listbox" aria-expanded={open}>
        <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" style={{ marginRight: 6, verticalAlign: '-2px' }} aria-hidden="true"><circle cx="12" cy="12" r="9" /><path d="M3 12h18" /><path d="M12 3c2.5 2.7 2.5 15.3 0 18M12 3c-2.5 2.7-2.5 15.3 0 18" /></svg>
        {cur[0].toUpperCase()}<span className={`lg-cur-caret ${open ? 'lg-cur-caret-up' : ''}`}>▾</span>
      </button>
      {open && (
        <ul className="lg-cur-menu" role="listbox" style={{ minWidth: 128 }}>
          {LANGS.map(l => (
            <li key={l[0]} role="option" aria-selected={lang === l[0]}
                className={`lg-cur-opt ${lang === l[0] ? 'lg-cur-opt-on' : ''}`}
                style={{ whiteSpace: 'nowrap' }}
                onClick={() => { setLang(l[0]); setOpen(false); }}>{l[1]}</li>
          ))}
        </ul>
      )}
    </div>
  );
}

Object.assign(window, { LangCtx, useLang, LangSwitcher, translateAll, LANGS });
