Standard controls: the audit and the target shape

"activities display not very pretty. are we using standard controls library? check all user interfaces and all apps if they use standard user interface components" — maintainer, 2026-09-16

The Governance activity page rendered its whole record — state, inputs, a gates table, the signatures, the log — as one markdown string built with a StringBuilder, wrapped the state in a hand-styled <span>-like pill with literal hex colours, and used ✅ ❌ ⏳ as the gate indicator. That is the shape the maintainer called not very pretty, and the audit below found it is the majority shape in this repo, not the exception.

What the audit measured

Count
Source/*.cs files that build UiControls (layout areas) 116
…that hit at least one of the four anti-patterns below ~101
Files using Skins.Card 0
Files using Controls.Badge 4
Files using Controls.DataGrid / ToDataGrid 15
Files using Controls.Html(...) 25
Files with a literal #rrggbb colour in a style 44

The four anti-patterns, each measured against the platform's own guidance (Badges, Icons & Status, DataGrid, Layout Areas, the /layout-area skill):

The target shape

Every page is composed from the platform's controls and nothing else:

Governance/Activity and Governance/Standard are the first two pages in this shape (#1981). Read them as the reference.

PR Module What moved
#1981 Governance Activity + Standard: badges, cards, grids, toolbar, texts per language
#1983 ten gallery pages the shared hand-rolled card line → Skins.Card; a Card example in DefaultViews
#1985 Essentials OperationRequest: state badge, facts, cards, toolbar, plain progress line
#1986 Hosting Issue, DeploymentStatus, TriageStatus (counts as an int-typed grid), TriageItem (facts, links, code-view logs)
#1987 Signature signers grid, card thumbnail, facts for the credential summaries, token colours, desk cards
#1988 Approvals token colours, toolbars, badge for the desk error
#1989 Providers the setup page as a card, an Invalid badge
#1990 MyAi source rows as cards
#1991 Training the tour's prose panel as a card
#1992 Feedback cards, category badge, status badges

Three lessons from the first pass, so the next one does not repeat them: a skin and the stack it wraps both bind the control's style — padding goes on an inner stack, never on the skinned one; a count column is PropertyColumnControl<int> — the grid deserializes each cell as the column's type and a string column over numbers throws per row; and a page whose tests read the direct area ids of a card (the Signature desk) needs those ids on the card's direct children, not on a nested content stack.

The remaining debt, per module

Letters are the anti-patterns above. A module is done when its line can be deleted.

Module Files Anti-patterns
AppleMaps Maps/Source/MapsAreas.cs, AmapsConnect.cs A, D
AppleMusic Music/Source/MusicAreas.cs, AmConnect.cs A, B, D
AppleWeather Weather/Source/WeatherAreas.cs, AwConnect.cs A, B, D
Chess GambitHunt/Source/GambitHuntLayoutAreas.cs, Game/Source/ChessGameLayoutAreas.cs, ChessBoardView.cs, ChessNativeBoard.cs B, C, D
Collaboration Review/Source/ReviewLayoutAreas.cs (13 Controls.Html sites) B, C, D
Cornerstone Article/Source/ArticleLayoutAreas.cs, Pricing/Source/PricingLayoutAreas.cs B
DataModelling DataModelExplorer/Source/DataModelExplorerLayoutAreas.cs, DataModelExplorerLogic.cs A
Edu CourseCatalog, LearningJourney, CourseInvite, Exercise, Quiz, Workbook, AnswerSheet layout areas A, B, C, D
Essentials Email/Source/EmailLayoutAreas.cs A, C, D
Google Account/Source/AccountAreas.cs, GoConnect.cs A, B, D
HomeAssistant Home/Source/HomeAreas.cs, HaConnect.cs A, B, D
Hosting 16 files — Admin, Backup, BackupStore, Build (2), ConfigAudit, Deployment, FleetConsole (3), InstanceAction (2), LogEntry, ModuleInventory, PlatformBuildInbox, RepoHealth A, C, D
ICloud Calendar/Source/CalendarAreas.cs, IcConnect.cs A, B, D
MyAi Panel/Source/AiSettingsAreas.cs — the ✅/❌ status messages D
Providers ProvidersApp/Source/ProviderSetupAreas.cs (status messages), ProviderSetup.cs (models as markdown rows) A, D
RemoteControl Console/Source/ConsoleAreas.cs, Screen/Source/ScreenLayoutAreas.cs A, B, D
RolePlay Character, Playroom (2), Scenery, Story layout areas A, B, C, D
Signature the transient action messages (RefreshMessage, the login status lines) D
Store Catalog (4), Plugin (3), Core (2), Coupon, Publishing, Installer (2), Maintenance (3) A, B, C, D

Not counted: the canvas and SVG renderers (DoublePendulum, FractalStars, ThreeBody), where Controls.Html carries a drawing rather than a layout; the Tests areas, whose pass/fail table is read by CI; and the package covers' hero blocks, which are pre-rendered rich text by design.

The clean references to align against, from the same audit: DefaultViews/Gallery, Analysis/Gallery (the only KpiStrip), Approvals/Approval, Publish/Deck, Edu/Module, Edu/Lesson, Essentials/Mailbox, Hosting/LogEntry.

How to re-run the audit

for p in 'Skins.Card' 'Controls.Badge' 'Controls.DataGrid' 'Controls.Html(' 'StringBuilder' \
         'border-radius' '#[0-9a-fA-F]\{6\}'; do
  printf '%4s  %s\n' "$(grep -rl --include='*.cs' -e "$p" --exclude-dir=src --exclude-dir=.worktrees \
      --exclude-dir=clients --exclude-dir=app --exclude-dir=e2e . | grep '/Source/' | wc -l)" "$p"
done

The per-file classification was a read of every one of the 116 layout-area files; re-read a module before deleting its line, the counts above only say where to look.

Reconnecting…
The server was updated. Reloading the page to pick up the latest version.