/* global React */
// Shared components for Langebaan

const { useState, useMemo, useEffect, useRef } = React;

// ──────────────────────────────────────────────────────────────
// Icons (small, hand-stroked, inline SVG)
// ──────────────────────────────────────────────────────────────
const Ico = {
  search: (p) => <svg viewBox="0 0 24 24" width={p.s||16} height={p.s||16} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></svg>,
  pin:    (p) => <svg viewBox="0 0 24 24" width={p.s||16} height={p.s||16} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M12 22s-7-7.5-7-13a7 7 0 1 1 14 0c0 5.5-7 13-7 13Z"/><circle cx="12" cy="9" r="2.5"/></svg>,
  cal:    (p) => <svg viewBox="0 0 24 24" width={p.s||16} height={p.s||16} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><rect x="3.5" y="5" width="17" height="15.5" rx="2"/><path d="M3.5 9.5h17M8 3.5v3M16 3.5v3"/></svg>,
  user:   (p) => <svg viewBox="0 0 24 24" width={p.s||16} height={p.s||16} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><circle cx="12" cy="8" r="4"/><path d="M4 21c0-4.4 3.6-8 8-8s8 3.6 8 8"/></svg>,
  bed:    (p) => <svg viewBox="0 0 24 24" width={p.s||18} height={p.s||18} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M3 18V8m18 10v-5a3 3 0 0 0-3-3H3"/><path d="M3 18h18"/><circle cx="8" cy="12.5" r="2"/></svg>,
  bath:   (p) => <svg viewBox="0 0 24 24" width={p.s||18} height={p.s||18} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M3 12h18v3a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4v-3Z"/><path d="M6 12V6a2 2 0 0 1 4 0M5 19l-1 2M19 19l1 2"/></svg>,
  guests: (p) => <svg viewBox="0 0 24 24" width={p.s||18} height={p.s||18} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><circle cx="9" cy="9" r="3.2"/><circle cx="17" cy="10" r="2.4"/><path d="M3 19c0-3 2.7-5 6-5s6 2 6 5M15 18c0-2 1.6-3.5 4-3.5"/></svg>,
  wifi:   (p) => <svg viewBox="0 0 24 24" width={p.s||18} height={p.s||18} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><path d="M2 9a16 16 0 0 1 20 0M5 13a11 11 0 0 1 14 0M8.5 16.5a6 6 0 0 1 7 0"/><circle cx="12" cy="19.5" r="1" fill="currentColor"/></svg>,
  fire:   (p) => <svg viewBox="0 0 24 24" width={p.s||18} height={p.s||18} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2.5c1 3 4 4 4 8a4 4 0 0 1-8 0c0-1.5.7-2.4 1.5-3"/><path d="M9 13c-2 1-3 3-3 5a6 6 0 0 0 12 0c0-3-2-4-3-5"/></svg>,
  parking:(p) => <svg viewBox="0 0 24 24" width={p.s||18} height={p.s||18} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><rect x="4" y="4" width="16" height="16" rx="3"/><path d="M10 17V8h4a2.5 2.5 0 0 1 0 5h-4"/></svg>,
  pool:   (p) => <svg viewBox="0 0 24 24" width={p.s||18} height={p.s||18} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M2 18c1.5-1 3-1 4.5 0s3 1 4.5 0 3-1 4.5 0 3 1 4.5 0"/><path d="M2 14c1.5-1 3-1 4.5 0s3 1 4.5 0 3-1 4.5 0 3 1 4.5 0"/><path d="M7 13V6a2 2 0 0 1 4 0v8M13 13V6a2 2 0 0 1 4 0v8"/></svg>,
  pet:    (p) => <svg viewBox="0 0 24 24" width={p.s||18} height={p.s||18} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round"><circle cx="6" cy="10" r="1.8"/><circle cx="10" cy="6" r="1.8"/><circle cx="14" cy="6" r="1.8"/><circle cx="18" cy="10" r="1.8"/><path d="M12 11c-2.5 0-5 2.4-5 5 0 1.7 1.3 3 3 3 1 0 1.5-.5 2-.5s1 .5 2 .5c1.7 0 3-1.3 3-3 0-2.6-2.5-5-5-5Z"/></svg>,
  kitchen:(p) => <svg viewBox="0 0 24 24" width={p.s||18} height={p.s||18} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M6 3v8M9 3v6a3 3 0 0 1-6 0V3M7.5 11v10M17 3c-2 0-3 1.5-3 4v5h6V7c0-2.5-1-4-3-4ZM17 12v9"/></svg>,
  ac:     (p) => <svg viewBox="0 0 24 24" width={p.s||18} height={p.s||18} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><path d="M12 3v18M3 12h18M5.5 5.5l13 13M18.5 5.5l-13 13"/></svg>,
  star:   (p) => <svg viewBox="0 0 24 24" width={p.s||14} height={p.s||14} fill="currentColor"><path d="M12 2.5l2.7 6 6.5.7-4.9 4.4 1.4 6.4L12 16.7 6.3 20l1.4-6.4L2.8 9.2l6.5-.7L12 2.5Z"/></svg>,
  heart:  (p) => <svg viewBox="0 0 24 24" width={p.s||16} height={p.s||16} fill={p.filled?'currentColor':'none'} stroke="currentColor" strokeWidth="1.6" strokeLinejoin="round"><path d="M12 20s-7-4.5-7-10a4.5 4.5 0 0 1 8-3 4.5 4.5 0 0 1 8 3c0 5.5-7 10-7 10Z" strokeLinecap="round"/></svg>,
  arrow:  (p) => <svg viewBox="0 0 24 24" width={p.s||16} height={p.s||16} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>,
  back:   (p) => <svg viewBox="0 0 24 24" width={p.s||16} height={p.s||16} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M19 12H5M11 6l-6 6 6 6"/></svg>,
  chev:   (p) => <svg viewBox="0 0 24 24" width={p.s||14} height={p.s||14} fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m9 6 6 6-6 6"/></svg>,
  plus:   (p) => <svg viewBox="0 0 24 24" width={p.s||14} height={p.s||14} fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M12 5v14M5 12h14"/></svg>,
  minus:  (p) => <svg viewBox="0 0 24 24" width={p.s||14} height={p.s||14} fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M5 12h14"/></svg>,
  check:  (p) => <svg viewBox="0 0 24 24" width={p.s||14} height={p.s||14} fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m4 12 5 5L20 6"/></svg>,
  share:  (p) => <svg viewBox="0 0 24 24" width={p.s||16} height={p.s||16} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><circle cx="6" cy="12" r="2.5"/><circle cx="18" cy="6" r="2.5"/><circle cx="18" cy="18" r="2.5"/><path d="m8.2 11 7.6-4M8.2 13l7.6 4"/></svg>,
  tide:   (p) => <svg viewBox="0 0 24 24" width={p.s||18} height={p.s||18} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M2 12c2-2 4-2 6 0s4 2 6 0 4-2 6 0M2 17c2-2 4-2 6 0s4 2 6 0 4-2 6 0M12 5V2M9 5l3-3 3 3"/></svg>,
  filter: (p) => <svg viewBox="0 0 24 24" width={p.s||16} height={p.s||16} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><path d="M4 6h16M7 12h10M10 18h4"/></svg>,
  sort:   (p) => <svg viewBox="0 0 24 24" width={p.s||16} height={p.s||16} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><path d="M7 5v14M3 9l4-4 4 4M17 19V5M13 15l4 4 4-4"/></svg>,
  lock:   (p) => <svg viewBox="0 0 24 24" width={p.s||16} height={p.s||16} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"><rect x="4.5" y="11" width="15" height="9" rx="2"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/></svg>,
  menu:   (p) => <svg viewBox="0 0 24 24" width={p.s||18} height={p.s||18} fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><path d="M4 7h16M4 12h16M4 17h16"/></svg>,
};

