Brief #4, fluent-2. A ward team inside Teams. The night team hands Ward 7 to the day team at 07:00, and this is the screen both of them stand at while it happens.
The four direction lines
- Archetype: shell. A persistent rail, a top bar and one content well, for a team that returns to the same place every twelve hours.
- Data stance: tile-first. Four tiles, and each one states its change since the 19:00 handover. A number with nothing to compare it against does not go up there.
- Density: compact. 32px controls, 24px controls inside a thread entry, the 4px spacing grid,
body1at 14px. - The one bold thing: the handover thread holds the primary column and the tiles are the secondary surface. The words a nurse writes at 06:52 outrank every count on the screen.
What the critique round changed
The inversion was asserted and not composed. h1 and .metric-value were both fontSizeHero700, so four 28px figures stood against one 28px heading while the primary column's own h2 sat at 16px: the tiles were the headline. The figure came down to fontSizeBase600, the thread's heading went up to fontSizeBase500, and below 640px, where the title itself drops to 24px, the figure drops again to 20px so the heading is the largest thing on the screen at every width. On a phone the four tiles had also stacked into 474px of numbers between the title and the first word anybody wrote; they are two columns there now and the thread starts on the first screen.
Five behaviours were wrong rather than missing. Sign off as read — the only control drawn as primary, and the act the screen exists for — did nothing. A posted entry took its time from the reader's clock, so it landed at 02:21 under an entry timed 07:02 in a column whose whole meaning is the order. 14 entries since 19:00 never moved: not when the filter hid twelve of them, not when somebody posted a fifteenth. Posting under Escalations only left the new routine entry on screen with the filter still pressed. And the ward and category menus carry role="menu", which is a promise about the arrow keys that only Escape was keeping.
The second state
The entry that did not send. A day charge nurse types the one thing with a clock on it, a repeat sample the theatre slot depends on, and the post fails. It sits in the thread where she wrote it, marked as reaching nobody, with two ways out: send it again, or move it back to the box she wrote it in. Both are live on the page. The composer's empty-submit validation is live too.
Generator
fluent_theme.py --mode both
tokens.css is that output, unedited. The audit acted on:
fluent_theme.py --contrast --mode dark
which passes every required pair and reports colorNeutralStroke1 at 2.53:1 as a decorative divider. The page draws no hairline at all: the composer separates from the thread by receding one neutral layer instead. Every control boundary reads colorNeutralStrokeAccessible.
Measured contrast
Read out of the rendered page with getComputedStyle, and confirmed with contrast.py:
colorNeutralForeground1oncolorNeutralBackground1, the thread body at 14px: 15.52:1 light, 14.55:1 dark, against a 4.5:1 minimum.colorNeutralForeground3oncolorNeutralBackground1, times and roles at 12px: 6.19:1 light, 6.48:1 dark, against a 4.5:1 minimum.colorPaletteRedForeground1oncolorNeutralBackground1, the adverse comparison: 5.85:1 light, 5.20:1 dark, against a 4.5:1 minimum.colorPaletteDarkOrangeForeground1oncolorNeutralBackground1, the warning comparison: 5.45:1 light, 5.45:1 dark, against a 4.5:1 minimum.colorNeutralForeground1oncolorNeutralBackground1Selected, the selected rail item and its count: 13.02:1 light, 11.73:1 dark, against a 4.5:1 minimum.colorNeutralForeground2BrandSelectedsat here first and measured 4.18:1 in dark at both 14px and 12px. The filled icon, thecolorBrandStroke1indicator and the selected background already mark the selection, which is what Fluent asks for, so the brand did not need to sit in the text as well.
The lever spent against the neighbouring index
direction_check.py --compare put Rota and Carbon's Grid North at 0.83 against a 0.75 ceiling. The lever is elevation, which is the one structural language Carbon has no word for: it rules its regions and forbids shadows, while Fluent layers colorNeutralBackground1 through 6 and lifts what floats. So the thread surface lifts off the canvas on shadow2 and borderRadiusLarge, the four tiles stay flat on the canvas, and the composer recedes to colorNeutralBackground2 inside the lifted surface, which is what let the last decorative hairline go. The elevation now carries the bold thing: the primary column is the only region on the page that lifts. The pair reports 0.67, distinct, and Rota's highest similarity against any of the other eighteen pages is 0.59.
Deviations
- The page authors three widths rather than reading them from a token: a 208px rail, a 320px side column and a 1300px cap on the well. Fluent tokenizes no layout grid, since a Fluent surface lives inside a host whose width it does not control. Without the cap a 1920px screen gave the thread surface 1324px to carry a 68ch measure, so two thirds of the primary column was empty on every entry.
- The composer sits at
fontSizeBase400(16px) where the rest of the page is compact at 14px. Fluent gives 16px to text somebody writes rather than scans, and it keeps iOS from zooming the field on focus.