Theming and density
This page documents the Orleans.Lattice.Explorer packages, which are in progress, in the documentation for Orleans.Lattice 9.9.0 (release line 9.9), built 2026-10-04. It is also published as markdown, with every table and list, at theming-and-density.md, and llms.txt lists every page.The Explorer draws in the documentation site's visual world and adds an operator-console layer for density, focus, state roles, and app frames. Appearance is made of three choices: theme, contrast, and density.
Theme
The theme choice is the material:
- System follows
prefers-color-scheme. - Paper stores and applies
light. - Board stores and applies
dark.
The active material is applied to the document element as data-bs-theme="light" or data-bs-theme="dark". The system choice resolves to one of those values for rendering, and the chrome listens for operating-system colour-scheme changes while System is selected.
Contrast
The contrast axis has three choices:
- System leaves
data-lt-contrastunset and lets CSS followprefers-contrast: more. - Standard writes
data-lt-contrast="standard"and opts out of the system high-contrast overlay. - More writes
data-lt-contrast="more"and applies the high-contrast overlay.
The high-contrast overlay is not a label-only duplicate. Its tokens target 7:1 text contrast and 4.5:1 non-text contrast on Paper and Board.
Density
Density changes row and control heights without changing the address or the data being read.
- Comfortable is the default. Rows and controls are 44px, so ordinary actions are touch targets.
- Compact sets
data-lt-density="compact". Rows and controls are 28px, still above the 24px WCAG 2.2 minimum target size.
When comfortable is selected the density attribute is removed, so the default CSS tokens apply.
Fields and toolbars
Every field - a text box, a name box, a picker, a multi-value picker, a select, a search box, a date and time field or a duration field - is a visible label row over a control box. The label row is one line, and the control box is one control height (44px comfortable, 28px compact) with the same border, fill and padding in Paper and Board, so fields of every kind line up beside each other. A search box's label is visible like any other and is its accessible name.
A toolbar lines its controls up on their control boxes. In a toolbar that holds a labelled field, a button, a segmented choice, a switch, a checkbox or a count starts one label row down, on the control row; a field's hint or error grows the field downwards without moving a control. Below 768px a toolbar stacks one item per line. A placeholder is always prose in the interface face, even in a field whose value is an id in the monospace face.
DESIGN.md (Fields and toolbars) holds the rule and names the tests that enforce it.
Dates, times and durations
A field that takes a point in time is never a bare text box. The date and time field is one control box holding the instant, typed or shown as ISO 8601 to the second (2026-09-28T14:05:00Z), the zone it is in, and a calendar button. The zone is always UTC and always written in the box. A typed time that names another offset is read as the instant it names and rewritten in UTC in the box, so nothing is converted silently. Once the page is interactive, the reader's own local time is shown under the box as secondary text. A field may allow an empty value, whose meaning (such as Latest) is its placeholder, and it may refuse times before a minimum, after a maximum, or in the future, with the reason shown under the box.
The calendar button opens a picker below the field, or in the flow of the page on a phone. It has quick picks (Now, 1 hour ago, 24 hours ago, 7 days ago; one outside the field's range is disabled), a month grid starting on Monday, a time to the second in UTC, and Done (with Clear when the field may be empty). In the grid the arrow keys move by a day or a week, Page Up and Page Down by a month (with Shift, by a year), and Home and End to the start and end of the week. Escape closes the picker and returns focus to its button.
A field that takes a duration has a whole-number box for each unit it offers - days, hours, minutes or seconds - in one control box, each named by the field and its unit. A box that is not a whole number, or a total outside the field's range, is refused with the reason shown under the box. ShellTimeFieldHygieneTests fails the build when a field whose label, hint or placeholder names a date, a time, UTC, ISO or a duration is drawn as a plain text box.
First paint and document attributes
A classic blocking script in the document head reads the small appearance record orleans.lattice.explorer.appearance.v2 from local storage. It accepts only shipped names, resolves System against the operating system, and sets these attributes before the first paint:
data-bs-themedata-lt-contrastdata-lt-density
This avoids a flash of the wrong material. The script is only a paint helper; after startup, the app restores the declared preference keys and applies appearance through the chrome module.
Appearance menu and commands
The header appearance menu renders one toggle button per choice. Each button carries the same data-lt-command id as the command palette command that performs the action:
appearance.theme.systemappearance.theme.paperappearance.theme.boardappearance.contrast.systemappearance.contrast.standardappearance.contrast.moreappearance.density.comfortableappearance.density.compact
The menu state uses pressed buttons, so the visible control and the palette are two entries to the same action, not separate behaviours.
Reduced motion
The design layer respects prefers-reduced-motion: reduce by reducing transition and animation durations to 0.01ms and limiting animation iteration to one. This is a global rule for the Explorer UI.
Lattice App frames receive appearance through the app-frame protocol. The bundle and context.read include { theme, contrast, density, reducedMotion }, and the protocol lets a host notify a running frame with context.changed carrying the same closed set. The frame vocabulary is Paper or Board, standard or more contrast, comfortable or compact density, and a reduced-motion boolean. The web head does not yet pass the console's own appearance on: every frame is given the fallback appearance - Paper, standard contrast, comfortable density and full motion - whatever theme, contrast, density or motion preference the console is using, and no context.changed is sent when they change.