{calendar} shows a month. The month is the first parameter ('2026-10'); without it, the request value named by query (?month=2026-11) - the value the links to the month before and after set - and otherwise this month, by padNow, so padNowFreeze holds it still in a test. A month that cannot be read is an error under the strict check.

Written alone it answers a complete table: the month in the caption between links to its neighbours (keeping the other request values, as {pager} does), a column per weekday, a cell per day with its <time> and its events as a list. Today has aria-current="date". A small default look rides along under :where(), so the page's own CSS wins.

The events come from data= - a {data} store, a page array or a _data file. date names the field with the day and title the text; left out, the first field that reads as a date and the first other text field are taken. link makes an event's text a link.

Written as a pair it hands over the weeks as rows instead: $week (the ISO number) and days, in which every day is a row with $date, $day, $weekday, $month, $other (a day of the month before or after), $today, $weekend, $count, $class (other today weekend events, as they apply) and events, the data rows of that date. A store named events hides the day's field of that name - {level:events} reaches it then. For a whole year of values as coloured squares, see {chart 'calendar'}.