// home/Today.jsx — the post-onboarding home base. One vertical scroll that // opens as a calm morning briefing and becomes the launcher as you scroll. // // 1. Hero (fills first viewport): eyebrow · narrative · signature metric · // one thin stat row. greetingGradient, full-bleed. // 2. Today's Arc — today-only timeline (the only calendar surface here). // 3. Module shelf — 2-col tiles, each a chip + label + one live datum. // + 5-tab bar pinned (Today active). ✛ opens the Create sheet. function Today({ dark = false, tint = 'blue', heroMetric = 'bedtime', // bedtime | focus view = 'top', // top | shelf — 'shelf' shows the on-scroll (collapsed-hero) state interactive = false, // when true, ✛ toggles the Create sheet in-frame palette, // hero gradient palette (array rep or name) timeOfDay = 'Auto', // Auto | Dawn | Morning | Afternoon | Evening | Night onCreate, }) { const [sheetOpen, setSheetOpen] = React.useState(false); const handleCreate = interactive ? () => setSheetOpen(true) : onCreate; const collapsed = view === 'shelf'; const grad = gradientFor(palette, timeOfDay); const greeting = greetingForTod(timeOfDay, 'Lukas'); const arcItems = [ { kind: 'past', time: '7:15', suffix: 'AM', title: 'Morning shift', location: 'Riverside · Office', feed: 'work' }, { kind: 'past', time: '9:00', suffix: 'AM', title: 'Daylight walk', location: 'Hyde Park', feed: 'personal' }, { kind: 'next', time: '10:30', suffix: 'AM', title: 'Standup', location: 'Engineering · room G', feed: 'work' }, { kind: 'next', time: '1:00', suffix: 'PM', title: 'Lunch with Maya', location: 'Honey & Co', feed: 'family' }, { kind: 'next', time: '2:30', suffix: 'PM', title: 'COMP3010 · Algorithms', location: 'Roberts G06', feed: 'uni' }, { kind: 'next', time: '5:00', suffix: 'PM', title: 'Climbing session', location: 'The Castle', feed: 'gym' }, { kind: 'next', time: '10:00', suffix: 'PM', title: '🌙 Wind down', location: 'Bedtime 10:30 PM', feed: 'bedtime' }, ]; const heroProps = heroMetric === 'focus' ? { metricLabel: 'Focus left today', metric: '3', metricUnit: 'things', showMoon: false, metricSub: 'Algorithms lecture · Maya at 1 · finish thesis §4.2.', } : { metricLabel: "Tonight's bedtime", metric: '10:30', metricUnit: 'PM', showMoon: true, metricSub: 'Worked back from tomorrow — wake 6:15, an 8-hour night.', }; return ( {collapsed ? ( ) : ( )} {/* Today's arc — trimmed in the collapsed/launcher view so the shelf shows */} {/* Module shelf — the launcher */}
{interactive && sheetOpen && ( setSheetOpen(false)}/> )} ); } window.Today = Today; // Compact on-scroll header: the big midnight hero has scrolled away; iOS // collapses it to a light blur title bar. The bedtime number persists as a // small pill so the signature metric never fully leaves Today. function TodayCollapsedNav({ metric = '10:30', metricUnit = 'PM', metricLabel = "Tonight's bedtime", grad }) { const tone = grad ? { background: grad } : undefined; return (
Today
Sun · Mar 16
L
); } window.TodayCollapsedNav = TodayCollapsedNav; // ── First-run / empty state ───────────────────────────────────── function TodayEmpty({ dark = false, tint = 'blue', palette, timeOfDay = 'Auto', onCreate }) { const grad = gradientFor(palette, timeOfDay); const greeting = greetingForTod(timeOfDay, 'Lukas'); return (
Nothing scheduled for today. Add an event below, or enjoy the free time.
); } window.TodayEmpty = TodayEmpty;