Step 12d: UI redesign from calternal.js polish #21
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?
Step 12d, from owner feedback on the preview (2026-09-23): "the UI looks absolutely horrible, with the font weights even worse".
The owner's direction:
kayg/calternal.js, branchdev; pinned as a read-only reference at604105bin/mnt/hdd/infraternal/artifacts/reference/calternal.js). Use progressive blur, shadows and depth.docs/UI.md.Done when merged to
dev, browser-verified at 1440×900 and 390×844, light and dark, with before-and-after screenshots.Starting the UI redesign job.
ui-redesigndevat244df292cbe6ae7280d83d0abdaab9b8026fb14fFinding from the baseline review:
AppShell.svelteexposes an “Edit sidebar” toggle, andSidebar.sveltegates item/group dragging plus create, rename and move controls onsidebarStore.editMode. The inbox currently opens as a generic dialog, while account, sign-out and version occupy separate footer rows. The sidebar behavior and footer structure will move to the always-available layout requested for this job.Started the ui-redesign restart on branch ui-redesign. Merged the current origin/dev; base head is
1830177ac5. Capturing the existing owned pages and browser states before changes.Baseline findings from the unchanged UI at
1830177ac5: the desktop screenshot shows a centered modal with a uniform dark scrim and no backdrop blur; the header still exposes “Edit sidebar”; the current account identity, server version and sign-out are three separate footer rows. The existing font treatment renders the sidebar group labels and primary headings heavier than surrounding text. Captured owned pages at 1440×900 and 390×844 in light/dark, plus open inbox and an in-progress sidebar drag, under /mnt/hdd/infraternal/artifacts/ui-redesign/before. Baseline first-load JavaScript: 73,410 bytes gzip of 122,880 bytes.Baseline gate output:
Resuming UI redesign on branch
ui-redesignat3df38e1; fetchedorigin/devat1830177, which is already an ancestor of this branch. I’m reviewing the unfinished WIP against the UI contract and will report fixes, screenshots and gate output here.The inherited browser check still targeted the removed “Edit sidebar” controls, so it could not verify the new always-editable navigation. Review also found that keyboard reparenting can remove the focused handle when an item moves between keyed sections; the desktop sidebar and mobile drawer also render duplicate group IDs, making global ID-based focus restoration target the inert copy. I’m updating the gate and scoping/fixing those focus paths before the screenshot runs.
The production-browser overflow guard isolated the 1024px container-filter overflow to the shared shell: the viewport and app shell were 1024px wide, the collapsed sidebar was 68px, but
.app-bodyended at x=757 (689px wide). The Inbox status paragraph carriedsr-only, but that utility only existed in Sidebar-scoped CSS, so it rendered as a normal flex item in AppShell and reserved the remaining 267px. I added the shared visually-hidden utility to the global UI tokens and removed the duplicate scoped rule; this restores the shell width without touching the container page.CI=1 INFRATERAL_ARTIFACT_DIR=/mnt/hdd/infraternal/artifacts/ui-redesign/after scripts/verify browserstopped in the parallel-owned terminal fixture before the web browser check. The Playwright traces showxterm: waits for the exact terminal font before measuringdiffered by 12 px,xterm: mounts with the CSS fallback when the terminal font fails to loadmeasured a 0 px cell, and the clipboard test read an empty string; the producer-bound test also timed out under concurrent release compilation. No terminal-owned files were changed. I restored the shared regular and medium weight tokens to 500 and 560, which match the reference’s weight range, and will rerun the required gate after the parallel build finishes.Independent review found that the terminal reads
--text-mdwithNumber.parseFloatinpackages/terminal/src/theme.ts:25-28; keeping the shared type-size scale in px preserves its 14 px terminal font without changing parallel-owned code. Keyboard and pointer drops into a collapsed navigation group now expand it so the moved handle remains present and focused. The browser check now tests collapsed-group focus, touch input, pointer drag start/drop/order, sticky Hosts header blur, and cold Dashboard JS after disabling the browser cache for that navigation.Starting ui-redesign4 continuation on branch
ui-redesign.Base: current
devat2c69013777a95218d17e36cfb6a0408341b0c5f0, fetched and merged into the worktree. Starting head:1a5730c84bf753561de4fcee8f06ec93227f38af.I’m reviewing the inherited WIP against the step 12d brief, then will implement the remaining UI changes, commit in small steps, and run the requested fast and browser gates with screenshots.
Baseline browser finding:
scripts/verify browsermeasuredMETRIC initial route JS gzip: 77462 bytes, within the 120 KB budget, then failed during the setup/sign-in flow before the owned-page screenshot loop.Relevant output:
I’m tracing the auth/browser fixture so the final browser gate can complete and generate the requested before/after captures.
Finding: the baseline shell sets
--weight-regular: 500, so body copy inherits the same medium weight used by controls and labels. The 1440×900 Dashboard capture also shows every sidebar drag grip at full contrast. Reworked the scale around Inter Variable at 400/500/560/600/650/680, use Spline Sans Mono from calternal for identifiers, and keep drag grips low contrast until hover/focus (visible on touch). The selected mono package resolved to 5.3.0; the reference source is/mnt/hdd/infraternal/artifacts/reference/calternal.jsat604105b1e490e9e91b0a62a6bdc59ff6596bc7ae.Browser finding: replacing the shared
--font-monoface with Spline Sans Mono made the terminal fixture's xterm and Ghostty font-measurement checks fail by 5 px (expected ≤1.01 px). The terminal package owns that token as its measured cell face. I restored JetBrains Mono on the stable--font-monoAPI, added--font-datafor Spline Sans Mono identifiers, and will rerunscripts/verify browserbefore recording the final result.Browser capture finding: the inbox locator timed out after its dialog was visible because
captureInboxOpensearched for.ui-floating-surfacebeneath the dialog, while that class is on the dialog element itself. The Playwright run had already measured first-load JS at 77,495 bytes gzip (baseline browser run: 77,462 bytes). I am correcting the capture to inspect the dialog node directly and rerunning the full browser gate.Browser capture finding: the data-face assertion also ran on unrelated routes. It failed on the container table, which retains JetBrains Mono through the stable
--font-monotoken owned by the parallel container/terminal work. I narrowed the Spline Sans Mono assertion to the Dashboard, Hosts, Account and host-detail screenshots owned by this job; the first-load measurement was 77,503 bytes gzip, within the 120 KB budget.Browser finding on
71ba255: the mobile touch-drag guard reached the drop check but the Hosts item stayed before Containers (["hosts", "containers", "stacks", "images", "volumes"]instead of["containers", "hosts", ...]). The same run passed both font assertions and measured 77,503 bytes gzip. I am tracing pointer target detection and drop-index handling before the final browser rerun.Browser gate finding: touch pointer movement reached the intended sidebar row and applied its drop-target styling, but the item order remained unchanged after touch release. I added event tracing for pointerdown/move/up/cancel to identify whether the release event reaches the captured drag handle. The required touch reorder behavior remains under test.
Touch trace identified the test failure: the helper measured the Containers row at y=217..257, then the live row shifted to y=233..277 during the touch stream. Its y=247 endpoint was above the live midpoint (255), so the app correctly resolved a before-target insertion and left Hosts in place. Updated the browser check to aim near the target row's lower edge, assert that the intended row is highlighted alone, and then verify the committed order. No production drag behavior change was needed.
Finished ui-redesign4 continuation on branch
ui-redesign.Head:
0315d7e7d4587a76bc22fa2e5f6bd1a972a74826Gate output (verbatim):
The Playwright gate also passed its existing viewport overflow guard, inbox focus checks, reduced-transparency fallback, account-row fit checks, and pointer/touch/keyboard sidebar reorder checks.
Initial route JS gzip was 76,619 bytes in
artifacts/ui-redesign/before/production-first-load.jsonand 76,787 bytes inartifacts/ui-redesign/after/production-first-load.json(+168 bytes). The budget is 122,880 bytes (120 KiB); both are within budget.Screenshots:
/mnt/hdd/infraternal/artifacts/ui-redesign/beforeand/mnt/hdd/infraternal/artifacts/ui-redesign/after; examples includelight-1440x900-dashboard.png,dark-390x844-dashboard.png,light-1440x900-hosts.png,dark-390x844-account.png,light-390x844-sign-in.png, anddark-1440x900-setup.png.before/light-1440x900-inbox-open.png,before/dark-390x844-inbox-open.png; after:after/inbox-open-light-1440x900.png,after/inbox-open-dark-390x844.png(same pattern for the other two sizes/themes).before/sidebar-drag-light-1440x900.png,before/sidebar-drag-dark-1440x900.png, and the matching files underafter.beforeset has desktop host-detail screenshots but no 390×844 host-detail pair; I left that baseline gap explicit rather than synthesizing an image.Rules applied:
emil-design-engandbetter-typographyfor variable type roles, tuned weight tokens, optical sizing and unitless leading;better-colors,better-uiandbetter-layoutfor shared semantic tokens, elevation, spacing and aligned surfaces;apple-designfor restrained depth, masked blur and safe-area-aware sheet behavior;better-accessibilityandmobile-nativefor named controls, touch hit areas, keyboard DnD, live announcements, managed focus, and mobile viewport behavior;better-writingfor concise sentence-case labels;review-animationsfor transform/opacity-only motion, reduced-motion handling and no keyboard-triggered motion.Ported/adapted from calternal.js commit
604105b1e490e9e91b0a62a6bdc59ff6596bc7ae: type and font-source choices from/mnt/hdd/infraternal/artifacts/reference/calternal.js/packages/web/src/app.css,packages/web/src/lib/fonts.ts, andpackages/web/src/lib/fontSources/local.ts; elevation values frompackages/web/src/lib/styles/blockLift.css; progressive scrim behavior and floating-card handling frompackages/web/src/lib/styles/scrim.cssandpackages/web/src/lib/components/menu/FloatingSurface.svelte; sidebar hierarchy frompackages/web/src/lib/components/Sidebar.svelte. Each adapted source file records its reference path and commit.Safari/iOS owner checklist:
Review started for step 12d. Branch: ui-redesign. Base: dev at
2c69013. Review head:0315d7e7d4. Scope is read-only review of the requested UI redesign diff, reference styling, screenshots, behavior, and bundle evidence.Independent review of step 12d at
0315d7e7d4587a76bc22fa2e5f6bd1a972a74826(base2c69013). Review-only; no source edits or commits.Findings
HIGH · blocks-merge · Account row requirement is not met. Before: profile, server version, and sign-out share one line. After: the 1440 screenshot shows the version below the profile name;
Sidebar.svelte:436-443,500-502uses a grid for the copy. Evidence:/mnt/hdd/infraternal/artifacts/ui-redesign/after/dark-1440x900-account.png. The account-row browser assertion checks visibility/height/side-by-side controls, not whether the version shares the name's row. Fix: usedisplay:flex; align-items:baseline; gap:var(--space-2)(8px) for.account-copy; keep.account-nameatmin-inline-size:0with ellipsis, and.account-versionwhite-space:nowrap; flex:0 0 auto; retain a 40px sign-out control. Check the 272px drawer at 320px and the 300px drawer at 390px. Port the flexible, truncating account segment pattern from calternal.jspackages/web/src/lib/components/Sidebar.svelte(.foot-acct). Rule: better-layout's single-row grouping and deliberate truncation; preserve the better-accessibility target size.MEDIUM · blocks-merge · The main dashboard still reads almost like the before version. The 1440 before/after pair retains the same bordered-card grid; the new shadow is visible but subtle, so the requested calternal depth/material treatment does not read clearly on the primary page. Evidence:
/mnt/hdd/infraternal/artifacts/ui-redesign/before/dark-1440x900-dashboard.pngand/mnt/hdd/infraternal/artifacts/ui-redesign/after/dark-1440x900-dashboard.png;Surface.sveltenow applies--shadow-cardto every default surface. Fix: use explicit elevation tiers: keep secondary surfaces on--shadow-card, and use the existingSurfaceraised tone /--shadow-panelfor primary dashboard status surfaces (light:0 1px 1px rgb(0 0 0 / 8%), 0 8px 18px -4px rgb(0 0 0 / 22%), 0 24px 44px -12px rgb(0 0 0 / 30%); dark:0 1px 1px rgb(0 0 0 / 34%), 0 10px 22px -4px rgb(0 0 0 / 56%), 0 28px 50px -12px rgb(0 0 0 / 66%)). Use calternal.jslib/styles/blockLift.cssfor the contact/mid/ambient shadow recipe andlib/components/menu/FloatingSurface.sveltefor the floating material recipe, rather than treating all cards alike. Rules: emil-design-eng and better-ui, visible material/elevation hierarchy.MEDIUM · later · The inbox scrim's ramp is too subtle to read as progressive. The implementation does have a mask:
FloatingSurface.svelte:174-177keeps full blur through 76% of the viewport and fades only over the final 24%; the 1440 screenshot consequently reads as a broad full-page blur, including the sidebar. Evidence:/mnt/hdd/infraternal/artifacts/ui-redesign/after/inbox-open-dark-1440x900.pngand/mnt/hdd/infraternal/artifacts/ui-redesign/after/inbox-open-dark-390x844.png. The top bar also has its own masked 8px blur (AppShell.svelte:284), disabled while inbox is open to keep one live blur (:322-325). Correction to the claim: calternal.jslib/styles/scrim.cssitself has no gradient mask; it defines one live full-screen blur and disables other backdrop filters. Fix: keep that one-live-filter rule,--scrim-blur:8px, and the existing 18% tint; change the mask tolinear-gradient(to bottom,#000 0%,#000 58%,transparent 100%), matching the current top-bar fade, so the fade spans 42% instead of 24%. Keep the solid fallback and reduced-transparency behavior. Use calternal.jslib/styles/scrim.cssfor single-live-filter behavior andlib/components/menu/FloatingSurface.sveltefor the floating material. Rules: apple-design's single live material layer and emil-design-eng's intentional depth.MEDIUM · later · Sidebar controls add persistent visual noise. Desktop drag handles have default
opacity:0.12and every group has a visible 32px menu/gear (Sidebar.svelte:480,483-486); the screenshot shows both. The “group headers have no hierarchy” claim is refuted: headers are 32px/13px versus 40px/14px items, with separate spacing (:475-477). Fix: make desktop handles and group menus hidden at rest, reveal handles at.65on hover and1on keyboard focus/drag, and reveal the menu on hover/focus/open. Keep coarse-pointer affordances visible at the existing.75opacity and 44px target. Align the group title with item labels when its handle is hidden. Use calternal.jspackages/web/src/lib/components/Sidebar.svelteandlib/components/modeIsland.cssfor contextual sidebar feedback. Rules: better-ui contextual controls, better-layout hierarchy, and better-accessibility keyboard/touch access.LOW · later · Inbox close target is 32×32px.
FloatingSurface.svelte:147-149requestsIconButton size="sm";IconButton.svelte:53sets 32px. The accessible name and focus path work, but the × is a small pointer target. Fix: usesize="lg"(44×44px, already supported) in the floating header. Rule: better-accessibility's comfortable touch target; use calternal.jslib/components/menu/FloatingSurface.sveltefor the header/material context.Checked with no finding
docs/UI.md:91-92specifies; a full reload resets it.backdrop-filterfallbacks are present. Top-bar progressive blur exists; at the initial scroll position there is little content beneath it to make the blur visible.font-weightfor the variable weight axis andfont-optical-sizing:auto; there is no authoredfont-variation-settingsoverride (computednormalis expected). Calternal's body/title values are 400/600. The browser harness checks weights, not that property directly.VITE_ENABLE_DEV_ROUTES=1;/dev/overlaystill redirected to/loginwithout its authenticated backend/session, so visual comparison used the checked-in CSS. The reference app did load the login screen without page errors.Browser gate output
Verdict: Block on the account-row requirement and the insufficiently visible dashboard treatment. Findings use emil-design-eng, better-interface, better-ui, better-layout, better-typography, better-colors, better-accessibility, better-writing, apple-design, and review-animations rules; the focus here is on layout, hierarchy, material, target size, and reduced-motion/transparency behavior.
Starting the one fix round for step 12d.
ui-redesign0315d7e7d4587a76bc22fa2e5f6bd1a972a74826scripts/verify fastandscripts/verify browserwith the requested screenshot and blur-cost evidence.First
scripts/verify fastresult on the fix-round diff: the migration, dependency, web build, formatting, clippy, Rust tests, Svelte checks, stream typecheck, and first Vitest steps passed. It then exited 1 atfast: UI package Vitestbefore running tests:src/primitives.test.tsandsrc/timestamp.test.tseach had a worker fork startup timeout after 60.07s (Timeout waiting for worker to respond) during concurrent heavy Rust compilation. I will rerun after the load clears.Browser gate attempt on 2026-09-24 stopped before the owned UI screenshots or assertions. The container lifecycle step waited for the success toast
Start infraternal-browser-3294301-1790212863237, but the toast had already changed toStop infraternal-browser-3294301-1790212863237; the test row reported Exited (137) and Start was disabled. No account, surface, blur, sidebar, or owned-route browser checks ran in this attempt. I am rerunning after the concurrent Cargo build load clears to determine whether this is transient.Browser rerun evidence: at 1440 the account row was 44 px high, all four controls were contained in its line box, the name/version baseline delta was 0.875 px, and their common vertical band was 15.98 px. The profile and sign-out centers were 3.58 px apart because the row uses baseline alignment. I removed the extra center-equality check and kept the required containment, overlap, common-line-band, and name/version baseline assertions at 320, 390, and 1440. This run stopped before screenshots; the browser gate is running again.
Starting continuation on branch ui-redesign at
9f54a04549; the fix round originated from0315d7e. I am checking the current head against the review and owner brief before making any changes.Current-head check at
9f54a04: the Dashboard and Hosts comparison captures show visibly deeper shadows; FloatingSurface has three 2/6/12px masked passes and its close control already uses size="lg". The 320px drawer capture also looks like one row. The browser assertion still needs stronger evidence: assertAccountRowFits checks positive overlap for the profile wrapper, version, and sign-out, but does not include the avatar in the common-line calculation or assert the sign-out is exactly 40×40. The existing blur-scroll-smoke.json records mean 120.55ms and p95 144.5ms for 90 moved frames; the fresh browser gate is remeasuring this.Blur smoke evidence: at the time of the 102.25ms mean / 113.10ms p95 run, a second production browser gate was active. The Chromium process used --disable-gpu-compositing and SwiftShader, so this is a contended software-rendered headless smoke, not a GPU performance result. The current gate adds an on/off A/B with the same scroll loop to isolate the filters.
Fix round complete on branch
ui-redesign, HEADd694f5ad8cd9e296b6570b7bc6308a02e0f69c79(ahead 23; not pushed).Owner requirements
var(--space-2)gap. Browser assertion checks their shared line at 1440px and in the open 390px and 320px drawers; the 320px drawer is opened in the browser gate.--shadow-panel, with softened borders. Secondary Dashboard cards use--shadow-card. Before/after side-by-side captures show the difference in both themes.--disable-gpu-compositingwith SwiftShader and had no concurrent browser gate, so these are software-renderer smoke figures, not a GPU performance result. Data:/mnt/hdd/infraternal/artifacts/fix-ui-redesign/after/blur-scroll-smoke.json.size="lg"; browser gate checks at least 44×44px.Production first-load JavaScript is 76,761 bytes gzip (122,880-byte budget):
/mnt/hdd/infraternal/artifacts/fix-ui-redesign/after/production-first-load.json.Gates
scripts/verify fast:scripts/verify browser:Screenshots
Full before and after sets are under
/mnt/hdd/infraternal/artifacts/fix-ui-redesign/{before,after}/:{light,dark}-{1440x900,390x844}-{dashboard,hosts}.pnginbox-open-{light,dark}-{1440x900,390x844}.png,topbar-scrolled-{light,dark}-{1440x900,390x844}.pngsidebar-{rest,hovered}-{light,dark}-1440x900.pngaccount-row-{light,dark}-{1440x900,390x844-drawer,320x844-drawer}.png/mnt/hdd/infraternal/artifacts/fix-ui-redesign/comparison-{dashboard,hosts}-{light,dark}-1440x900.pngDesign rules applied
Applied
emil-design-eng,better-interface,better-ui,better-layout,better-typography,better-colors,better-accessibility,better-writing,apple-design, andreview-animations: use shared tokens and primitives, establish clear surface hierarchy, align and truncate deliberately, retain accessible focus and 44px touch targets, preserve reduced-transparency fallbacks, and keep motion to the approved transform/opacity properties with reduced-motion behavior.Starting verify-ui-redesign on branch
ui-redesign. Assignment base head:d694f5ad8cd9e296b6570b7bc6308a02e0f69c79.Fetched
devas2c69013777a95218d17e36cfb6a0408341b0c5f0; it is already an ancestor of the assignment head.git merge --no-ff --no-edit FETCH_HEADreportsAlready up to date.No product files changed yet.Verification finished on head
d694f5ad8c.Fetched origin/dev at
2c69013777. It was already an ancestor of the verified head; git merge --no-ff --no-edit FETCH_HEAD reported “Already up to date.”, so no merge commit was needed. No product code changes were required.Findings:
PASS — Account row: avatar, name, version and sign-out fit one line at 320×844 (drawer open), 390×844 (drawer open) and 1440×900 in light and dark.
PASS — Visible depth: Dashboard and Hosts show a raised focal tier with layered shadows and softened borders. Before/after comparisons in both themes are in /mnt/hdd/infraternal/artifacts/verify-ui-redesign/.
PASS — Progressive blur: Inbox uses three masked levels (2/6/12 px), and the top-bar blur fades over scrolled content. Inbox blur DOM layer and scrim are absent when closed; top-bar blur is suspended while Inbox is open. Reduced Transparency uses a solid scrim; the unsupported-backdrop-filter fallback was checked through its CSS fallback and a Chromium no-filter simulation.
Software-renderer browser-gate smoke, 90 synthetic scroll frames while Inbox was open: blur on 103.15 ms mean / 114.8 ms p95; filters off 17.65 ms mean / 17.0 ms p95. This synthetic background scrolling is not reachable by the user: at 390×844 the page scrolls with Inbox closed, but the background is inert and does not move under wheel input while Inbox is open, with no background animation. The scroll-related Inbox cost therefore applies to the opening visual change; the surface is removed immediately on close, and keyboard opening does not animate.
With Inbox closed, desktop top-bar smoke was 16.84 ms mean / 18.6 ms p95 with blur versus 16.63 ms / 18.4 ms without. On a naturally scrollable mobile page p95 was 19.3 ms with blur versus 17.0 ms without; the blur-on mean was 291 ms due to one scheduler outlier. These are software-renderer smoke measurements, not a performance gate. The explicit SwiftShader run showed unstable frame-time outliers.
PASS — Calm sidebar: fine-pointer handles/group menus are hidden at rest and shown on hover/focus; headers are distinct; pointer, touch and keyboard reorder work with live announcements. Coarse-pointer handles and menus are visible with 44×44 px targets. No edit mode control.
PASS — Inbox close: 44×44, keyboard reachable; Escape closes and restores focus.
Also PASS — overflow guard across all routes at 1440×900, 1024×768, 768×1024, 390×844 and 320×640 in light and dark. docs/UI.md and DECISIONS §20 state there is no edit mode. First-load JavaScript: 76,761 bytes gzip / 122,880-byte budget.
Owner Safari/iOS checklist:
Gate output:
scripts/verify fast
INFRATERNAI_ARTIFACT_DIR=/mnt/hdd/infraternal/artifacts/verify-ui-redesign scripts/verify browser
The complete evidence, screenshots, blur measurements and checklist are in /mnt/hdd/infraternal/artifacts/verify-ui-redesign/verification.md.EOF
Correction to the browser command label in my finish comment: the variable is INFRATERNAL_ARTIFACT_DIR (ending in L):
INFRATERNAL_ARTIFACT_DIR=/mnt/hdd/infraternal/artifacts/verify-ui-redesign scripts/verify browser
The quoted PASS output and verification results are unchanged. The artifact report has the corrected command.EOF
Orchestrator: step 12d is merged to
devat7bda001and pushed. The merged tree is identical to the verified headd694f5a. The path was build (ui-redesign, 4 runs across usage limits), one independent review, one fix round (the review's five findings, all promoted to blocks-merge as owner requirements) and one verify: all PASS, fast and browser green.Blur cost, decided acceptable.
/mnt/hdd/infraternal/artifacts/verify-ui-redesign/safari-ios-checklist.md.Note: sidebar order is still in memory until the arrangement API exists (
docs/UI.md).