// ============================================ // i18n + currency + shared state // ============================================ const COMPANY = { name: "Marrakech Story", email: "Marrakechstory@outlook.com", phone: "+47 457 74 743", phoneIntl: "004745774743", whatsapp: "004745774743", // strip 00 for wa.me address: "La Kasbah, Marrakech 40000, Marokko", instagram: "marrakechstory", }; const TRANSLATIONS = { no: { // nav nav_packages: "Reiser", nav_catalog: "Katalog", nav_plan: "Skreddersy", nav_contact: "Kontakt", nav_cta: "Start planlegging", nav_lang: "Språk", nav_curr: "Valuta", // hero hero_eyebrow: "Eksklusiv reise · siden 2022", hero_hello: "Hei, og velkommen til", hero_brand: "Marrakech Story", hero_sub: "Håndplukkede riader, Atlasfjellene, Sahara og Agafay – reiser skreddersydd av folk som faktisk bor her.", hero_cta_trips: "Utforsk reiser", hero_cta_plan: "Lag din egen reise", stat_years: "År i Marrakech", stat_travellers: "Reisende", stat_review: "Snittvurdering", stat_concierge: "Concierge underveis", // flight search fs_eyebrow: "Direkte fra Oslo til Marrakech", fs_live: "Direktepriser", fs_round: "Tur/retur", fs_one: "En vei", fs_multi: "Flere byer", fs_from: "Fra", fs_to: "Til", fs_dep: "Avreise", fs_ret: "Retur", fs_pax: "Reisende", fs_search: "Søk fly", fs_partner: "partner av", // packages pkg_eyebrow: "Våre mest bookede reiser", pkg_title_a: "Fem varigheter,", pkg_title_b: "én historie", pkg_title_c: "for hver.", pkg_sub: "Hver pakke er fullt tilpassbar – bytt en riad, legg til en hammam, flytt kamelturen til solnedgang. Dette er utgangspunkter, ikke menyer.", pkg_request: "Be om denne reisen", pkg_from: "Fra", pkg_pp: "/ person", pkg_day: "Dag", pkg_included: "Hva er inkludert", pkg_not_included: "Ikke inkludert", pkg_book: "Reserver nå", pkg_view_timeline: "Dag-for-dag tidslinje", pkg_view_incl: "Hva er inkludert", pkg_view_terms: "Vilkår & Refusjon", pkg_final_price: "Sluttpris · per person", pkg_basis: "Basert på 2 som deler · alt inkludert utenom fly", pkg_quote_note: "Kontakt oss for et skreddersydd pristilbud basert på reisedatoer, antall reisende og foretrukket innkvartering.", pkg_custom_label: "Lag din egen", pkg_custom_eyebrow: "Skreddersydd reise", pkg_custom_title_a: "Din reise,", pkg_custom_title_b: "dine regler.", pkg_custom_sub: "Ingen faste pakker passer deg? Fortell oss hva du drømmer om – Sahara, Atlas, riad, aktiviteter – vi setter opp en reise bare for deg.", pkg_custom_cta: "Start planlegging", terms_cancel_title: "Avbestillingsvilkår", terms_col_notice: "Varsel før avreise", terms_col_fee: "Gebyr", terms_fee_admin: "Kun administrasjonsgebyr (€30)", terms_fee_no_refund: "Ingen refusjon", terms_amend_title: "Endringer i bestilling", terms_amend_1: "Navneendringer: €15 per passasjer (der tillatt av leverandør)", terms_amend_2: "Dato- eller ruteendringer: €30 per person + evt. differanse", terms_amend_3: "Endringer aksepteres inntil 30 dager før avreise, avhengig av tilgjengelighet", terms_force_title: "Force majeure", terms_force_body: "Ved force majeure (naturkatastrofer, politisk uro, epidemier eller andre ekstraordinære hendelser utenfor vår kontroll) tilbys full refusjon eller kostnadsfri ombooking. Vi følger IATA- og ONMT-retningslinjene.", terms_insurance_title: "Reiseforsikring", terms_insurance_body: "Vi anbefaler sterkt at alle reisende tegner reise- og avbestillingsforsikring. Marrakech Story er ikke ansvarlig for tap som følge av sykdom, forsinkelse, tyveri eller andre hendelser som dekkes av forsikring.", terms_payment_title: "Betalingsbetingelser", terms_payment_1: "30% depositum ved bestilling for å bekrefte reisen", terms_payment_2: "Resterende 70% forfaller senest 45 dager før avreise", terms_payment_3: "Betaling via bankoverføring eller kortbetaling (Visa/Mastercard). Vi aksepterer EUR, MAD og NOK.", terms_law: "Marrakech Story opererer under marokkansk reiselivslovgivning (Loi n° 31-96 relative aux agences de voyages) og er lisensiert av ONMT (lisens #14872). Tvister behandles etter marokkansk lov.", // catalog cat_eyebrow: "Katalog", cat_title_a: "Våre beste", cat_title_b: "tilbud", cat_title_c: "", cat_sub: "Aktiviteter, restauranter, spa, leirer i Agafay, basseng og transport — alt vi anbefaler. Trykk på det du liker.", cat_results: "treff", cat_per_person: "/ person", cat_per_night: "/ natt", cat_per_day: "/ dag", cat_per_trip: "/ tur", cat_activities: "Aktiviteter", cat_restaurants: "Restauranter", cat_spa: "Spa & Hammam", cat_camps: "Agafay-leirer", cat_pools: "Basseng", cat_transport: "Transport", cat_excursions: "Utflukter", cat_filter_all: "Alle", cat_reviews: "anmeldelser", cat_book: "Reserver", // itinerary form itin_eyebrow: "Bygg din egen reise", itin_title_a: "Lag", itin_title_b: "din egen reise", itin_title_c: "live.", itin_sub: "Velg varighet, stil og interesser – din reise tar form til høyre mens du fyller ut. Når du er klar, sender du den til oss, og vi forfiner detaljene.", itin_step_dur: "Hvor lenge?", itin_step_who: "Hvem reiser?", itin_step_when: "Når?", itin_step_stay: "Overnatting", itin_step_pace: "Tempo", itin_step_int: "Interesser", itin_step_extra: "Det lille ekstra", itin_step_contact: "Kontaktinfo", itin_adults: "Voksne", itin_adults_sub: "12+", itin_kids: "Barn", itin_kids_sub: "2–11", itin_infants: "Spedbarn", itin_infants_sub: "Under 2", itin_start: "Startdato", itin_flex: "Fleksibilitet", itin_flex_exact: "Eksakt", itin_flex_3: "± 3 dager", itin_flex_week: "± 1 uke", itin_flex_month: "Hele måneden", itin_pace_slow: "Avslappet", itin_pace_slow_sub: "Lange lunsjer, sene starter", itin_pace_balanced: "Balansert", itin_pace_balanced_sub: "Aktivitet + hvile", itin_pace_packed: "Pakket fullt", itin_pace_packed_sub: "Se så mye som mulig", itin_acc_riad: "Boutique riad", itin_acc_luxury: "Luksushotell", itin_acc_villa: "Privat villa", itin_acc_camp: "Ørkenleir", itin_acc_mix: "Bland det", itin_acc_surprise: "Overrask oss", itin_budget: "Budsjettramme", itin_budget_sub: "per person, utenom fly", itin_int_medina: "Medina & souker", itin_int_food: "Mat & restauranter", itin_int_sahara: "Sahara-dyner", itin_int_agafay: "Agafay-ørkenen", itin_int_hike: "Atlas-fjellvandring", itin_int_spa: "Hammam & spa", itin_int_cook: "Matkurs", itin_int_shop: "Shopping & håndverk", itin_int_quad: "Quad / buggy", itin_int_balloon: "Luftballong", itin_int_photo: "Fotografi", itin_int_night: "Uteliv & barer", itin_int_coast: "Essaouira-kysten", itin_int_imperial: "Imperialbyene", itin_special: "Spesiell anledning?", itin_special_ph: "f.eks. 40-årsdag, 10-årsjubileum...", itin_avoid: "Noe du vil unngå?", itin_avoid_ph: "f.eks. ingen kameler, ingen turbusser, ingen tidlige starter...", itin_notes: "Annet vi bør vite?", itin_notes_ph: "Åpent – allergier, arbeidsforpliktelser, formnivå, linker du har sett...", itin_name: "Fullt navn", itin_email: "E-post", itin_phone: "Telefon / WhatsApp", itin_country: "Land", itin_send: "Send min reise", itin_sent_title: "Takk, vi har mottatt din reise.", itin_sent_sub: "Du hører fra en ekte planlegger innen 6 arbeidstimer – med fullstendig forfinet program og levende priser.", itin_sent_again: "Lag en ny reise", itin_preview_title: "Din reise – forhåndsvisning", itin_preview_sub: "Reisen din oppdateres live etter hvert som du fyller ut.", itin_preview_arrival: "Ankomst", itin_preview_departure: "Avreise", itin_back: "Tilbake", itin_next: "Neste", itin_step: "Steg", itin_of: "av", // instagram ig_eyebrow: "Følg oss", ig_title_a: "Sett deg i", ig_title_b: "stemningen.", ig_sub: "Daglige glimt fra Marrakech – fra Atlas til Agafay. Tag oss @marrakechstory for å bli delt.", ig_follow: "Følg @marrakechstory", // contact / footer contact_eyebrow: "Snakk med oss", contact_title_a: "Vi er her,", contact_title_b: "i Marrakech.", contact_sub: "Klar til å hjelpe – på e-post, WhatsApp eller telefon.", contact_email_btn: "Send oss en e-post", contact_wa_btn: "Chat på WhatsApp", contact_call_btn: "Ring oss", foot_plan: "Planlegg", foot_discover: "Oppdag", foot_contact: "Kontakt", foot_tag_a: "Boutique-reiser,", foot_tag_b: "designet i", foot_tag_c: "Marrakech.", foot_rights: "Alle rettigheter forbeholdt", wa_label: "Trenger du råd?", wa_sub: "Chat med oss på WhatsApp", }, en: { nav_packages: "Trip packages", nav_catalog: "Catalogue", nav_plan: "Plan your trip", nav_contact: "Contact", nav_cta: "Start planning", nav_lang: "Language", nav_curr: "Currency", hero_eyebrow: "Exclusive travel · est. 2012", hero_hello: "Hello, and welcome to", hero_brand: "Marrakech Story", hero_sub: "Hand-picked riads, the High Atlas, the Sahara dunes and the Agafay stone desert — handcrafted journeys with the people who actually live here.", hero_cta_trips: "Explore trips", hero_cta_plan: "Plan your trip", stat_years: "Years in Marrakech", stat_travellers: "Travellers hosted", stat_review: "Avg. review score", stat_concierge: "Concierge in-trip", fs_eyebrow: "Direct from Oslo to Marrakech", fs_live: "Live fares", fs_round: "Round trip", fs_one: "One way", fs_multi: "Multi-city", fs_from: "From", fs_to: "To", fs_dep: "Departure", fs_ret: "Return", fs_pax: "Travellers", fs_search: "Search flights", fs_partner: "partner of", pkg_eyebrow: "Our most booked trips", pkg_title_a: "Five durations,", pkg_title_b: "one story", pkg_title_c: "for each.", pkg_sub: "Each package is fully tailorable — swap a riad, add a hammam, push the camel sundown an hour later. These are starting points, not menus.", pkg_request: "Request this trip", pkg_from: "From", pkg_pp: "/ person", pkg_day: "Day", pkg_included: "What's included", pkg_not_included: "What's not included", pkg_book: "Book now", pkg_view_timeline: "Day-by-day timeline", pkg_view_incl: "What's included", pkg_view_terms: "Terms & Refund", pkg_final_price: "Final price · per person", pkg_basis: "Based on 2 sharing · all-in except flights", pkg_quote_note: "Contact us for a tailored quote based on travel dates, group size and preferred accommodation.", pkg_custom_label: "Make your own", pkg_custom_eyebrow: "Tailor-made trip", pkg_custom_title_a: "Your trip,", pkg_custom_title_b: "your rules.", pkg_custom_sub: "No fixed package fits you? Tell us what you're dreaming of — Sahara, Atlas, riad, activities — and we'll build a trip just for you.", pkg_custom_cta: "Start planning", terms_cancel_title: "Cancellation policy", terms_col_notice: "Notice before departure", terms_col_fee: "Fee", terms_fee_admin: "Admin fee only (€30)", terms_fee_no_refund: "No refund", terms_amend_title: "Booking amendments", terms_amend_1: "Name changes: €15 per passenger (subject to supplier approval)", terms_amend_2: "Date or itinerary changes: €30 per person + any fare difference", terms_amend_3: "Amendments accepted up to 30 days before departure, subject to availability", terms_force_title: "Force majeure", terms_force_body: "In the event of force majeure (natural disasters, political unrest, epidemics or other extraordinary events beyond our control), a full refund or free rebooking will be offered. We follow IATA and ONMT guidelines.", terms_insurance_title: "Travel insurance", terms_insurance_body: "We strongly recommend all travellers purchase comprehensive travel and cancellation insurance. Marrakech Story is not liable for losses arising from illness, delay, theft or other events typically covered by insurance.", terms_payment_title: "Payment terms", terms_payment_1: "30% deposit required at booking to confirm your trip", terms_payment_2: "Remaining 70% due no later than 45 days before departure", terms_payment_3: "Payment by bank transfer or card (Visa/Mastercard). We accept EUR, MAD and NOK.", terms_law: "Marrakech Story operates under Moroccan tourism law (Loi n° 31-96 relative aux agences de voyages) and is licensed by the ONMT (licence #14872). Disputes are governed by Moroccan law.", cat_eyebrow: "Catalogue", cat_title_a: "Our best", cat_title_b: "offers", cat_title_c: "", cat_sub: "Activities, restaurants, spas, Agafay camps, pools and transport — everything we recommend. Tap on what you like.", cat_results: "results", cat_per_person: "/ person", cat_per_night: "/ night", cat_per_day: "/ day", cat_per_trip: "/ trip", cat_activities: "Activities", cat_restaurants: "Restaurants", cat_spa: "Spa & Hammam", cat_camps: "Agafay camps", cat_pools: "Pools", cat_transport: "Transport", cat_excursions: "Excursions", cat_filter_all: "All", cat_reviews: "reviews", cat_book: "Book", itin_eyebrow: "Build your own trip", itin_title_a: "Design", itin_title_b: "your own itinerary", itin_title_c: "live.", itin_sub: "Pick duration, style and interests — your itinerary takes shape on the right as you fill in. When you're ready, send it to us and we'll refine the details.", itin_step_dur: "How long?", itin_step_who: "Who's coming?", itin_step_when: "When?", itin_step_stay: "Where to stay", itin_step_pace: "Pace", itin_step_int: "Interests", itin_step_extra: "Personal touches", itin_step_contact: "Contact details", itin_adults: "Adults", itin_adults_sub: "12+", itin_kids: "Children", itin_kids_sub: "Ages 2–11", itin_infants: "Infants", itin_infants_sub: "Under 2", itin_start: "Start date", itin_flex: "Flexibility", itin_flex_exact: "Exact", itin_flex_3: "± 3 days", itin_flex_week: "± 1 week", itin_flex_month: "Anywhere in the month", itin_pace_slow: "Slow & spacious", itin_pace_slow_sub: "Long lunches, late starts", itin_pace_balanced: "Balanced", itin_pace_balanced_sub: "Activity + downtime", itin_pace_packed: "Pack it in", itin_pace_packed_sub: "See as much as possible", itin_acc_riad: "Boutique riad", itin_acc_luxury: "Luxury hotel", itin_acc_villa: "Private villa", itin_acc_camp: "Desert camp", itin_acc_mix: "Mix it up", itin_acc_surprise: "Surprise us", itin_budget: "Budget range", itin_budget_sub: "per person, excluding flights", itin_int_medina: "Medina & souks", itin_int_food: "Food & restaurants", itin_int_sahara: "Sahara dunes", itin_int_agafay: "Agafay stone desert", itin_int_hike: "Atlas hiking", itin_int_spa: "Hammam & spa", itin_int_cook: "Cooking class", itin_int_shop: "Shopping & artisans", itin_int_quad: "Quad / buggy", itin_int_balloon: "Hot-air balloon", itin_int_photo: "Photography", itin_int_night: "Nightlife & bars", itin_int_coast: "Essaouira coast", itin_int_imperial: "Imperial cities", itin_special: "Special occasion?", itin_special_ph: "e.g. 40th birthday, 10-year anniversary...", itin_avoid: "Anything you'd rather avoid?", itin_avoid_ph: "e.g. no camels, no big tour buses, no early starts...", itin_notes: "Anything else we should know?", itin_notes_ph: "Open-ended — allergies, work commitments, fitness level, links you've seen...", itin_name: "Full name", itin_email: "Email", itin_phone: "Phone / WhatsApp", itin_country: "Country", itin_send: "Send my itinerary", itin_sent_title: "Thank you — your itinerary is on its way.", itin_sent_sub: "You'll hear from a real planner within 6 working hours, with a fully refined programme and live quotes.", itin_sent_again: "Plan another trip", itin_preview_title: "Your itinerary · live preview", itin_preview_sub: "Your trip updates as you fill in the questions on the left.", itin_preview_arrival: "Arrival", itin_preview_departure: "Departure", itin_back: "Back", itin_next: "Continue", itin_step: "Step", itin_of: "of", ig_eyebrow: "Follow us", ig_title_a: "Get in the", ig_title_b: "mood.", ig_sub: "Daily glimpses from Marrakech — from the Atlas to Agafay. Tag us @marrakechstory to be featured.", ig_follow: "Follow @marrakechstory", contact_eyebrow: "Talk to us", contact_title_a: "We're right here,", contact_title_b: "in Marrakech.", contact_sub: "Ready to help — by email, WhatsApp or phone, every day from 8am to midnight.", contact_email_btn: "Send us an email", contact_wa_btn: "Chat on WhatsApp", contact_call_btn: "Call us", foot_plan: "Plan", foot_discover: "Discover", foot_contact: "Contact", foot_tag_a: "Boutique travel,", foot_tag_b: "designed in", foot_tag_c: "Marrakech.", foot_rights: "All rights reserved", wa_label: "Need advice?", wa_sub: "Chat with us on WhatsApp", }, fr: { nav_packages: "Voyages", nav_catalog: "Catalogue", nav_plan: "Planifier", nav_contact: "Contact", nav_cta: "Commencer", nav_lang: "Langue", nav_curr: "Devise", hero_eyebrow: "Voyage d'exception · depuis 2012", hero_hello: "Bonjour, et bienvenue à", hero_brand: "Marrakech Story", hero_sub: "Riads choisis avec soin, Haut Atlas, dunes du Sahara et désert d'Agafay — des voyages composés par ceux qui vivent ici.", hero_cta_trips: "Découvrir nos voyages", hero_cta_plan: "Créer mon itinéraire", stat_years: "Années à Marrakech", stat_travellers: "Voyageurs accueillis", stat_review: "Note moyenne", stat_concierge: "Conciergerie pendant le séjour", fs_eyebrow: "Direct d'Oslo à Marrakech", fs_live: "Tarifs en direct", fs_round: "Aller-retour", fs_one: "Aller simple", fs_multi: "Multi-villes", fs_from: "De", fs_to: "À", fs_dep: "Départ", fs_ret: "Retour", fs_pax: "Voyageurs", fs_search: "Rechercher", fs_partner: "partenaire de", pkg_eyebrow: "Nos voyages les plus réservés", pkg_title_a: "Cinq durées,", pkg_title_b: "une histoire", pkg_title_c: "pour chacune.", pkg_sub: "Chaque voyage est entièrement personnalisable. Remplacez un riad, ajoutez un hammam, repoussez la balade à dos de chameau. Ce sont des points de départ.", pkg_request: "Demander ce voyage", pkg_from: "Dès", pkg_pp: "/ personne", pkg_day: "Jour", pkg_included: "Inclus", pkg_not_included: "Non inclus", pkg_book: "Réserver", pkg_view_timeline: "Programme jour par jour", pkg_view_incl: "Ce qui est inclus", pkg_view_terms: "Conditions & Remboursement", pkg_final_price: "Prix final · par personne", pkg_basis: "Sur la base de 2 personnes · tout inclus sauf vols", pkg_quote_note: "Contactez-nous pour un devis personnalisé selon les dates, le groupe et l'hébergement souhaité.", pkg_custom_label: "Créer le vôtre", pkg_custom_eyebrow: "Voyage sur mesure", pkg_custom_title_a: "Votre voyage,", pkg_custom_title_b: "vos règles.", pkg_custom_sub: "Aucun forfait fixe ne vous convient ? Dites-nous ce dont vous rêvez — Sahara, Atlas, riad, activités — et nous créons un voyage rien que pour vous.", pkg_custom_cta: "Commencer la planification", terms_cancel_title: "Politique d'annulation", terms_col_notice: "Préavis avant départ", terms_col_fee: "Frais", terms_fee_admin: "Frais admin uniquement (€30)", terms_fee_no_refund: "Aucun remboursement", terms_amend_title: "Modifications de réservation", terms_amend_1: "Changements de nom : €15 par passager (sous réserve d'approbation du prestataire)", terms_amend_2: "Changements de dates ou d'itinéraire : €30 par personne + différence tarifaire éventuelle", terms_amend_3: "Modifications acceptées jusqu'à 30 jours avant le départ, selon disponibilité", terms_force_title: "Force majeure", terms_force_body: "En cas de force majeure (catastrophes naturelles, troubles politiques, épidémies ou autres événements extraordinaires hors de notre contrôle), un remboursement intégral ou un report gratuit sera proposé, conformément aux directives IATA et ONMT.", terms_insurance_title: "Assurance voyage", terms_insurance_body: "Nous recommandons vivement à tous les voyageurs de souscrire une assurance voyage et annulation complète. Marrakech Story décline toute responsabilité pour les pertes dues à la maladie, retards, vol ou autres événements normalement couverts par les assurances.", terms_payment_title: "Conditions de paiement", terms_payment_1: "30 % d'acompte à la réservation pour confirmer le voyage", terms_payment_2: "Solde de 70 % dû au plus tard 45 jours avant le départ", terms_payment_3: "Paiement par virement bancaire ou carte (Visa/Mastercard). Nous acceptons EUR, MAD et NOK.", terms_law: "Marrakech Story opère conformément à la législation touristique marocaine (Loi n° 31-96 relative aux agences de voyages) et est agréée par l'ONMT (licence #14872). Tout litige est régi par le droit marocain.", cat_eyebrow: "Catalogue", cat_title_a: "Nos meilleures", cat_title_b: "offres", cat_title_c: "", cat_sub: "Activités, restaurants, spas, camps d'Agafay, piscines et transport — tout ce que nous recommandons. Touchez ce que vous aimez.", cat_results: "résultats", cat_per_person: "/ personne", cat_per_night: "/ nuit", cat_per_day: "/ jour", cat_per_trip: "/ trajet", cat_activities: "Activités", cat_restaurants: "Restaurants", cat_spa: "Spa & Hammam", cat_camps: "Camps d'Agafay", cat_pools: "Piscines", cat_transport: "Transport", cat_excursions: "Excursions", cat_filter_all: "Tous", cat_reviews: "avis", cat_book: "Réserver", itin_eyebrow: "Composez votre voyage", itin_title_a: "Créez", itin_title_b: "votre itinéraire", itin_title_c: "en direct.", itin_sub: "Choisissez durée, style et envies — votre itinéraire prend forme à droite à mesure que vous remplissez. Envoyez-le quand vous êtes prêt, on affine les détails.", itin_step_dur: "Durée ?", itin_step_who: "Qui voyage ?", itin_step_when: "Quand ?", itin_step_stay: "Hébergement", itin_step_pace: "Rythme", itin_step_int: "Vos envies", itin_step_extra: "Petits détails", itin_step_contact: "Vos coordonnées", itin_adults: "Adultes", itin_adults_sub: "12 ans et +", itin_kids: "Enfants", itin_kids_sub: "2 à 11 ans", itin_infants: "Bébés", itin_infants_sub: "Moins de 2 ans", itin_start: "Date de départ", itin_flex: "Flexibilité", itin_flex_exact: "Exact", itin_flex_3: "± 3 jours", itin_flex_week: "± 1 semaine", itin_flex_month: "Tout le mois", itin_pace_slow: "Doux & posé", itin_pace_slow_sub: "Longs déjeuners, levers tardifs", itin_pace_balanced: "Équilibré", itin_pace_balanced_sub: "Activités + repos", itin_pace_packed: "Bien rempli", itin_pace_packed_sub: "Voir un maximum", itin_acc_riad: "Riad de charme", itin_acc_luxury: "Hôtel de luxe", itin_acc_villa: "Villa privée", itin_acc_camp: "Camp dans le désert", itin_acc_mix: "Mélangez", itin_acc_surprise: "Surprenez-nous", itin_budget: "Budget", itin_budget_sub: "par personne, hors vols", itin_int_medina: "Médina & souks", itin_int_food: "Cuisine & restaurants", itin_int_sahara: "Dunes du Sahara", itin_int_agafay: "Désert d'Agafay", itin_int_hike: "Randonnée Atlas", itin_int_spa: "Hammam & spa", itin_int_cook: "Cours de cuisine", itin_int_shop: "Shopping & artisans", itin_int_quad: "Quad / buggy", itin_int_balloon: "Montgolfière", itin_int_photo: "Photographie", itin_int_night: "Sorties nocturnes", itin_int_coast: "Côte d'Essaouira", itin_int_imperial: "Villes impériales", itin_special: "Occasion spéciale ?", itin_special_ph: "ex. 40 ans, 10 ans de mariage...", itin_avoid: "Quelque chose à éviter ?", itin_avoid_ph: "ex. pas de chameau, pas de gros bus, pas de levers tôt...", itin_notes: "Autre chose à savoir ?", itin_notes_ph: "Libre — allergies, niveau de forme, liens vus, contraintes pro...", itin_name: "Nom complet", itin_email: "Email", itin_phone: "Téléphone / WhatsApp", itin_country: "Pays", itin_send: "Envoyer mon itinéraire", itin_sent_title: "Merci, votre itinéraire est en route.", itin_sent_sub: "Un humain — pas un chatbot — vous recontacte sous 6h ouvrées, avec programme affiné et tarifs en direct.", itin_sent_again: "Créer un autre voyage", itin_preview_title: "Votre itinéraire · aperçu en direct", itin_preview_sub: "Votre voyage se construit à mesure que vous répondez aux questions.", itin_preview_arrival: "Arrivée", itin_preview_departure: "Départ", itin_back: "Retour", itin_next: "Continuer", itin_step: "Étape", itin_of: "sur", ig_eyebrow: "Suivez-nous", ig_title_a: "Mettez-vous", ig_title_b: "dans l'ambiance.", ig_sub: "Aperçus quotidiens de Marrakech — de l'Atlas à Agafay. Identifiez-nous @marrakechstory pour être partagé.", ig_follow: "Suivre @marrakechstory", contact_eyebrow: "Parlons", contact_title_a: "Nous sommes", contact_title_b: "à Marrakech.", contact_sub: "Disponibles par email, WhatsApp ou téléphone — tous les jours de 8h à minuit.", contact_email_btn: "Nous envoyer un email", contact_wa_btn: "Discuter sur WhatsApp", contact_call_btn: "Nous appeler", foot_plan: "Planifier", foot_discover: "Découvrir", foot_contact: "Contact", foot_tag_a: "Voyages boutique,", foot_tag_b: "conçus à", foot_tag_c: "Marrakech.", foot_rights: "Tous droits réservés", wa_label: "Besoin de conseils ?", wa_sub: "Discutez avec nous sur WhatsApp", }, }; // ----- currency ----- const CURRENCIES = { NOK: { rate: 11.5, format: (n) => `kr ${Math.round(n).toLocaleString('no-NO')}` }, EUR: { rate: 1, format: (n) => `€${Math.round(n).toLocaleString('en-GB')}` }, USD: { rate: 1.08, format: (n) => `$${Math.round(n).toLocaleString('en-US')}` }, MAD: { rate: 11, format: (n) => `${Math.round(n).toLocaleString('fr-MA')} MAD` }, GBP: { rate: 0.85, format: (n) => `£${Math.round(n).toLocaleString('en-GB')}` }, }; const LANG_LIST = [ { id: 'no', label: 'Norsk', flag: '🇳🇴' }, { id: 'en', label: 'English', flag: '🇬🇧' }, { id: 'fr', label: 'Français', flag: '🇫🇷' }, ]; const CURR_LIST = [ { id: 'NOK', label: 'kr · Norske kroner' }, { id: 'EUR', label: '€ · Euro' }, { id: 'USD', label: '$ · US Dollar' }, { id: 'MAD', label: 'MAD · Dirham' }, { id: 'GBP', label: '£ · British Pound' }, ]; // Shared state context — language, currency, AND shared flight dates const MSCtx = React.createContext(null); function MSProvider({ children }) { const [lang, setLang] = React.useState('no'); const [curr, setCurr] = React.useState('NOK'); // shared dates between flight search and itinerary form const [dates, setDates] = React.useState({ dep: '2026-06-12', ret: '2026-06-19' }); const [travellers, setTravellers] = React.useState({ adults: 2, children: 0, infants: 0 }); const [from, setFrom] = React.useState({ city: 'Oslo', code: 'OSL' }); return ( {children} ); } function useMS() { return React.useContext(MSCtx); } function useT() { const { lang } = useMS(); return (key) => (TRANSLATIONS[lang] && TRANSLATIONS[lang][key]) || TRANSLATIONS.en[key] || key; } function usePrice() { const { curr } = useMS(); return (eurAmount) => CURRENCIES[curr].format(eurAmount * CURRENCIES[curr].rate); } window.MS_CTX = { MSProvider, useMS, useT, usePrice, LANG_LIST, CURR_LIST, CURRENCIES, TRANSLATIONS, COMPANY };