// ──────────────────────────────────────────────────────────────
// Property data
// ──────────────────────────────────────────────────────────────
const PROPERTIES = [
  { id: 'driftwood',   name: 'Driftwood Cottage',        loc: 'Pearl Bay',     price: 245, rating: 4.94, reviews: 128, beds: 3, baths: 2, guests: 6, walk: 2,  tone: 'sand',  blurb: 'Whitewashed clapboard with a deep verandah and uninterrupted reach across the dune line.', tags:['Beachfront','Pet-friendly','Family'], img: 'whitewashed cottage · golden hour', icon:'NW-facing'},
  { id: 'tideglass',   name: 'Tideglass House',          loc: 'Langebaan',       price: 410, rating: 4.99, reviews:  84, beds: 4, baths: 3, guests: 8, walk: 1,  tone: 'ocean', blurb: 'Architect-built, full-height glazing onto the breakers. Sleeps eight in linen-soft calm.', tags:['Architect','Sea views','Hot tub'], img: 'modernist deck · breakers below', icon:'2 min · sand'},
  { id: 'salthaven',   name: 'Salt Haven',               loc: 'Calypso Beach',        price: 185, rating: 4.86, reviews: 211, beds: 2, baths: 1, guests: 4, walk: 5,  tone: 'shell', blurb: 'A working fisherman’s cottage, soft-restored. Slate floors, deep window seats.', tags:['Historic','Cosy','Couples'], img: 'fisherman cottage · slate hearth', icon:'5 min · path'},
  { id: 'pelican',     name: 'Pelican Loft',             loc: 'Club Mykonos',    price: 168, rating: 4.81, reviews: 156, beds: 1, baths: 1, guests: 2, walk: 3,  tone: 'dusk',  blurb: 'A one-bedroom apartment above the harbour, with the rigging-clink as your morning soundtrack.', tags:['Harbour','Studio','Walkable'], img: 'harbour loft · rigging masts', icon:'Quay-side'},
  { id: 'duneline',    name: 'Duneline Lodge',           loc: 'Kraalbaai',     price: 295, rating: 4.92, reviews:  47, beds: 3, baths: 2, guests: 6, walk: 0,  tone: 'sky',   blurb: 'Cedar-clad lodge built into the marram. Step from the deck onto warm sand.', tags:['Dune access','Sauna','Family'], img: 'cedar lodge · marram grass', icon:'On the dune'},
  { id: 'mariner',     name: "Mariner's Reach",          loc: 'Mykonos Village',       price: 220, rating: 4.88, reviews:  93, beds: 3, baths: 2, guests: 5, walk: 6,  tone: 'deep',  blurb: 'A captain’s house on the cobbled lane up from the slipway. Restored bookcases, deep bath.', tags:['Historic','Walk to pubs','Reading'], img: 'georgian terrace · brass knocker', icon:'Old town'},
];

