Standardize central content width on /settings/personalization and /operator/aiconfig #71
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Depends on #70 (the personalization page must exist at its new path first; the /operator/aiconfig half is independent).
What
The central content column width on two pages does not match the product's standard:
http://192.168.31.41:5173/settings/personalizationandhttp://192.168.31.41:5173/operator/aiconfighttp://192.168.31.41:5173/operator/applicationsandhttp://192.168.31.41:5173/operator/usersMake the two offenders render at exactly the same content width, padding and max-width behaviour
as the standard pages, desktop and mobile.
Scope hints
<Page>fromdashboard/src/lib/components/Page.sveltefor breadcrumb routes, plus the shared list/detaillayout the machines/groups/sources pages reuse — see "Recurring dashboard mistakes" in
AGENTS.mdand the split-list row rules inDESIGN.md).existing standard structure, not to tune numbers until it looks right.
aiconfigarrived in #38 and personalization in #46 — both likely hand-rolled their pagewrapper instead of reusing the standard one.
floating 16px);
min-w-0/overflow-autorules for scrolling columns.Gates
Dashboard
bun run test+bun run check; if a UC describes these pages' layout, update it andkeep
_check.pygreen. One commit per page if they diverge,Refs #<N>, no closing keywords.Visual proof: describe the before/after width source (which component/CSS decides it) in the
issue comment — a claim without the responsible line of code is not done.
Claimed — branch
issue/71-content-width. Doing: adopt the standard<Page>content-width chrome on/operator/aiconfig(personalization half deferred to #70 follow-up).Issue #71 — standardize aiconfig content width (personalization half deferred)
Restated goal
/operator/aiconfigmust render its central content column at exactly the same width, padding andmax-width behaviour as the standard operator pages
/operator/applicationsand/operator/users,desktop and mobile. Both standard pages render through
<Page>with nomaxWidthprop, so thechrome falls back to
.page-chrome--padded { max-width: 90rem }and the body gutters.page-chrome__body { padding: 0 1.5rem 2rem }(dashboard/src/app.css:327,:329-337; mobile@media (max-width: 720px)→padding: 0 0.75rem 5.5rem,app.css:1300-1302).aiconfigalready uses<Page>, but passesmaxWidth="60rem", whichPage.svelte:41turns into aninline
style="max-width: 60rem"that overrides the 90rem chrome cap. That single override is theentire divergence. Fix = remove it (adopt the standard structure), not tune numbers.
"Done" for the operator: opening
/operator/aiconfigshows the same content column edges, the sameleft/right gutters and the same mobile padding as
/operator/applications//operator/users.Scope
Change:
dashboard/src/routes/operator/aiconfig/+page.svelte— dropmaxWidth="60rem"; bump the AI headerLast:field (RULES.md §6).Do not touch:
dashboard/src/routes/operator/personalization/+page.svelte(PR #76 moves it; the/settings/personalizationhalf of the issue is deferred to the #70 follow-up).dashboard/src/lib/components/Page.svelte,dashboard/src/app.css, any width token. No new token,no per-page CSS override.
grid min-w-0 gap-4,space-y-3): the issue scopes width/padding/max-width, andgap-4between stacked cards is the page's own rhythm, not the content column. Reusing the body'sgap-lgwould be a restyle beyond the issue.plans/(product content).UC decision
No UC describes these pages' layout:
rg -n 'page-chrome|90rem|content width|<Page>' docs/use-casesreturns nothing, and
docs/use-cases/frontend/UC-FE-96-aiconfig.mdcovers only the provider-configbehaviour (load/PATCH/refresh/select), not chrome.
UC-FE-50-applications.mdlikewise says nothingabout width. So no UC is authored or edited; the Implementation cite of UC-FE-96 already points at
dashboard/src/routes/operator/aiconfig/+page.svelte, so the cite stays valid. No UCversion:bumpneeded — behaviour of the page does not change, only its chrome instantiation.
I deliberately do not author a new "content width" UC: the standard is stated in
DESIGN.md(line 67, "Default pages cap at 90rem") and in
RULES.md/AGENTS.md(always use<Page>), so a UCwould duplicate a design rule with no handler/behaviour to cite.
Ordered tasks
python3 $FJ comment 71 --file /home/eduardez/workspace/gotoi-wt/meta/issue-71.plan.md.Verify: comment URL printed, exit 0.
maxWidth="60rem"(line 140), update headerLast:to2026-10-08 — content width matches <Page> default (Refs #71).Verify:
rg -n 'maxWidth' dashboard/src/routes/operator/aiconfig/+page.svelte→ no match;sed -n '137,143p' …shows the<Page>attrs intact and the file tail closed at</Page>.dashboard: aiconfig uses the standard <Page> content width (Refs #71).Verify:
git show --stat HEAD.python3 docs/use-cases/_check.py;python3 scripts/check-ai-headers.py;python3 scripts/check-type-mirror.py;cd dashboard && bun run test && bun run check;rg -n 'Showing lines' --glob '!node_modules' --glob '!.git'.Verify: every command exits 0.
max-width/paddingof.page-chromeand.page-chrome__bodybefore (60rem) and after(90rem) the edit, and confirm equality with
/operator/applicationsafter the edit. Dev-serverroute requires an operator session; fall back to a deterministic DOM-level check if sign-in is not
reachable. Verify: recorded computed values in the report + Done comment.
Middle (a)
middlewareand (b)agentgates are not run: the diff touches onlydashboard/.Open questions (assumption stated, proceeding)
explicitly demands the standard width and forbids tuning numbers. If the operator dislikes it, that
is a design decision for a new UC/DESIGN change, not for this issue.
maxWidthhave any other effect on aiconfig? No:Page.svelte:41only emitsstyle="max-width: …". Verified by reading the component./settings/personalizationin scope? No — the file does not exist on this branch(
origin/agent-develophas onlyoperator/personalization/); half deferred to #70.Risk and fallback
maxWidth="60rem"on aiconfig. Mitigation:rg -n 'maxWidth'overdashboard/src/**/*.test.tsshows the only width assertion ismaxWidth="90rem"forsettings/secrets. If a gate still goes red, that is information — report, do not weaken.bun run checkpicks up a leftover unclosed tag. Mitigation: the edit is a single attributedeletion inside the
<Page …>opening tag; re-read lines 137-142 after the edit.styleon the<Page>element ⇒.page-chrome--padded90rem applies, same rule the standardpages hit — and say so explicitly in the report.
DONE (scoped to the /operator/aiconfig half; /settings/personalization deferred to the #70 follow-up)
Commits:
cd1920fdashboard: aiconfig uses the standard content width (Refs #71)Root cause (the responsible line):
dashboard/src/routes/operator/aiconfig/+page.sveltepassedmaxWidth="60rem"to<Page>, anddashboard/src/lib/components/Page.svelte:41turns that prop into an inlinestyle="max-width: 60rem"on the<section class="page-chrome page-chrome--padded">. An inline style beats the class rule.page-chrome--padded { max-width: 90rem }(dashboard/src/app.css:327), so aiconfig capped at 60rem while/operator/applicationsand/operator/users(both plain<Page>, nomaxWidth) capped at 90rem. Fix = drop the prop, adopt the standard structure. No width token or per-page CSS was added.Visual proof measured in the worktree dev server (Chromium, computed styles):
.page-chrome.style.maxWidth='60rem'): max-width 960px, width 960, left 659 — i.e. the pre-fix signature.app.css:1301-1302).Gates (all exit 0):
python3 docs/use-cases/_check.pyok (96 frontend UCs, all conform)python3 scripts/check-ai-headers.pyok (576 ok, 0 missing)python3 scripts/check-type-mirror.pyokcd dashboard && bun run testok (16 files, 251 tests)cd dashboard && bun run checkok (0 errors, 7 pre-existing warnings)cd dashboard && bun run buildokUC: no UC describes these pages' layout, so none was authored or edited; UC-FE-96's Implementation cite already points at the edited file and its behaviour is unchanged.
DESIGN.mdline 67 ('Default pages cap at 90rem') is the contract the page now obeys.DONE — both halves.
Commits:
a1b7da0dashboard: aiconfig uses the standard content width (Refs #71)4d40620dashboard: personalization uses the standard content width (Refs #71)(
a1b7da0is the earlier commit, rebased onto origin/agent-develop; the deferred-personalization premise from the first comment is void — #70/#76 are merged.)Root cause, same pattern in both files: the page passed a
maxWidthprop to<Page>, anddashboard/src/lib/components/Page.svelte:41turns it into an inlinestyle="max-width: …"that beats the class rule.page-chrome--padded { max-width: 90rem }(dashboard/src/app.css:327). Standard pages pass nomaxWidth.routes/operator/aiconfig/+page.svelte:140maxWidth="60rem"→ capped at 960px (removed).routes/settings/personalization/+page.svelte:18maxWidth="48rem"→ capped at 768px (removed).Fix = drop the prop; no width token, no per-page CSS, no number tuning.
Checked PR #76 first: it did not touch the width —
git show 0ed997e^:…/operator/personalization/+page.svelteandgit show 0ed997e:…/settings/personalization/+page.svelteare byte-identical at line 18 (maxWidth="48rem"); the move was verbatim plus a 308 shim I did not touch.Visual proof (worktree dev :5183, Chromium, computed styles):
.style.maxWidth='60rem'→ 960px/left 659;.style.maxWidth='48rem'→ 768px/left 755. That is the pre-fix signature.Gates (all exit 0):
python3 docs/use-cases/_check.pyokpython3 scripts/check-ai-headers.pyok (577 ok, 0 missing)python3 scripts/check-type-mirror.pyokcd dashboard && bun run testok (16 files, 254 tests)cd dashboard && bun run checkok (0 errors, 7 pre-existing warnings)cd dashboard && bun run buildokUC: neither page's layout is described by a UC, so none authored/edited. UC-FE-96 and UC-FE-99 both already cite their page file and their behaviour is unchanged (UC-FE-99 version was already bumped to 2026-10-08 by #76).
DESIGN.mdline 67 ('Default pages cap at 90rem') is the contract both pages now obey.Note for follow-up:
Page.maxWidthremains the drift vector —plans/executions/[id]/approvestill passesmaxWidth="48rem"andsettings/secretspasses a redundantmaxWidth="90rem". Left alone; issue names only two pages.REVIEW: CLEAN — findings: (1) both offenders verified fixed — aiconfig dropped maxWidth="60rem" (
a1b7da0), settings/personalization dropped maxWidth="48rem" (4d40620); no residual width styles in either file, Page.svelte:41 inline-style path now inert for both, class rule .page-chrome--padded { max-width: 90rem } (app.css:334) + body padding 0 1.5rem 2rem (app.css:343) + mobile 0 0.75rem 5.5rem (app.css:1307-1309) are the responsible lines, identical to /operator/applications and /operator/users; (2) plan fidelity: diff touches exactly the two page files, Page.svelte/app.css/plans/ untouched, orchestrator's both-halves extension honored; (3) re-ran gates: _check.py, check-ai-headers (577 ok), check-type-mirror, dashboard test (254 pass), check (0 errors), build — all exit 0; no test touched, no Showing lines in source; (4) non-blocking note: implementer report's app.css line cites (327/1300-1302) drifted a few lines after rebase (actual 334/1307-1309) — report prose only, tree correct; UNFIXED: nonePUBLISHED — branch issue/71-content-width pushed, PR #81 opened to agent-develop: #81. Both halves done: aiconfig dropped maxWidth="60rem" (
a1b7da0), settings/personalization dropped maxWidth="48rem" (4d40620, unblocked mid-run when #70 merged; branch rebased onto origin/agent-develop before the second half). Orchestrator gates on final reviewed tree: _check.py 0, check-ai-headers 0 (577 ok), check-type-mirror 0, dashboard test 254/254, svelte-check 0 errors, build ok. Review: CLEAN (independent reviewer session). Follow-up flagged, out of scope: Page.maxWidth remains a drift vector — plans/executions/[id]/approve still maxWidth="48rem", settings/secrets redundant maxWidth="90rem".