Tangible · design scarecrow · hub
The Hub, and its mark on the bar
One landing page for everything Tangible on a site — installed plugins with their
licence truth, recent releases pulled from tangible.one, and the notification
channel that exists so we never have to post an admin notice again. Plus the
admin-bar entry that gets people there, drawn into a real, crowded bar rather
than an empty one.
§1 · The admin-bar mark, in the bar it will actually live in
This bar is transcribed from a live client site: pending updates, Yoast with its
red pill, a stats sparkline, UpdraftPlus, and Jetpack Safe Mode in shouting
orange. Our mark is the six-tile logo, monochrome at rest — the bar's own
grey — with the count as an inline pill in the bar's existing vocabulary.
The badge is inline, not superscript
"Top right or some such" was the ask; the bar answers it. A 32px strip has no
corner to superscript into — Yoast, the precedent on this very bar, sets its
count as an inline pill after the icon. We follow the native convention rather
than invent one, including the red: the pill is the bar's vocabulary for
"unread count", so it stays #d63638. The brand moment is
the six-tile mark, not the number.
Discretion rules
Monochrome at rest (tiles take the bar's grey; purple only on hover). No pill at
zero. Count caps at 9+. No dropdown in v1 — click goes to
the Hub, one navigation, no hover panel to misfire on touch. And the mark never
appears on the right side of the spacer: that half belongs to the user
(account, Howdy), and squatting there is Jetpack behaviour.
What counts as unread
Only notification-centre items (§2 rail) increment the pill. Available updates
do NOT — WordPress already counts those at ⟳, and double-counting them is how
a badge becomes wallpaper. The pill is backed by the same read/dismissed state
as the rail, so clearing one clears the other.
§2 · The Hub page, at real width
Under the shared Tangible top-level menu the v3 framework already creates —
the hub is its missing landing page. Structure follows the host accent
(--wp-admin-theme-color); the purples do marks and data, the
House dial unchanged.
The table tells licence truth quietly
Tile-dot in mark-purple = valid; salmon = attention (the screen's one coral,
spent here). "Renews in 14 days" is stated as a fact with a date, not an urgency
banner — the renewal notice in the rail carries the action. Free products
say so plainly instead of showing an empty licence field.
Setup resumes from here
The dashed resume chip is the onboarding re-entry point the
playbook found on every plugin studied (LearnDash's pointer, MonsterInsights'
permanent checklist tab). The wizard is one-shot nowhere: the Hub row is its
permanent doorway, drawn in the same dashed idiom the wizard's rail uses for
skipped steps.
Notifications = the campaign channel
The rail is the wp-admin client of the campaign builder — same registry,
same formats, delivered here instead of as admin notices. Popup Maker's
notification centre is the precedent; ours differs in that the content is
authored in the campaign builder we already ship, not a second CMS.
§3 · Why the Tangible menu, not Settings or Tools
The Tangible menu — chosen
The v3 framework already creates the shared top-level and every plugin already
registers into it; get_admin_menus() even enumerates the
registrations — the plugins table above is that call, rendered. The top level
currently lands on an arbitrary first submenu; the Hub is the landing page it
has been missing. Cost: zero new chrome, one position
argument.
Settings — rejected
Each plugin's settings page already lives under Settings → {plugin}, and the
Hub is deliberately not settings — it holds no forms, saves no options,
and reads licence facts it does not own. Putting a read-mostly dashboard in
Settings teaches people to look for controls that are not there.
Tools — rejected
Tools is where WordPress puts things nobody visits twice (Site Health aside).
A page whose job includes surfacing notifications cannot live somewhere with
zero organic traffic — it would depend entirely on the bar badge for
discovery, making the badge louder than it should be.
§4 · Every region maps to a store that exists
Installed plugins
framework::$state->plugins (name, title, version, urls) joined
with updater\get_license_status() per plugin. The Hub renders
licence facts, never owns them — same seam as the settings-page licence field.
Releases
tangible.one's release records (the same rows the publishing pipeline upserts
per asset·channel·version), filtered to installed products, cached with a lazy
TTL. The one-liner is authored at publish time — it is the changelog's first
line, not marketing copy.
Notifications + badge
Campaign channel API, keyed by the licence's account; read/dismissed state
stored per-site via the framework's option plumbing (per-user is a known,
deliberate cut). The bar badge counts exactly this list — nothing else feeds
it.
Agency mode mutes all of it
On an agency-managed site (account-level flag): no bar mark, no renewal
notices, no releases feed, no marketing campaigns — the menu keeps only each
plugin's functional pages. The Hub is a customer surface, and the person in
this admin is not the customer.
scarecrow · not a spec — settles look, placement and data seams for the Hub landing page + admin-bar mark ·
house dial from /plugin-onboarding-e · six-tile mark geometry from OnboardingFrame.tsx ·
bar transcribed from a live client site screenshot, 2026-08-27