// ──────────────────────────────────────────────────────────────
// Image placeholder (designed, not generic)
// ──────────────────────────────────────────────────────────────
function SBImage({ tone='sand', label, corner, children, style, className='', kind }) {
  return (
    <div className={`sb-img tone-${tone} ${className}`} style={style}>
      {children}
      {corner ? <div className="sb-img-corner">{corner}</div> : null}
      {label ? <div className="sb-img-label">{label}</div> : null}
      {kind ? <div className="sb-img-label" style={{left:'auto', right:12, bottom:12}}>{kind}</div> : null}
    </div>
  );
}

// ──────────────────────────────────────────────────────────────
// Logo
// ──────────────────────────────────────────────────────────────
function Logo({ size = 22, light = false }) {
  // Recoloured Langebaan wordmark (sand-gold + ocean-navy on cream disc).
  // `light` flips background to translucent so it sits cleanly on the dark hero.
  return (
    <img
      src="/logo_recoloured.png"
      alt="Langebaan Holiday Homes"
      style={{
        height: size * 2.8, width: 'auto', display: 'block',
        filter: light ? 'drop-shadow(0 2px 8px rgba(0,0,0,0.25))' : 'none',
      }}
    />
  );
}

// ──────────────────────────────────────────────────────────────
// Rating
// ──────────────────────────────────────────────────────────────
function Rating({ value, count, compact }) {
  return (
    <span className="star" style={{display:'inline-flex', alignItems:'center', gap:5, fontSize: compact?12:13, fontWeight:600}}>
      <Ico.star s={compact?12:13}/>
      {value}{count ? <span style={{color:'var(--muted)', fontWeight:500}}>({count})</span> : null}
    </span>
  );
}

