A month on a plate. The month and year sit on two drums behind a window and roll when you page; the chosen day is a latched cap, a range is a groove cut between two caps, and events are lamps named in the line below.
The grid is a role="grid" table labelled by the drum window, which reads the month and year and is a polite live region: paging says “October 2026”.
One day holds the tab stop; arrows move it. Each day is named in full (“Thursday 17 September 2026, Tracking · Room 2, Clash: two bookings”), with “today” and “unavailable” where true.
Chosen days carry aria-selected="true", today aria-current="date". Chosen is also the contrast cap and a heavier figure, not only a colour.
Every lamp has its words: in the day’s name, and printed in the line under the grid for the day in focus.
The page keys name where they go (“Next month, October 2026”) and are disabled past min and max.
06
How it’s built
A custom element that builds its own light DOM: a head with two small keys and the drum window, a role="grid" table of six weeks (blank cells before the 1st and after the last, so the plate never changes height), and the note line. Dates are whole days since 1970 in UTC, so no time zone can move one. Each drum is a strip of three faces (last, this and next) in a recess, shaded like a cylinder; paging re-prints the strip one face off and animates it back with the Web Animations API over 220ms (zero under reduced motion), so the old month rolls away and the new one comes round. The chosen day takes the contrast cap and the pressed shadow; a range’s groove is a ::before strip of the well under the days, half-width under its two caps.
07
Rules
calendar.rules.mdIn the brain
Lamps mark the days; the words live in the markup and in the line under the grid.
5 rules in this file, with the foundations they rest on and the anti-patterns that break them. Full rules ship in the brain with the Pass.
A date field with its calendar card in a slot underneath: type a date in any common form for your locale, or press the key and the card slides out. Single dates and ranges; shown the Intl way, posted as ISO.
The only colour in the kit: a lamp that is on. Green is on, amber is waiting, red is recording or failing, blue is linked, white is standing by. Always next to words.