The calendar is not a standalone component. It is the popover half of the date picker — a 280px panel that opens under a read-only input. One implementation ships, and its title button cycles the panel through three views: day → month → year.
The three views
Clicking the title moves out one level; picking a value moves back in. The header arrows step by one month, one year, or twelve years depending on the view.
Su
Mo
Tu
We
Th
Fr
Sa
Specs
| Part | Value |
|---|---|
| Panel | width 280px · radius 16px · padding 16px · #fff on 1px #E9EAEC · shadow 0 10px 30px rgba(0,0,0,.12) |
| Position | absolute · left 0 · margin-top 8px below the input · z-index 50 |
| Header | margin-bottom 12px · justify-content: space-between |
| Arrows | padding 6px · radius 8px · 16×16 lucide chevrons · hover #F9FAFB |
| Title | 13px / 600 · padding 4px 8px · radius 8px · hover #F9FAFB · clickable |
| Weekday row | 7 columns · gap 4px · margin-bottom 4px · 10px / 600 centred · #6B7280 |
| Day cell | height 30px · 12px · radius 8px · gap 4px |
| Month / year cell | height 40px · 12px · 3 columns · gap 8px |
Cell states
One function styles every cell in all three views, so a selected month looks exactly like a selected day.
| State | Fill | Text | Weight | Border |
|---|---|---|---|---|
| Rest | Transparent | #1F2937 | 500 | 1px transparent |
| Hover | #F9FAFB | #1F2937 | 500 | 1px transparent |
| Today | Transparent | #A855F7 | 700 | 1px rgba(168,85,247,.45) |
| Selected | Brand gradient | #fff | 700 | 1px transparent |
Today is #A855F7, not #A614C3. That value is hard-coded and does not change between light and dark mode — it is the only place in the product where the dark-mode purple appears on a light surface. Treat it as the today marker’s own colour, not as the brand accent. |
| Today and selected are mutually exclusive: once a date is selected the today ring is suppressed on that cell, so a cell never carries both. |
| There is no range selection, no multi-date selection, no disabled days, no min/max and no footer. A click commits the value and closes the panel. |
Leading blanks are empty <div>s, not greyed-out days from the previous month. |