// ──────────────────────────────────────────────────────────────
// Tide widget — fake but pretty
// ──────────────────────────────────────────────────────────────
function Tide({ compact=false, dark=false }) {
  // Pseudo wave bars
  const bars = useMemo(() => {
    const out = [];
    for (let i=0; i<14; i++) {
      const v = 0.4 + Math.abs(Math.sin((i+2)/2.4))*0.6;
      out.push(v);
    }
    return out;
  }, []);
  return (
    <div className="tide" style={dark ? { background: 'rgba(255,255,255,0.10)', color: 'var(--paper)', borderColor: 'rgba(255,255,255,0.18)', backdropFilter: 'blur(8px)' } : {}}>
      <Ico.tide s={16}/>
      <div className="tide-bars">
        {bars.map((v,i) => <i key={i} style={{height: `${v*100}%`, opacity: dark?0.9:0.75, background: dark?'var(--paper)':'var(--ocean)'}}/>)}
      </div>
      <div style={{display:'flex', flexDirection:'column', lineHeight:1.15}}>
        <span style={{fontWeight:600, letterSpacing:'-0.005em'}}>High 14:32</span>
        {!compact && <span style={{fontSize:10.5, letterSpacing:'0.06em', opacity:.75}}>Low 08:14 · 21:08</span>}
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────
// Top navigation
// ──────────────────────────────────────────────────────────────
function TopNav({ onNav, active, transparent=false }) {
  const style = transparent ? { background: 'transparent', borderBottomColor: 'rgba(255,255,255,0.18)', color: 'var(--paper)' } : {};
  const linkColor = transparent ? { color: 'var(--paper)' } : {};
  return (
    <header className="nav" style={style}>
      <div style={{display:'flex', alignItems:'center', gap:40}}>
        <div onClick={() => onNav && onNav('home')} style={{cursor:'pointer'}}>
          {transparent ? <Logo size={22} light/> : <Logo size={22}/>}
        </div>
        <nav className="nav-links" style={linkColor}>
          <a onClick={()=>onNav&&onNav('list')} style={{cursor:'pointer', ...linkColor, fontWeight: active==='list'?700:500}}>Stay</a>
          <a style={linkColor}>Experiences</a>
          <a style={linkColor}>Local guide</a>
          <a style={linkColor}>Owners</a>
        </nav>
      </div>
      <div style={{display:'flex', gap:14, alignItems:'center'}}>
        <span style={{fontSize:13, ...linkColor}}>EN · ZAR</span>
        <button className={transparent?'btn btn-paper btn-sm':'btn btn-ghost btn-sm'}>
          <Ico.user s={14}/> Sign in
        </button>
      </div>
    </header>
  );
}

// ──────────────────────────────────────────────────────────────
// Search bar (composer)
// ──────────────────────────────────────────────────────────────
function SearchBar({ values, onChange, onSearch, dark=false }) {
  const v = values || { where: 'Langebaan, West Coast', checkin: 'Fri 12 Jun', checkout: 'Mon 15 Jun', guests: '4 guests · 1 dog' };
  const upd = (k) => (e) => onChange && onChange({ ...v, [k]: e.target.value });
  return (
    <div className="searchbar" style={dark ? { background: 'rgba(255,255,255,0.95)', boxShadow:'0 24px 60px -24px rgba(0,0,0,0.6)' } : {}}>
      <div className="seg field">
        <label>Where</label>
        <input value={v.where} onChange={upd('where')}/>
      </div>
      <div className="seg field">
        <label>Check in</label>
        <input value={v.checkin} onChange={upd('checkin')}/>
      </div>
      <div className="seg field">
        <label>Check out</label>
        <input value={v.checkout} onChange={upd('checkout')}/>
      </div>
      <div className="seg field">
        <label>Guests</label>
        <input value={v.guests} onChange={upd('guests')}/>
      </div>
      <button className="btn btn-primary" onClick={onSearch} style={{height:48, paddingLeft:22, paddingRight:22}}>
        <Ico.search s={14}/> Search
      </button>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────
// Property card
// ──────────────────────────────────────────────────────────────
function PropCard({ p, fav, onFav, onClick, large=false }) {
  return (
    <div className="prop" onClick={onClick}>
      <div className="img-wrap" style={ large ? { aspectRatio: '5/4' } : {}}>
        <SBImage tone={p.tone} label={p.img} corner={p.icon}/>
        <button className={`heart ${fav?'on':''}`} onClick={(e)=>{e.stopPropagation(); onFav && onFav(p.id);}} aria-label="favourite">
          <Ico.heart filled={fav}/>
        </button>
        {p.walk <= 2 && (
          <div style={{position:'absolute', left:12, top:12, display:'inline-flex', gap:6, alignItems:'center', padding:'5px 10px', background:'rgba(255,255,255,0.92)', borderRadius:999, fontSize:11, fontWeight:600, letterSpacing:'0.02em'}}>
            <span style={{width:6, height:6, borderRadius:999, background:'var(--ocean)'}}/> Steps from sand
          </div>
        )}
      </div>
      <div>
        <div className="prop-meta">
          <div>
            <div className="prop-title">{p.name}</div>
            <div className="prop-loc">{p.loc} · Sleeps {p.guests}</div>
          </div>
          <Rating value={p.rating} count={p.reviews} compact/>
        </div>
        <div className="prop-meta" style={{marginTop:10}}>
          <div className="prop-price">R{p.price} <small>/ night</small></div>
          <div className="t-meta">Tide HW 14:32 · {p.walk===0?'0 min':p.walk+' min'} to sea</div>
        </div>
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────
// Mini-calendar
// ──────────────────────────────────────────────────────────────
function MiniCalendar({ year=2026, month=5 /* 0-idx; June */, startDay=12, endDay=15, onSelect, disabled=[] }) {
  const monthName = new Date(year, month, 1).toLocaleString('en-GB', { month: 'long' });
  const first = new Date(year, month, 1).getDay(); // 0 Sun
  // Make Monday-first
  const firstMon = (first + 6) % 7;
  const dim = new Date(year, month+1, 0).getDate();
  const prevDim = new Date(year, month, 0).getDate();
  const days = [];
  for (let i=0; i<firstMon; i++) days.push({d: prevDim - firstMon + 1 + i, out:true});
  for (let i=1; i<=dim; i++) days.push({d: i});
  while (days.length % 7 !== 0) days.push({d: days.length - dim - firstMon + 1, out:true});
  // pad to 6 rows
  while (days.length < 42) days.push({d: days.length - dim - firstMon + 1, out:true});

  return (
    <div>
      <div style={{display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:14}}>
        <button className="btn btn-ghost btn-sm" style={{borderRadius:8, padding:'6px 10px'}}><Ico.chev s={12} style={{transform:'rotate(180deg)'}}/></button>
        <div style={{fontWeight:600, fontSize:15, letterSpacing:'-0.005em'}}>{monthName} {year}</div>
        <button className="btn btn-ghost btn-sm" style={{borderRadius:8, padding:'6px 10px'}}><Ico.chev s={12}/></button>
      </div>
      <div className="cal">
        {['Mo','Tu','We','Th','Fr','Sa','Su'].map(d => <div key={d} className="cal-head">{d}</div>)}
        {days.map((cell, i) => {
          if (cell.out) return <div key={i} className="cal-day is-out">{cell.d}</div>;
          const between = cell.d > startDay && cell.d < endDay;
          const start = cell.d === startDay;
          const end = cell.d === endDay;
          const dis = disabled.includes(cell.d);
          return (
            <div key={i}
              className={`cal-day ${start?'is-start':''} ${end?'is-end':''} ${between?'is-between':''} ${dis?'is-disabled':''}`}
              onClick={() => !dis && onSelect && onSelect(cell.d)}>
              {cell.d}
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────
// Step indicator
// ──────────────────────────────────────────────────────────────
function Steps({ step }) {
  const labels = ['Dates', 'Guests', 'Review', 'Pay'];
  return (
    <div className="steps">
      {labels.map((l, i) => (
        <React.Fragment key={i}>
          <div className={`dot ${step===i?'is-active':''} ${step>i?'is-done':''}`}>{step>i ? <Ico.check s={11}/> : (i+1)}</div>
          <span style={{fontWeight: step===i?700:500, color: step>=i?'var(--ink)':'var(--muted)'}}>{l}</span>
          {i<labels.length-1 && <span className={`bar ${step>i?'is-done':''}`}/>}
        </React.Fragment>
      ))}
    </div>
  );
}

// ──────────────────────────────────────────────────────────────
// Counter
// ──────────────────────────────────────────────────────────────
function Counter({ label, sub, value, onChange, min=0, max=12 }) {
  return (
    <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', padding:'18px 0', borderBottom:'1px solid var(--rule)'}}>
      <div>
        <div style={{fontWeight:600}}>{label}</div>
        {sub && <div className="t-meta">{sub}</div>}
      </div>
      <div style={{display:'flex', alignItems:'center', gap:14}}>
        <button onClick={()=>onChange(Math.max(min, value-1))} disabled={value<=min}
          style={{width:32, height:32, borderRadius:999, border:'1px solid var(--rule-strong)', background:'transparent', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center', opacity:value<=min?0.3:1}}>
          <Ico.minus/>
        </button>
        <div style={{width:24, textAlign:'center', fontVariantNumeric:'tabular-nums', fontWeight:600}}>{value}</div>
        <button onClick={()=>onChange(Math.min(max, value+1))} disabled={value>=max}
          style={{width:32, height:32, borderRadius:999, border:'1px solid var(--rule-strong)', background:'transparent', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center', opacity:value>=max?0.3:1}}>
          <Ico.plus/>
        </button>
      </div>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────
// Footer
// ──────────────────────────────────────────────────────────────
function Footer() {
  return (
    <footer className="foot">
      <div>
        <Logo size={20}/>
        <p style={{color:'var(--muted)', fontSize:13, lineHeight:1.6, maxWidth:340, marginTop:14}}>
          Independent holiday homes on the west coast. Hand-picked by people who live a sand-shake from the dunes.
        </p>
        <div className="tags" style={{marginTop:18}}>
          <span className="chip">B-Corp Pending</span>
          <span className="chip">Travellers Choice ’26</span>
        </div>
      </div>
      <div>
        <h4>Explore</h4>
        <a>The bay</a><a>Tide guide</a><a>Local journal</a><a>Surf report</a>
      </div>
      <div>
        <h4>Company</h4>
        <a>About</a><a>Owners portal</a><a>Press</a><a>Careers</a>
      </div>
      <div>
        <h4>Help</h4>
        <a>Cancellation</a><a>Trust & safety</a><a>Contact</a><a>FAQ</a>
        <div style={{marginTop:24, paddingTop:18, borderTop:'1px solid var(--rule)', fontSize:11, color:'var(--muted)'}}>© 2026 Langebaan Holiday Homes</div>
      </div>
    </footer>
  );
}

Object.assign(window, { Ico, PROPERTIES, SBImage, Logo, Rating, Tide, TopNav, SearchBar, PropCard, MiniCalendar, Steps, Counter, Footer });
