// Shared: Navbar, Footer, WhatsAppFab, TourModal, DibberMark (heart/clover svg), helpers. const { useState, useEffect, useRef } = React; // Brand heart/clover mark \u2014 simplified version of the logo's symbol. // Two stacked rounded shapes: small dot above, a larger soft \u201cheart-blob\u201d below. function DibberMark({ size = 28, color = '#13452A' }) { return ( ); } // A larger \u201chero clover\u201d frame for masking imagery function CloverFrame({ children, size = 480 }) { const id = 'clover-mask-' + Math.random().toString(36).slice(2, 8); return (
{children}
); } const NAV_ITEMS = [ { id: 'home', label: 'Home' }, { id: 'approach', label: 'Nordic Approach' }, { id: 'programmes', label: 'Programmes' }, { id: 'branches', label: 'Branches' }, { id: 'admissions', label: 'Admissions' }, ]; function Navbar({ route, navigate, openTour }) { return (
{ e.preventDefault(); navigate({ name: 'home' }); }} aria-label="Dibber UAE \u2014 home"> Dibber \u2014 Scandinavian Education
Toll-free 800-DIBBER
); } function Footer({ navigate, openTour }) { return ( ); } function FooterCol({ title, children }) { return (
{title}
{children}
); } function FooterLink({ as = 'button', children, onClick, ...rest }) { const Tag = as; const props = as === 'button' ? { onClick, style: { background: 'transparent', color: 'rgba(251,248,240,0.85)', textAlign: 'left', padding: 0, fontSize: 15 } } : { ...rest, style: { color: 'rgba(251,248,240,0.85)', fontSize: 15 } }; return {children}; } // Floating WhatsApp + Call buttons function FabStack() { return (
); } // Tour modal \u2014 prefillable from any branch CTA function TourModal({ open, close, prefill }) { const [step, setStep] = useState(1); const [data, setData] = useState({ branch: prefill?.branch || '', parentName: '', email: '', phone: '', childName: '', dob: '', date: '', timeSlot: 'morning', notes: '', }); useEffect(() => { if (open) { setStep(1); setData(d => ({ ...d, branch: prefill?.branch || '' })); } }, [open, prefill]); if (!open) return null; const set = (k, v) => setData(d => ({ ...d, [k]: v })); const branchObj = BRANCHES.find(b => b.id === data.branch); return (
e.stopPropagation()}>
Book a visit
{step === 3 ? 'You\u2019re booked in' : 'Find a tour time'}
{step !== 3 && (
{[1,2].map(s => (
))}
)} {step === 1 && (

A 45-minute walkaround with the branch manager. Bring your child if you like.

set('date', e.target.value)} />
set('dob', e.target.value)} />
We\u2019ll route you to the right room \u2014 infant, toddler, preschool or KG.
)} {step === 2 && (

Booking a tour at {branchObj?.name || 'Khalifa City A'}. We\u2019ll only use this to contact you about the visit.

set('parentName', e.target.value)} />
set('phone', e.target.value)} />
set('email', e.target.value)} />
)} {step === 3 && (

Tusen takk \u2014 thank you!

The {branchObj?.name || 'Abu Dhabi'} team will be in touch within one working day to confirm your visit. For anything urgent, message us on WhatsApp.

)}
); } // Generic image-with-fallback (some photos may not exist; show striped placeholder) function SafeImg({ src, alt, label, style }) { const [ok, setOk] = useState(true); if (!src || !ok) { return (
{label || 'image placeholder'}
); } return {alt setOk(false)} loading="lazy" />; } // Section header (eyebrow + title + lead) function SectionHead({ eyebrow, title, lead, align = 'left', onDark }) { return (
{eyebrow &&
{eyebrow}
}

{title}

{lead &&

{lead}

}
); } Object.assign(window, { DibberMark, CloverFrame, Navbar, Footer, FabStack, TourModal, SafeImg, SectionHead, NAV_ITEMS });