/* global React */ const { useState, useEffect, useMemo, useRef } = React; // ─── Iconography ────────────────────────────────────────────────────────── // Simple stroke-only icons; matches the technical/precise aesthetic. const Icon = ({ name, size = 18, stroke = 1.6 }) => { const props = { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: stroke, strokeLinecap: "round", strokeLinejoin: "round" }; const paths = { arrow: <>, arrowDl: <>, close: <>, chevron: <>, plus: <>, minus: <>, check: <>, phone: <>, whatsapp: <>, pin: <>, clock: <>, shield: <>, bolt: <>, seats: <>, gear: <>, fuel: <>, door: <>, star: , award: <>, search: <>, filter: <>, cal: <>, user: <>, car: <>, grid: <>, list: <>, ext: <>, play: }; return ; }; window.Icon = Icon; // ─── Brand / Logo ───────────────────────────────────────────────────────── const Logo = ({ height = 22 }) => ( { e.preventDefault(); window.go("home"); }} className="logo" style={{ display:"inline-flex", alignItems:"center", gap:10, height, textDecoration:"none" }}> O OCTANE.RENT ); window.Logo = Logo; // ─── Chip / Pill ────────────────────────────────────────────────────────── const Chip = ({ children, tone = "default", icon, size = "md" }) => { const tones = { default: { bg:"rgba(255,255,255,0.04)", fg:"var(--text)", bd:"var(--border)" }, primary: { bg:"rgba(225,108,42,0.12)", fg:"var(--primary)", bd:"rgba(225,108,42,0.45)" }, ghost: { bg:"transparent", fg:"var(--muted)", bd:"var(--border)" }, solid: { bg:"var(--primary)", fg:"#0E0F12", bd:"var(--primary)" }, paper: { bg:"#fff", fg:"#0E0F12", bd:"#fff" } }[tone]; const sizing = size === "sm" ? { fontSize: 11, padding:"4px 8px" } : { fontSize: 12, padding:"6px 10px" }; return ( {icon && } {children} ); }; window.Chip = Chip; // ─── Button ─────────────────────────────────────────────────────────────── const Btn = ({ children, onClick, variant = "primary", icon, iconRight, size = "md", as = "button", href, full, type, style }) => { const sizing = { sm: { padding:"8px 14px", fontSize: 12, gap: 6 }, md: { padding:"12px 18px", fontSize: 13, gap: 8 }, lg: { padding:"16px 24px", fontSize: 14, gap: 10 } }[size]; const variants = { primary: { bg:"var(--primary)", fg:"#0E0F12", bd:"var(--primary)", hover:"var(--secondary)" }, ghost: { bg:"transparent", fg:"var(--text)", bd:"var(--border)", hover:"rgba(255,255,255,0.06)" }, dark: { bg:"var(--surface-2)", fg:"var(--text)", bd:"var(--border)", hover:"var(--surface)" }, whatsapp:{ bg:"#25D366", fg:"#0E0F12", bd:"#25D366", hover:"#1fb957" }, outline: { bg:"transparent", fg:"var(--primary)", bd:"var(--primary)", hover:"rgba(225,108,42,0.08)" } }; const v = variants[variant]; const [hover, setHover] = useState(false); const css = { display:"inline-flex", alignItems:"center", justifyContent:"center", ...sizing, fontFamily:"var(--font-display)", fontWeight: 700, letterSpacing: 1, textTransform:"uppercase", border:`1px solid ${v.bd}`, background: hover ? v.hover : v.bg, color: v.fg, borderRadius: 4, cursor:"pointer", textDecoration:"none", width: full ? "100%" : "auto", transition:"all .15s ease", ...style }; const inner = <>{icon && }{children}{iconRight && }; if (as === "a" || href) return setHover(true)} onMouseLeave={() => setHover(false)} target={href?.startsWith("http") || href?.startsWith("tel") || href?.startsWith("mailto") ? "_blank" : undefined} rel="noopener">{inner}; return ; }; window.Btn = Btn; // ─── Price helper ───────────────────────────────────────────────────────── const Price = ({ value, size = "md", muted }) => { const sizes = { sm: 14, md: 18, lg: 28, xl: 40 }; if (value == null) { return On request; } return ( FROM {value.toLocaleString()} AED / day ); }; window.Price = Price; // ─── Vehicle Card ───────────────────────────────────────────────────────── const VehicleCard = ({ v, onSelect, density = "comfortable" }) => { const [hover, setHover] = useState(false); const padding = density === "compact" ? 16 : 20; return (
onSelect(v)} onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)} style={{ background:"var(--surface)", border:"1px solid var(--border)", borderRadius: 10, overflow:"hidden", cursor:"pointer", display:"flex", flexDirection:"column", transition:"transform .25s ease, border-color .25s ease", transform: hover ? "translateY(-3px)" : "translateY(0)", borderColor: hover ? "var(--primary)" : "var(--border)" }} >
{`${v.make} {/* corner badge */}
{v.tags.slice(0,1).map(t => {t})}
No deposit
{/* category strip */}
{v.category}·{v.body}
{v.make}

{v.model}

{v.seats} {v.transmission} {v.fuel}
Book
); }; window.VehicleCard = VehicleCard; // ─── Section header ────────────────────────────────────────────────────── const SectionHead = ({ kicker, title, sub, action, align = "left" }) => (
{kicker &&
{kicker}
}

{title}

{sub &&

{sub}

}
{action}
); window.SectionHead = SectionHead; // ─── Sticky WhatsApp / Call FAB ────────────────────────────────────────── const FloatRail = () => ( ); window.FloatRail = FloatRail; Object.assign(window, { Icon, Logo, Chip, Btn, Price, VehicleCard, SectionHead, FloatRail });