A scheduling day
Built only from Alpenglow, nothing drawn beside it.
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/primaryonsurface/base— light 15.16AAA dark 18.12AAA - the secondary words, on a panel,
text/secondaryonsurface/raised— light 12.28AAA dark 10.51AAA - the current row’s ring, on the table, 3:1,
border/accentonsurface/raised— light 5.96AA dark 7.18AAA - a primary button’s label, on the accent,
interactive/on-accentoninteractive/accent— light 5.96AA dark 7.73AAA
- the words, on the canvas,
- 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 takedensity/controland 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 in6423e2b). - 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-currentand 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
| Zone | Components | What it holds |
|---|---|---|
| Navigation | SideNav | A sheet under the narrow query |
| Top bar | TopBar, Button, Avatar | The day’s title, search, the account |
| Day bar | Filters, Badge, Button | Filters that narrow both views |
| Schedule | Scheduler, Field, Select, Avatar | A column per practitioner |
| Appointments | Table, Badge, Button | The current row, selection, bulk actions |
| Below 1280 | Tabs | The schedule and the appointments as two views |
| Details | Drawer, Badge, Button | The appointment that is current |
| New appointment | Dialog, Field, Combobox, Select, DatePicker | The form, or a drag on an empty slot |
| Commands | CommandPalette | ⌘K, the day’s people and actions |
| Feedback | Toast | What changed, with Undo |
| Other sections | EmptyState | Every 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.