Skip to content

improve(LINCHPIN-5644): Inset the screen once, recolour the default brand and fix menu icons - #12

Merged
aaronware merged 3 commits into
mainfrom
issue/LINCHPIN-5644-chrome-polish
Sep 21, 2026
Merged

aaronware merged 3 commits into
mainfrom
issue/LINCHPIN-5644-chrome-polish

Conversation

@aaronware

Copy link
Copy Markdown
Contributor

Three QA findings from the run-up to 1.0.0, one commit each.

LINCHPIN-5644 — Chrome cleanup: full-width layout, spacing, brand lockdown and DangerZone

Inset the screen once

The shell padded 12px outside core's Page, which pads its own header and body by 24px inline, so every edge was inset twice: a title 36px from the frame while the bar's mark above it sat at 12px, a band of admin grey between the bar and the panel, and the same doubled inset either side of the cards.

One inset now — --lp-admin-gutter, which is core's --wpds-dimension-padding-lg (16px), the same measure Page already leaves above and below. The panel runs edge to edge under the brand bar, and the bar, the panel, the body's column gap and the footer all meet their edges at 16px. Measured at 1440px: left and right insets 36 → 16, bar-to-panel 12 → 0, column gap 24 → 16.

Blue bar, black ink

primary (the design system seed) and deep (the bar) have swapped, so the chrome shows both agency colours instead of spending one on every button. Buttons, the selected menu row, the tab indicator and the links below the bar are now Linchpin black; the bar is Linchpin blue.

That makes the bar light, so its ink became a brand property of its own, --lp-brand-on-brand. A brand that colours the bar and names no ink has it measured against both gradient stops, so a plugin with a pale bar is given black rather than discovering 1.5:1 text in QA. Psst and Mantle, both dark, still resolve white.

Linchpin's own bar keeps white at 2.15:1, deliberately — the bar carries the two marks and a version badge, all heavy enough to hold it, and the white lockup is how we sign our work. It is written into DEFAULTS as a decision so the measurement stays intact for brands that have not made one.

Menu icons

LinchpinAdminNav has always taken an icon per item and Mantle has always passed one, and none of them were visible: an @wordpress/icons export is a bare <svg viewBox> with no width, which resolves to zero in a flex row. They now go through core's <Icon> in a 24px box, fitted rather than stretched, still inheriting the row's colour so the selected row inverts.

Verification

Storybook at 1440px and 760px across the Psst, Mantle and branded stories; geometry and contrast read out of the live DOM (primary button 15.27:1, selected row 12.15:1, icon box 24×24). lint:js, lint:css, verify:esm clean, 82 tests pass, and each commit passes on its own.

…once

The shell padded 12px outside core's `Page`, which pads its own header and
body by 24px inline. Every edge of a screen was therefore inset twice: a
title sat 36px from the frame while the plugin's mark in the bar above it
sat at 12px, a band of admin grey ran between the bar and the panel's top
edge, and the cards carried the same doubled inset on both sides.

There is now one inset, `--lp-admin-gutter`, and it is core's own
`--wpds-dimension-padding-lg` — the 16px `Page` already leaves above and
below its header and body, so the horizontal inset is the same measure as
the vertical one rather than a number of ours sitting beside core's. The
shell pads nothing, the panel runs edge to edge under the brand bar, and the
bar, the panel and the footer all meet their edges at the same 16px. The
body grid takes it as its column gap too, so a card's distance to its
neighbour is its distance to the edge.

Two details worth knowing. Core injects `.content.has-padding` into the head
at runtime, after our stylesheet, so the override matches two attributes to
win a tie it would otherwise lose on order. And a screen that composes the
layout outside the page — Mantle, with its menu beside the panel — has no
panel against those edges, so the body takes the gutter itself there.
…lack

The default brand carried Linchpin blue as the design system seed on a
Linchpin black bar, which showed one agency colour in the chrome and spent
the other on every button. Swapping them shows both, each doing the job it
is for: the bar is the colour people recognise us by, and a banner is where
a brand colour belongs, while `primary` is ink, so the buttons, the selected
menu row, the tab indicator and the links beneath the bar are black rather
than a second helping of the same cyan competing with it. Linchpin black is
a very dark teal, so the design system's pale brand tints still land in the
blue family and the sidebar still reads as ours.

That makes the bar light, and white on Linchpin blue is 2.15:1. The bar's
ink is therefore a brand property of its own, `--lp-brand-on-brand`, rather
than the agency palette's white: a brand that colours the bar and says
nothing about the ink now has it measured against both gradient stops, so a
plugin with a pale bar is given black instead of finding 1.5:1 text in QA.
The palette's `--lp-color-on-brand` stays white, where the logo tones want
it.

Linchpin's own bar keeps white regardless, named in DEFAULTS rather than
measured. The agency has looked at 2.15:1 and kept it: the bar carries the
two marks and a version badge, all heavy enough to hold the colour, and the
white lockup is how Linchpin signs its work. Writing it as a decision leaves
the measurement intact for every brand that has not made one.
…ir own

The menu has always taken an `icon` per item, and Mantle has always passed
one. None of them were visible. An `@wordpress/icons` export is a bare
`<svg viewBox>` with no width or height, and in a flex row that resolves to
no width at all, so the menu rendered seven icons of zero pixels and read as
a feature that did not exist.

Icons now go through core's `<Icon>`, which normalises the three forms a
plugin might have — an icons export, a component of its own, a dashicon name
— and sizes what it can. The row also gives the icon a 24px box of its own,
for artwork `<Icon>` cannot size, and the SVG fits itself to that box rather
than stretching, so a mark that is not square is letterboxed instead of
squashed. Fill still inherits, so the selected row gets an inverted icon
without being told.
@aaronware
aaronware merged commit 62c072b into main Sep 21, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant