A scheduling day

Built only from Alpenglow, nothing drawn beside it.

Width
Density
Mode

What it proves

  • The Scheduler and the Table on one state. The row current in the list is the card selected in the day, whichever side it was chosen on; the filters narrow both; a selection in the Table takes bulk actions; a drag in the day moves the appointment in both, and Undo puts it back.
  • The form in a dialog: New appointment, or a drag on an empty slot, with a Field, a Combobox, a Select and a DatePicker.
  • The empty state: every section but Today is an EmptyState with the way back.
  • Density on every control, row, hour and nav item. Compact takes a control from 40 to 32, a row from 72 to 48, an hour from 80 to 64 and a nav item from 40 to 32.
  • Both modes, each pair measured in light and dark:
    • the words, on the canvas, text/primary on surface/base — light 15.16AAA dark 18.12AAA
    • the secondary words, on a panel, text/secondary on surface/raised — light 12.28AAA dark 10.51AAA
    • the current row’s ring, on the table, 3:1, border/accent on surface/raised — light 5.96AA dark 7.18AAA
    • a primary button’s label, on the accent, interactive/on-accent on interactive/accent — light 5.96AA dark 7.73AAA
  • The targets in compact: controls 32 and nav items 32, both over WCAG 2.5.8’s 24. A row’s target is the button in its primary cell, the cell’s width and a line, 22, tall; it passes on the rule’s spacing, each one 48 from the next. Under a touch pointer compact gives the comfortable values back.

What moved up the list

What the screen could not be finished without, each with its commit.

  • System density. Five tokens in two modes, compact on any element and comfortable again under touch (34ab2ad); controls with no size take density/control and an explicit size keeps its height (10aec6f); the Table’s rows, the Scheduler’s hour and the side navigations’ items follow it (455785e, the items sized from their icon in 6423e2b).
  • The Table’s current row. The Scheduler selects one appointment and the Table has to show which row it is, apart from the multiple selection: currentId, aria-current and a ring (702370d), drawn in its final form as an inset outline on the row (6308409).
  • The Link’s new-tab announcement for an internal link. Open full screen is internal and opens a tab; the Link said so only for an external link, and now says it whenever it opens one (b6ac4ee).
  • The Table’s columns give way. It no longer becomes a list under 40rem: a column shrinks to its minimum and then leaves, the lowest priority first (8261f98); the row’s actions gather into “⋯” before any column does (b31c046). The screen says which of its columns stay, confirms from the row, and drops the meta line it had added (3e5ccbb).
  • The Button’s icon-only form. Square, the icon alone, its name required (1fcabc3).

Found, and not fixed in the package

  • The TopBar has no phone layout, though phone and tablet top bars are drawn.
  • In compact, a 30-minute card clips its time line.
  • Below 1280 the SideNav animates from 200 to 80 on load.
  • At desktop the first paint is the Tabs layout until hydration: useMediaQuery’s server snapshot.

Fixed since: the Scheduler’s column heads stand over their columns whatever the names’ length (2026-09-25; the screen keeps first names, since four of five full names would end in an ellipsis); the bulk bar keeps to one row in a narrow Table (2026-09-25); the SideNav’s narrow query and the screen’s own breakpoints are on the breakpoint scale (2026-09-24).

Composition

Zones
ZoneComponentsWhat it holds
NavigationSideNavA sheet under the narrow query
Top barTopBar, Button, AvatarThe day’s title, search, the account
Day barFilters, Badge, ButtonFilters that narrow both views
ScheduleScheduler, Field, Select, AvatarA column per practitioner
AppointmentsTable, Badge, ButtonThe current row, selection, bulk actions
Below 1280TabsThe schedule and the appointments as two views
DetailsDrawer, Badge, ButtonThe appointment that is current
New appointmentDialog, Field, Combobox, Select, DatePickerThe form, or a drag on an empty slot
CommandsCommandPalette⌘K, the day’s people and actions
FeedbackToastWhat changed, with Undo
Other sectionsEmptyStateEvery section but Today

18 package components, read from app/screen/ at build time: Avatar, Badge, Button, Combobox, CommandPalette, DatePicker, Dialog, Drawer, EmptyState, Field, Filters, Scheduler, Select, SideNav, Table, Tabs, Toast, TopBar.

Not checked: Safari, Firefox, a screen reader, a real touch device. The browser the screen was checked in emulates a mouse, so compact giving way to comfortable under a finger is held by a test on the stylesheet and has not been seen; nor was Esc on the New appointment dialog, which that browser’s keys do not always reach.