// Pasta Cook Timer const PASTA_COOK_TIMES = [ { id: 'truffle', name: 'Truffle Mafaldine', shape: 'Long ribbon pasta', time: 210, tip: 'Stir gently in the first 30 seconds to prevent sticking.', img: 'https://images.unsplash.com/photo-1622973536968-3ead9e780960?w=800&q=80' }, { id: 'squid', name: 'Squid Ink Tagliolini', shape: 'Long thin pasta', time: 180, tip: 'Tagliolini cooks fast — watch closely in the last 30 seconds.', img: 'https://images.unsplash.com/photo-1551183053-bf91a1d81141?w=800&q=80' }, { id: 'rigatoni', name: 'Classic Rigatoni', shape: 'Short ridged pasta', time: 270, tip: 'Test at 3:30 — the ridges should still have a firm bite.', img: 'https://images.unsplash.com/photo-1587740908075-9e245311e158?w=800&q=80' }, { id: 'burrata', name: 'Burrata & Pomodoro', shape: 'Short fresh pasta', time: 300, tip: 'Fresh pasta cooks faster than dried — trust the timer, not the color.', img: 'https://images.unsplash.com/photo-1565299624946-b28f40a0ae38?w=800&q=80' }, { id: 'pesto', name: 'Pesto alla Genovese', shape: 'Long thin pasta', time: 195, tip: 'Never rinse after draining — the starch helps the pesto cling.', img: 'https://images.unsplash.com/photo-1473093226795-af9932fe5856?w=800&q=80' }, { id: 'cacio', name: 'Cacio e Pepe', shape: 'Long thin pasta', time: 210, tip: 'Reserve extra pasta water — you\'ll need it for the sauce emulsion.', img: 'https://images.unsplash.com/photo-1556761223-4c4282c73f77?w=800&q=80' }, ]; function GLCookTimer({ app, go }) { const [phase, setPhase] = React.useState('select'); // select | active | done const [selected, setSelected] = React.useState(null); const [remaining, setRemaining] = React.useState(0); const [paused, setPaused] = React.useState(false); const totalRef = React.useRef(0); React.useEffect(() => { if (phase !== 'active' || paused) return; const interval = setInterval(() => { setRemaining(r => { if (r <= 1) { setPhase('done'); return 0; } return r - 1; }); }, 1000); return () => clearInterval(interval); }, [phase, paused]); const startTimer = (pasta) => { totalRef.current = pasta.time; setSelected(pasta); setRemaining(pasta.time); setPaused(false); setPhase('active'); }; const reset = () => { setPhase('select'); setSelected(null); setPaused(false); }; if (phase === 'done') return go('home')} />; if (phase === 'active') return ( setPaused(p => !p)} onReset={reset} /> ); return ; } // ─── Screen 1: Pasta selection ─────────────────────────────────────────────── function CookSelect({ onSelect, go, app }) { const [chosen, setChosen] = React.useState(null); const fmtTime = (s) => `${Math.floor(s / 60)}:${String(s % 60).padStart(2, '0')}`; return (
go('lab')} cartCount={app.cart.length} onCart={() => go('box')} center={
GUSTAI LAB
PASTA TIMER
} />

Cook It
Perfect.

Select your pasta. We'll count down the exact time for a perfect al dente bite — every time.

{PASTA_COOK_TIMES.map(pasta => { const on = chosen?.id === pasta.id; return ( ); })}
{/* Footer */}
{chosen && (
{chosen.tip}
)} chosen && onSelect(chosen)} icon={ } > {chosen ? `Start Timer — ${Math.floor(chosen.time / 60)}:${String(chosen.time % 60).padStart(2, '0')}` : 'Select a Pasta to Begin'}
); } // ─── Screen 2: Active countdown ────────────────────────────────────────────── function CookActive({ pasta, remaining, total, paused, onPause, onReset }) { const R = 130; const CX = 160; const circ = 2 * Math.PI * R; const progress = remaining / total; const dashOffset = circ * (1 - progress); const urgent = remaining <= 30; const mm = String(Math.floor(remaining / 60)).padStart(2, '0'); const ss = String(remaining % 60).padStart(2, '0'); const accentColor = urgent ? '#FF6B35' : GL.teal; return (
{/* Top bar */}
NOW COOKING
{pasta.name}
{pasta.shape}
{/* Ring */}
{/* track */} {/* progress */} {/* dot at leading edge */} {/* Center display — absolutely positioned over the SVG */}
{mm}:{ss}
{paused ? '— Paused —' : urgent ? 'Almost done!' : 'remaining'}
{/* Bottom controls */}
Lab Tip
{pasta.tip}
); } // ─── Screen 3: Done ─────────────────────────────────────────────────────────── function CookDone({ pasta, onReset, onHome }) { return (
{/* Check circle */}

Drain
Now!

{pasta.name} is ready.
Before you drain
Reserve ½ cup of pasta water — it's the secret to a silky sauce emulsion. Don't skip it!
); } Object.assign(window, { GLCookTimer });