"use client"; import { useEffect, useState, type MouseEvent } from "react"; import { motion, useReducedMotion } from "motion/react"; type Floor = { label: string; href: string; /** Small line shown in the lobby of that floor. */ note?: string; /** Text on the button. Default: G for the first floor, then 1, 2, 3. */ mark?: string; }; type ElevatorNavProps = { /** Lowest floor first, 2 to 6. */ floors: Floor[]; /** Index of the floor the lift starts on. */ start?: number; /** Seconds to travel one floor. */ secondsPerFloor?: number; /** Called on press. Call event.preventDefault() to stay on the page. */ onSelect?: (floor: Floor, event: MouseEvent) => void; /** Name read out by screen readers. */ label?: string; className?: string; }; const LOBBY = ["#7c2f25", "#27584f", "#3a4a78", "#7a5a1e", "#5b3560", "#2f5a7a"]; /* ElevatorNav: a brass lift panel. Press a floor: the doors shut, the needle sweeps over the arc floor by floor, the doors open on that page. */ export function ElevatorNav({ floors, start = 0, secondsPerFloor = 0.7, onSelect, label = "Site floors", className = "" }: ElevatorNavProps) { const reduce = useReducedMotion(); const [at, setAt] = useState(start); const [goal, setGoal] = useState(start); const [open, setOpen] = useState(true); useEffect(() => { const after = (seconds: number, run: () => void) => { const timer = setTimeout(run, reduce ? 0 : seconds * 1000); return () => clearTimeout(timer); }; if (at !== goal) { if (open) return after(0.55, () => setOpen(false)); return after(secondsPerFloor, () => setAt((a) => a + Math.sign(goal - a))); } if (!open) return after(0.3, () => setOpen(true)); }, [at, goal, open, reduce, secondsPerFloor]); const top = Math.max(floors.length - 1, 1); const tilt = (i: number) => -68 + (136 * i) / top; const mark = (i: number) => floors[i].mark ?? (i === 0 ? "G" : String(i)); const here = floors[at]; const going = Math.sign(goal - at); return ( ); }