FluidIQ ops · 14 August 2026

One merged look, one menu

The menu structure is shipped and frozen — Home, Work, Reports, Admin, exactly as config/navigation.php defines it. Every page carries the same header markup, class for class, from the real layout. The only thing that varies is look and feel, which is the one decision waiting on you. They also all sit on one rebuilt type system, so the jumpy, crooked letterforms are gone in every one.

What is on the Home screen is a separate question and is not being decided here. The dashboard content below is stand-in — real components, invented numbers — there to exercise the type, density and colour. Pinned reports and a customisable widget grid are wanted and are parked deliberately: they change the schema, not the stylesheet.

The recommendation

Each card is a live, scaled render of the actual page. Click to open it full size — then hover or tab into the header, because the menus really open, with no JavaScript in the file.

Recommended D · Merged A's density, C's shape, B's dark craft — and a light/dark toggle in the header, which is what turns B from a third option into a mode. Row padding, type scale and button height are A's verbatim, because rows-per-screen is a cost you pay daily and air is a one-time impression. From C it takes the 12px radius and the soft long shadow instead of a hard rule — shape costs nothing in density. It deliberately leaves C's orange links (in a table where every row links, everything shouts) and C's second typeface. Orange marks one thing: the next action. Light + darkA's densityC's shapeOne accent

The three it came from

Kept for comparison. Each is roughly fifteen CSS variables over one shared stylesheet, one shared palette and one shared HTML file — which is why they look more alike than "three options" suggests.

A · Console Compact and quiet. Dense rows, tight radii, restrained ink, dark primary button. The most rows on a screen and the least decoration. LinearVercelDensest B · Midnight The same density, rendered dark — straight from the [data-theme="dark"] block already in tokens.css. Adds a lit top edge on cards and a halo on status dots, which is what stops dark cards reading as grey rectangles. Linear darkLow-glareNo new colour C · Studio Roomier. Bigger display type, more air per row, softer corners, orange links so the eye finds the next action. Reads as a document rather than an instrument — the honest trade is that fewer rows fit on a screen. StripeShopify adminSecond typeface
What D decided, and what is still yours. Density, radius, elevation and type scale are settings — D picks a combination, and any of them can move. The two genuine proposals both got answered: C's second typeface is out (Instrument Sans buys a magazine feel on a screen nobody admires, at the cost of another font file), and B's dark is a mode, not a default — the toggle follows your OS until you touch it, then remembers. Everything draws its colour from tokens.css and nowhere else — those values already passed contrast and colour-blindness validation, and no mockup here introduces a hex code.

What each page proves, not just shows

Scroll to the bottom of any option. Five behaviours are reproduced live, because a still image can hide every one of them.

The crooked letters — cause and fix

Left is the live app's type, reproduced from its own declarations. Right is what all three mockups use. This part lands whichever letter you pick.

Today — ops.css

Spend, month to date

412.68

Needs a person today

Merchant Center sweep · biweekly · 3 disapprovals outstanding

font-weight: 650 and 550 are not real weights in this stack, so the browser fakes them by smearing every glyph sideways. 11.5px and 12.5px put letter edges on half-pixels. And ops.css sets its own stack on body, overriding --font from tokens.css — so half the app renders in a different face than the other half.

The mockups

Spend, month to date

412.68

Needs a person today

Merchant Center sweep · biweekly · 3 disapprovals outstanding

A real variable font (Inter, 100–900 continuous), so 450 and 550 are drawn rather than faked. font-synthesis: none makes faking impossible going forward. Integer sizes on a fixed scale. One stack, defined once. tabular-nums so digits line up column to column. Letter-spacing is a function of size — tight on headings, open on small caps.

Two more things fixed in all three

Independent of the look you choose.

Picking

Open D, hit the toggle in the header a few times, and say yes or name the one thing that is wrong. Individual values still move — rows tighter, radius softer, the accent somewhere else — without disturbing anything around them, because each is a single variable in assets/option-d.css.

D ports across as one step: the class names are already the shipped ones (app-menu, app-menu-pop, app-menu-heading, app-account, is-current), so nothing has to be re-typed. Re-run python3 docs/_reference/mockups/build.py after any menu change and every page follows config/navigation.php automatically.

One honest note on the script. A, B and C contain no JavaScript at all, and D's header, menus and phone drawer are still pure CSS — that is the property that proves the Blade layout works with script off. D adds about twenty inline lines, for the theme toggle and nothing else. It runs before the body so a stored choice paints with the first frame; a theme read after render flashes the wrong colours on every page load.