Give the composer full-width desktop space before the event timeline so capture stays prominent and the toolbar can keep its intended two-column composition. Add source-level regression tests to lock the new page hierarchy in place.
Replace the deprecated callModel / getText pattern with the chat.send
method and extract the response content via extractContentFromChatResponse.
This aligns with the current OpenRouter SDK interface.
Replace the button-only trigger with a native <input type="date"> (or
datetime-local when not all-day) paired with an icon button that opens
the calendar popover. This gives users direct keyboard entry while
keeping the rich calendar + quick-shortcut picker accessible.
- Add getInputValue helper to format the current value for the native
input.
- Import the Input component.
- Restructure the layout to place the input and popover trigger
side-by-side.
- Change input group horizontal padding from px-3 to pl-3 pr-2 to
better accommodate the trigger button.
- Add shrink-0 to the trigger button so it does not collapse in flex
layouts.
- Mark the Clock icon with aria-hidden to keep it out of the
accessibility tree.
- Forward the className prop in TimePickerSeparator and apply default
muted-foreground text styling.
Add [&::-moz-focus-inner]:border-0 and [&::-moz-focus-inner]:p-0 to
the base buttonVariants to prevent the extra inner dotted outline and
padding that Firefox renders on focused buttons.
- Updated OpenRouter integration to accept an array of image URLs
- Updated ImagePicker to use the `multiple` attribute natively
- Added `appendImagesDeduped` for handling client-side image deduplication
- Enhanced clipboard pasting to extract multiple images at once
- Rendered multiple images in a horizontal thumbnail strip in the AIToolbar
- Added tests to cover multi-image logic and AI request mapping
- Split composer into AI zone (primary accent) and data actions zone (neutral)
- Move Attach/Generate to labeled footer bar below textarea (left/right aligned)
- Add info icon with HoverCard (hover preview) + Popover (pinned click) showing identical keyboard shortcuts content using shadcn HoverCard to fix theme inconsistency vs Tooltip
- Expose imperative triggerRef on ImagePicker for keyboard shortcut access
- Wire TooltipProvider in root layout; install shadcn kbd and hover-card
- Unauthenticated state shows locked CTA with real sign-in button weight
- Add behavioral contract tests for footer bar, info trigger, and zone layout
Replace px-0 py-0 override with px-3 py-1 so placeholder text is
never flush against the edge. The ::placeholder pseudo-element
inherits box padding from the textarea; zeroing it out removed all
visual breathing room for the hint text.
Also adds tests/textarea.test.ts that locks down this behaviour via
class-string assertions on the resolved cn() output.
- Add popover shadcn component (radix-ui based)
- Create DateTimePicker component: Calendar popover for date + hour/minute
selects for time, allDay-aware, emits ISO / YYYY-MM-DD strings
- Replace datetime-local / date <Input> fields in EventDialog with DateTimePicker
- Remove unused CalendarIcon and Clock imports from event-dialog
- Add event action props (events, onAddEvent, onImport, onExport, onClearAll)
- Show skeleton loading state while session is pending
- Render event action buttons (Add, Import, Export, Clear) in action bar
- Add AnimatePresence for image preview attach/remove
- Replace Card summary panel with animated glass-card panel
- Inline AI Summarize button into action bar when authenticated
- Add Sparkles icon to AI command section header
- Apply glass-strong to DialogContent
- Add LucideMapPin and CalendarIcon/Clock icons to input fields
- Replace native checkbox with Checkbox + Label component
- Unify allDay date inputs into single relative-positioned blocks
- Add Cancel button to DialogFooter
- Rename Save to Create for new events
- Wrap card in motion.div with layout/enter/exit animations
- Replace Card/CardHeader/CardContent with flat glass-card div
- Add hover-reveal action menu with opacity transition
- Improve date formatting with locale options for month/day/time
- Show end time inline next to start
- Add ExternalLink for event URLs
- Add icons to dropdown menu items with DropdownMenuSeparator
- Replace Magra with Geist Mono font
- Rename font variables to geistSans/geistMono
- Apply both font variables to body
- Redesign sticky header with glass-strong and CalendarDays icon
- Wrap main content in max-w-4xl centered container
- Add glass-strong className to Toaster
- Default theme changed to dark
- Replace warm/mixed color palette with clean cool blue-grey tokens
- Reduce border-radius from 1.25rem to 0.75rem
- Rewrite shadow system using oklch with proper depth scale
- Switch fonts from custom serif/sans to Geist Sans/Mono CSS vars
- Add CSS animation keyframes (fade-in, slide-up, slide-down, scale-in)
- Add glass, glass-card, and glass-strong utility classes
- add DialogDescription (sr-only) to EventDialog to satisfy Radix UI
aria-describedby requirement and silence the React console warning
- add htmlFor/id pairing to the all-day checkbox label in EventDialog
- add id and name attributes to all raw form fields (textarea, checkbox)
in event-dialog to resolve biome a11y lint warnings (4 fields fixed)
- add name attribute to hidden file inputs in image-picker and ics-file-picker
- generate public/icon-192x192.png and public/icon-512x512.png so the PWA
manifest no longer returns 404 for the app icons
- add normalizeAiDateString() to coerce bare ISO datetimes, date-only
strings, and fractional-second variants into offset-aware format
- apply via z.preprocess in AiEventResponseItemSchema so Zod validation
no longer rejects AI responses missing a timezone offset
- fix system prompt to use toISOString() (unambiguous UTC) and clarify
expected datetime format for the AI model
- install bun-types and add to tsconfig so bun:test resolves cleanly
- add 8 behaviour-driven tests covering all normalizer edge cases
Replace manually duplicated variant/size type literals with
VariantProps<typeof buttonVariants> for type safety and
consistency with the Button component.
Add unoptimized prop to image preview to support blob URLs, contain
overflow on preview container, replace div with semantic section
element in DragDropContainer with aria-label, and import shared
image constants.
Break down the monolithic handleAiCreate into focused helpers
(sendAiRequest, persistAiEvents, populateEventForm), add client-side
image file validation before upload, and use toast.promise finally
callback for loading state cleanup.
Replace inline JSON extraction with the shared json-utils module,
extract chat response content parsing into a dedicated helper, make
the AI model configurable via AI_MODEL env var, and improve error
messages for production safety.
Add regex-based data URL validation for images, compute binary size
from base64 for accurate 10MB limit, enforce datetime strings with
offset for start/end fields, and derive CalendarEvent from the AI
response item type to eliminate field duplication.
Move image extensions, MIME types, and size limit into a dedicated
constants module. Extract JSON-from-text parsing into a pure utility
function for reuse across the codebase.