global.css defined its own fixed palette -- bg 0b1020, text e7ecff -- while
Wire UI surfaces follow the theme tokens. Switching to light turned the cards
light and left this text light with them, so the sign-in form rendered at a
contrast of about 1.1 and could not be read. The palette now derives from the
wire tokens, and the body wash is tinted from the primary token rather than a
fixed blue. Measured on the login form: light goes from 1.1 to 17.7, dark
stays at 18.2.
Anything an application hardcodes has to be themed as well, or it only ever
looks right in one mode.
The navigation tour is also reachable now: a Navigation entry in the site nav,
translated in both locales, and the page adopts the public layout so there is
a way back out of it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
examples/basic-app/app/pages/navigation.wrn puts all nine navigation
components in a single console shell instead of showing each alone: Navbar
with a nested dropdown, MegaMenu beside it, Breadcrumb, Sidebar as a rail that
becomes a Drawer, Tabs backed by a query parameter, a Stepper wizard,
Pagination, Scrollspy following the article, and Nav in the footer.
Three framework limits shaped the layout and are written into the page rather
than hidden:
- object props are held in state and bound, because a brace at the start of
an attribute is read as an interpolation
- a shared function on a page is compiled standalone and cannot see page
state by name, so state is passed as arguments
- component props and slot content render once and do not track page state,
so anything that has to react lives in page scope; Tabs reports the
selection and the page owns what is shown
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
DataTable replaces the 20-line Table scaffold entirely: columns, sorting,
filtering, pagination, selection, bulk actions, comparison layout, sticky
first column, custom HTML cells, and a remote source driven by a `request`
output rather than a function prop (props travel as HTML attributes, so a
function arrives as its own source text).
Toaster replaces the hand-rolled status div: tone icons, actions, hover
pause/resume and a progress bar.
Overlays audit -- Modal and Drawer declared aria-modal="true" but nothing
ever moved focus into the panel, so the @keydown handler on their root
never ran and closeOnEscape did nothing. Focus, focus restore, a Tab trap
and a body scroll lock now live in the reactive runtime, shared by both.
ContextMenu placed pointer menus by subtracting a guessed 340x420 from the
viewport, which pushed every menu that was not that size away from the
pointer; it now positions at the pointer and lets the anchored clamp pull
it back once it can be measured.
The reactive runtime size budget moves 150k -> 175k to cover anchored
overlays, dialog behaviour, the toaster and the DataTable client half.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>