You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adapt the ported UI to this repo's conventions — Tailwind, T3's design tokens, the app's font and background — while retaining what is functionally load-bearing in mindwalk's styling.
Mindwalk's styles.css is 2,452 lines and is not throwaway: it styles the HUD, timeline, and inspector, which is precisely the "UI should basically be the same" that was asked for. But T3 is Tailwind with its own tokens, and the whole point is that this fits the app.
Judgement call this ticket owns: which rules are load-bearing (scene overlay positioning, timeline histogram geometry, inspector layout, hit targets) versus which are mindwalk's visual identity to be replaced (font stack, background, palette chrome). Restyle with both rendering side by side so drift from the thing that was liked is visible as it happens.
Also in scope: the ui/ components copied then restyled — Timeline.tsx (458), Hud.tsx (330), Inspector.tsx (107), Dock.tsx (104), ViewPanel.tsx (45). Not SessionRail.tsx (316) or ReportPanel.tsx (330) — sidebar and judge are out of scope. Hud.tsx carries the subagent count and lens entry point, so it depends on how the agent-lenses gap is resolved.
AGENTS.md "Hit every surface" applies before this is called done, and web verification goes through test-t3-app.
Not in scope: the render loop
The frame loop was carved out into Make the scenes render on change, not every frame and is done — the two are separable, and that one was actionable against the scenes as they landed while this one still waits on the ui/ port. Anything new added here drives FrameLoop (scene/frameLoop.ts): a discrete change calls invalidate(), a running animation says so by returning true from the draw callback. Do not reintroduce an unconditional requestAnimationFrame.
This ticket deliberately departs from the faithful-port rule. Every earlier ticket preserved mindwalk's behaviour and deferred deviations; this one exists to replace mindwalk's visual identity with T3's, so divergence is the deliverable.
Decisions
Structural greys are distances, not colours — a percentage from --background toward --foreground, resolved at runtime. Preserves mindwalk's ordering while putting every value on whatever axis T3 currently uses. One table serves both themes, with a LIGHT_MIX_GAIN of 1.4 because the ground a mix lands on is not perceptually symmetric.
The coloured actions stay declared — confirmed by the dev. The touch states, the timeline's action spectrum, and the mark colours encode meaning T3 has no token for; mapping six actions onto four semantic tokens would lose the cool-is-observation / warm-is-mutation reading the legend teaches.
Mindwalk's 900/1180 breakpoints stay, since the thread side panel does much the same job as the rail they were chosen around.
Selection panning is measured and reversible. Mindwalk reserves a fixed 348px on the right; below its own 900px rule the inspector is a bottom sheet, so that reserve dodges the wrong edge and drags a narrow stage sideways. The reserve is now the inspector's real overlap, and the camera returns when it closes — upstream never restores, which is fine on a wide page and reads as a bug at panel width.
Two things the visual pass caught that reading could not
The token resolution was never running. Chromium serializes computed values in their authored space, so T3's oklch tokens came back as oklab(…), a startsWith("#") guard rejected every read, and the resolver returned its static fallback on every call in both themes. The whole mechanism was inert and only looked right because the fallback had been hand-tuned to match — precisely the drift it existed to prevent. Fixed by rasterizing a pixel and reading the bytes.
The ground plane was the light-mode gradient — a near-black plane six times the map's extent, mostly inside the fog, reading as a full-stage wash rather than as a plane. And the attention columns baked a multiply toward black into their geometry, which only reads as falloff on an unlit stage.
Activity
fix(web): take the 3D stage's sky from T3's background token
refactor(web): resolve the 3D scene's neutrals from T3 instead of dec…
fix(web): theme the 3D ground plane, grid, and column shade
fix(web): make the scene palette actually resolve from T3's tokens
fix(web): keep the 3D scenes framed when they mount at a transient size
fix(web): stop selection panning the stage off-centre in a narrow panel
fix(web): stop reserving the bottom sheet's worst-case height
fix(web): pan for the inspector by measurement, and put the camera back
fix(web): clear the selection when the inspector closes
fix(web): do not re-fit the camera while a selection pan is active
feat(web): restyle the ported mindwalk UI onto T3's design system
fix(web): take the 3D stage's sky from T3's background token
refactor(web): resolve the 3D scene's neutrals from T3 instead of dec…
fix(web): theme the 3D ground plane, grid, and column shade
fix(web): make the scene palette actually resolve from T3's tokens
fix(web): keep the 3D scenes framed when they mount at a transient size
fix(web): stop selection panning the stage off-centre in a narrow panel
fix(web): stop reserving the bottom sheet's worst-case height
fix(web): pan for the inspector by measurement, and put the camera back
fix(web): clear the selection when the inspector closes
fix(web): do not re-fit the camera while a selection pan is active
Dillpickleschmidt commentedon Aug 2, 2026
Merged in #26.
This ticket deliberately departs from the faithful-port rule. Every earlier ticket preserved mindwalk's behaviour and deferred deviations; this one exists to replace mindwalk's visual identity with T3's, so divergence is the deliverable.
Decisions
--backgroundtoward--foreground, resolved at runtime. Preserves mindwalk's ordering while putting every value on whatever axis T3 currently uses. One table serves both themes, with aLIGHT_MIX_GAINof 1.4 because the ground a mix lands on is not perceptually symmetric.Two things the visual pass caught that reading could not
The token resolution was never running. Chromium serializes computed values in their authored space, so T3's
oklchtokens came back asoklab(…), astartsWith("#")guard rejected every read, and the resolver returned its static fallback on every call in both themes. The whole mechanism was inert and only looked right because the fallback had been hand-tuned to match — precisely the drift it existed to prevent. Fixed by rasterizing a pixel and reading the bytes.The ground plane was the light-mode gradient — a near-black plane six times the map's extent, mostly inside the fog, reading as a full-stage wash rather than as a plane. And the attention columns baked a multiply toward black into their geometry, which only reads as falloff on an unlit stage.
Deferred