🤖 feat: match Review 1.4 layouts and palette (footer bar, title header, creation hero, composer)#3753
🤖 feat: match Review 1.4 layouts and palette (footer bar, title header, creation hero, composer)#3753ibetitsmike wants to merge 21 commits into
Conversation
… hero) Implements the two structural layout changes from the "Review 1.4" page of the "Mux exploration" Figma: - New WorkspaceFooterBar under the chat pane: repository state (branch selector, devcontainer chip, git drift indicator), PR link badge, and session token usage (+ live t/s while streaming) live in a persistent bottom status bar. Repository controls move out of WorkspaceMenuBar so the header keeps identity (runtime, project, title) and actions only. - "Let's get building." creation hero headline on ProjectPage, matching the design's "start V2" empty/creation state. Scratch workspaces keep hiding repository controls; gating coverage moved from WorkspaceMenuBar.test.tsx to WorkspaceFooterBar.test.tsx. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0173Z5TUFg4BqnACfxAKDJ3o
Match the Review 1.4 workspace frame more closely: - Header now reads "Workspace title ⓘ" — the workspace title is the header's identity, with project label, workspace name, and path one hover away on the info icon. RuntimeBadge and the project label move out of the header. - Footer bar gains the runtime badge (leading) and the project hierarchy label, matching the design's PR / drift / repo / branch item order. - e2e navigation check follows the project label into the footer bar. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0173Z5TUFg4BqnACfxAKDJ3o
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c711bd136d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Checked-in visual reference for the Review 1.4 page of the "Mux exploration" Figma: top-level layouts, sidebar/project-pane states, menus & selectors, chat column + footer info bar, and the right panel — each with exported screenshots, deep links back to the Figma nodes, designer intent notes, a design → code mapping table, and the tracked not-yet-implemented deviations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0173Z5TUFg4BqnACfxAKDJ3o
|
@codex review Generated by Claude Code |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 95bf6ca21b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Bring the footer bar to item-for-item parity with the design:
- Reorder items to the design sequence: PR, drift, repository, branch,
tokens, last prompt (drops the flex spacer that right-aligned usage).
- Show the GitHub repo slug ("coder/mux") like the design, falling back to
the project hierarchy label until PR detection resolves a remote.
- Add the design's "Lines" dropdown labelling the drift counts. It toggles
the drift mode through the same persisted key as the divergence dialog.
- Label the PR badge "PR #1234" and dim the token unit suffixes.
- Add the "Last prompt" item from the footer note, backed by a new
useWorkspaceLastUserPrompt selector that skips synthetic turns.
Two layout bugs found while checking narrow widths:
- The horizontal scrollbar consumed 11px of the bar's 28px height. The bar
now uses scrollbar-none.
- Footer items shrank instead of being clipped, so the repo slug collapsed
to zero width while its icon stayed. Items are now shrink-0, and the
project label caps its width rather than collapsing.
|
@codex review Footer parity pass on top of the original layout work: item order now follows the design (PR, drift, repository, branch, tokens, last prompt), the repository item shows the GitHub slug with a project-label fallback, the design's Two narrow-width bugs were found and fixed while diffing live screenshots against the Figma exports: the horizontal scrollbar was eating 11px of the bar's 28px height, and footer items were shrinking instead of being clipped (collapsing the repo slug to zero width while its icon stayed).
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e681468707
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Hoist the creation hero out of the provider-dependent branch. It was skipped entirely in the no-providers state (exactly the first-run case the hero is for) and flashed in then out while provider state loaded. - Fix the command-palette story play tests, which CI was already failing on this branch: the header now renders the workspace title that the sidebar row also shows, so findByText matched two elements. Wait on all matches. - Record the repository-slug limitation in the RFC: the footer shows the real slug only once PR detection resolves one, so a GitHub-backed branch with no PR still reads as the project label.
|
Addressed the three Codex findings on 1. Preserve footer height when horizontal scrolling ( 2. Keep the creation hero visible during provider setup ( 3. Derive the repository slug independently of PR detection ( Also fixed a CI failure that predates this parity pass:
|
|
@codex review All three prior findings are addressed on
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c8e70c29d7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
The prompt text was only reachable through a hover tooltip on a plain span, so touch users (no hover) and keyboard users (no focus target) could not read it at all. Swap in a Popover with a real button trigger: click, tap, and Enter/Space all open it now.
|
Make Last prompt usable without hover — fixed on Replaced it with a
|
|
@codex review The Last prompt accessibility finding is fixed on
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 735ffeab93
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Drop the useCallback wrappers from useWorkspaceLastUserPrompt. The React Compiler handles this, and useWorkspaceState right above it already subscribes to the same subscribeKey channel with plain inline arrows. - Make the header's workspace-details trigger a real button. It was a bare Info SVG behind a hover tooltip, so the project, workspace name, and path it holds were unreachable by touch or keyboard. Same fix as the footer's Last prompt item: a Popover on a focusable button.
|
Both round-3 findings fixed on 1. Remove manual memoization from the selector hook ( 2. Use an activatable trigger for workspace details (
|
|
@codex review Round-3 findings fixed on
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a6f28a7710
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Hide the Lines/Commits toggle for multi-project workspaces. MultiProjectGitStatusIndicator has no mode concept, so the toggle changed nothing on screen while still rewriting the shared preference that single-repo workspaces later read. - Register TOGGLE_DRIFT_MODE (Ctrl/Cmd+Shift+G) so the toggle is reachable from the keyboard like every other operation, wired with the same window-listener pattern as TOGGLE_NOTIFICATIONS and surfaced in the keybinds settings section. The button also advertises it in its tooltip.
|
Both round-4 findings fixed on 1. Hide the ineffective mode toggle for multi-project workspaces — fixed, and the diagnosis was exactly right: 2. Register a shortcut for the new drift-mode operation — fixed. Added
|
|
@codex review Round-4 findings fixed on
|
|
Codex Review: Didn't find any major issues. Bravo. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
The earlier passes left both the new-chat screen and the message composer
looking nothing like the design. This addresses the shared composer row plus
the creation surface.
Composer row, now matching the design's order and shapes:
- Agent mode pill leads the row (who is acting reads before which model).
- Model and thinking level share one bordered pill split by a divider,
matching the design's "claude opus 4.5 | max".
- The context meter is a bordered pill labelled "Context" with its percentage
always visible, instead of a bare meter whose percent only showed when narrow.
- Send is a filled circle, so it reads as the row's primary action.
Creation surface:
- Drop the raised-card chrome (shadow-lg, heavy padding) for the design's
plain bordered surface, so the headline carries the page.
- State runtime and branch as a sentence ("This workspace will use Worktree
from main") instead of stacked labelled fields. Labels move to sr-only, so
the controls and their handlers are unchanged.
- Placeholder now names the blank-prompt path, per the design: "Describe your
goals, or leave blank for a codebase summary."
Deliberately not copied from the design: the "Auto: Plan" mode pill (there is
no auto-selection concept, and AgentModePicker's tests assert its absence) and
the send chevron (PR #2633 removed it on purpose to keep Send single-action,
and tests/ui/chat/sendModeDropdown.test.ts guards that).
|
@codex review Follow-up on reviewer feedback that the new-chat screen and the message composer did not match the supplied design. Restyled both on Shared composer row now follows the design's order and shapes: agent-mode pill leads, model and thinking level share one bordered pill split by a divider ("Opus 5 | MAX"), the context meter is a bordered "Context … 7%" pill with the percentage always visible (previously the percent only appeared on narrow layouts), and Send is a filled circle. Creation surface: dropped the raised-card chrome for the design's plain bordered surface, restated runtime/branch as a sentence ("This workspace will use Worktree from main") with labels moved to Two things in the design I deliberately did not copy, both because the repo already made the opposite call on purpose:
Validation:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 822c1ae52b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Moving the mode pill to the start of the composer row left its dropdown anchored right-0, which pushed the menu off the viewport. Playwright could still see the rows but never click them, so every E2E spec calling ui.chat.setMode timed out on linux and macOS. Verified in a sandbox before and after: the "plan" row now reports onScreen/clickable with elementFromPoint hitting the row itself.
|
Enable the blank creation path before advertising it — fixed on Implementing blank-prompt creation plus a codebase-summary flow is a feature, not part of a restyle, so I removed the promise instead of shipping copy the app cannot honor. The placeholder now reads "Describe your goals to create a workspace..." (scratch: "...to start a scratch chat..."), and the blank-prompt path is recorded in the RFC's tracked deviations. While there I also recorded the creation-sentence slot mapping as a deviation: the design's "My project will use [select source] with [Select model] with [Select level] thinking." is the zero-projects frame where "source" means picking a repository, whereas the implemented sentence covers the has-project screen and must state workspace type and source branch because Separately, the E2E failures on the previous head were a real regression from moving the mode pill (its dropdown was anchored
|
|
@codex review Fixed on
|
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
The earlier passes matched the composer's layout but left its legacy colors in place, so it did not look like the Review 1.4 frames. Sampling the frames shows they use the zinc scale our dark theme already carries, so this maps them to existing tokens rather than new hex values: - The prompt has no fill or border of its own (design: same color as the page). One bordered box now wraps the textarea and the pill row, so there is no nested box, and it carries the amber editing tint that was on the textarea. - Pill borders drop to the composer box's hairline (border-light, #262626 vs the sampled #27272a) instead of the heavier border-medium (#454545). - The context meter track becomes surface-quaternary (#3f3f46), the sampled value, instead of bg-dark (#1D1D1D). - Send fills with the design's cyan once a message can be sent, and sits on surface-secondary (#18181b, also sampled) when it cannot. The cyan is a new --color-composer-send token per theme: the design's accent is not --color-accent's blue, and reusing --color-border-pending would borrow a token that means "needs attention". - The agent pill tints its label and icon and keeps a neutral border, per the design, rather than tinting the border. VimTextArea's isEditing and focusBorderColor props are gone: with no surface of its own it has nothing to color. The EditingMessage story asserted the tint on the textarea, so it now asserts it on the composer surface it moved to. The RFC records the sampled-value to token mapping, plus four places the frames were not followed: their label greys fail WCAG AA (~2.5:1), thinking level and runtime colors encode state we would lose, and the agent pill uses the agent's own color instead of the frame's cyan.
…er grey The frames use one fill for every surface (#09090b) and let hairline borders do the separating. Our chrome (left sidebar, both header bars, footer bar) painted itself #171717 through --color-sidebar, so it read as a lighter grey band around a correctly-colored transcript and composer. --color-sidebar now resolves to --color-surface-primary in the dark theme, which covers every bg-sidebar consumer at once. The light and Flexoki themes keep their own sidebar fill: a lighter sidebar is a deliberate choice there, and the frames only specify dark. Three bg-sidebar consumers are floating surfaces rather than chrome (the drag ghost, the skill count badge, the SQL samples dropdown) and would have lost their contrast against the page, so they move to bg-dark, matching the fill the repo's other popovers already use. Also fixed while here: - ThemeContext pinned an inline body background of --color-background (#1f1f1f), overriding the stylesheet's surface-primary. Nothing visible sat on it, but it would show through overscroll and before mount. - The context pill's hover was bg-sidebar-hover, which is not a defined token, so the pill had no hover feedback at all. It now uses bg-hover. Review follow-ups on the previous commit: --color-composer-send carries the sampled #a4e8f2 rather than an hsl() that rounded to #a6e8f2; ChatInput's focusBorderColor is renamed agentColor since nothing draws a focus border with it anymore; and the story checks the editing class with classList.contains.
|
@codex review Two commits since your last pass, both addressing feedback that the implementation matched the design's layout but not its colors.
Worth your attention: whether the dark-only
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9745fc1e52
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…theme-color Codex caught that the Windows/Linux titlebar overlay still hardcoded #171717, so the native window-controls strip stayed the old lighter grey above a now page-colored header. The main process cannot read CSS variables, so the value has to be duplicated somewhere; this puts it in one place both layers import. The theme-color meta tag had the same problem for a different reason: its dark value was #1e1e1e, matching neither the old chrome nor the new. Both now come from CHROME_COLORS, so mobile browser chrome matches the page too. The overlay still uses the dark value on every theme, as before: the window is created before the renderer resolves a theme, and making the overlay follow theme changes needs setTitleBarOverlay plumbing that is out of scope here.
|
@codex review Fixed in Since the main process cannot read CSS variables, the value has to live in TS somewhere, so it now lives in exactly one place ( The overlay still uses the dark value regardless of theme, as it did before. Making it follow theme changes needs
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 93995c1b7c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codex found a third copy of the palette: index.html sets theme-color synchronously before any bundle loads, and its dark/light values were still #1e1e1e / #f5f6f8. So a cold load painted the old color and the React path then replaced it, flipping the browser chrome during hydration. The boot script is inline and cannot import, so the values stay duplicated. A colocated test now parses that block and compares it against CHROME_COLORS, which turns silent drift into a failing test. Verified it fails by reintroducing the old dark value.
|
@codex review Fixed in
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 44e022677f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
… per workspace Two Codex findings. The theme-color flash was not fully fixed: the static meta tag was still #1e1e1e, which is what a cold load shows before the boot script runs and what survives when that script's catch path fires (blocked storage sets data-theme dark but never touches the meta). Correcting the static value fixes both paths at once, so the catch branch needs no extra code, and the boot script's own last-resort literal now reads from its palette. The guard test covers the static value too; verified it fails by reintroducing #1e1e1e. WorkspaceShell keeps ChatPane mounted across workspace switches, so the footer's horizontal scroll offset carried over: on a narrow viewport, switching from a scrolled footer to another overflowing one opened with the runtime, PR, and drift items off-screen. The bar is now keyed by workspace id so it remounts at scroll 0.
|
@codex review Both fixed in Boot fallback: you're right that I only fixed the assigned value, not the starting one. The static Footer scroll: confirmed,
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b6f2c1fabe
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…inside 375px The native chrome palette (titlebar overlay, theme-color meta) mirrored the page fill, which only matches the chrome in the dark theme. It now mirrors each theme's --color-sidebar, so light and Flexoki keep their own chrome contrast. The composer's new bordered surface added 16px of inner padding, which pushed the pill row's 340px minimum past what a 375px viewport leaves. The row now clamps at 320px, with the matching container-query threshold.
|
@codex review Both P2 findings are addressed in 412adfa (replies on each thread):
|
The installed app paints its splash and OS chrome from public/manifest.json, which still held the old #1e1e1e. The chrome palette test now covers it, so the manifest cannot drift from the boot script and meta tag.
|
@codex review Latest head is d63f817. Since the previous request it also brings
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 64bbf3421c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Moving the border off the textarea also removed its focus border, and the textarea keeps focus:outline-none, so keyboard focus had no visible state. The box now takes the agent-colored border the textarea used to show, keyed off textarea focus so tabbing across the pills does not light up the whole box. The story asserts the rendered border color changes, which also covers the arbitrary has-[] variant compiling.
|
@codex review The focus-state P2 is fixed in 7151343 (reply on the thread). Head is 7151343. The composer box now shows the agent-colored border the textarea used to show on focus, keyed off
|
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
The comment claimed the pill row's controls carry their own focus rings, which is false: their computed outline-style is none even at :focus-visible. That gap predates this branch. State the real reason for keying off textarea focus, which is that the border replaces the textarea's own focus border and should keep meaning "the prompt has focus".
|
@codex review Head is 0462aeb. Comment-only change since your approval of 7151343: my justification comment on the composer focus border claimed the pill row's controls carry their own focus rings, which is false (their computed
|
|
Codex Review: Didn't find any major issues. Can't wait for the next one! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Summary
Matches the Review 1.4 page of the Mux exploration Figma in both layout and palette: a workspace footer info bar, a workspace-title header, a creation hero, a restyled composer row, and the design's flat surface treatment, plus a design-reference RFC with exported Figma screenshots so the target design is reviewable alongside the code.
Background
Review 1.4 is the latest iteration of the Mux UI exploration (design: Tracy Johnson). Much of its sidebar/right-panel language already exists in the app (the Figma is Code Connect-mapped to
AgentListItem), so this PR targets the genuinely new layout structures: the workspace footer info bar, the workspace-title header, the creation hero, the composer row, and the flat surface palette. The target frames are checked in underrfc/assets/review-1.4-layouts/(start-workspace-layout.png,start-v2-creation.png,chat-column.png,footer-info-bar.png) and indexed with Figma deep links inrfc/20260725_review-1.4-layouts.md.Implementation
WorkspaceFooterBar(new, bottom of the chat pane): matches the design's item sequence of PR link, git drift, repository, branch, token usage, and last prompt, plus a runtime badge. Repository identity shows the GitHub slug (coder/mux) and falls back to the project hierarchy label until PR detection resolves a remote. The design'sLinesdropdown labels the drift counts and toggles drift mode through the same persisted key as the divergence dialog, so both surfaces stay in sync.Last promptreveals the latest real user prompt via tooltip, backed by a newuseWorkspaceLastUserPromptselector that skips synthetic turns. All items are leaf store subscriptions so per-delta streaming stats never cascade through the transcript.WorkspaceMenuBar: header now reads "Workspace title ⓘ". Project label, workspace name, and path move into the info-icon tooltip; repository controls and the PR badge move to the footer. The header keeps identity + actions only, per the design.ProjectPage: "Let's get building." hero headline above the creation card (design's "start V2" state).ChatInput, shared by the chat and creation surfaces): the agent pill leadsthe row, model and thinking level share one bordered pill split by a divider, the context meter
becomes a labelled pill with its percentage always visible, and send is a filled circle.
#09090b)separated by hairline borders, and that our dark theme already holds those exact values under
different names. So the fix is mostly token swaps, recorded as a mapping table in the RFC:
#1D1D1Dfill and border. It is now transparent inside a singlebordered box that also holds the pill row, so there is no nested box, and that box carries the
amber editing tint that used to sit on the textarea. Since the textarea also loses its focus
border, the box shows that agent-colored focus state instead, keyed off textarea focus so the
pill row's own focus rings do not light up the whole box.
border-medium(#454545) to the same hairline as the box, and thecontext meter track moves from
#1D1D1Dto the sampled#3f3f46.#18181bwhen itcannot. The cyan is a new per-theme
--color-composer-send: the design's accent is not--color-accent's blue, and--color-border-pending(the same cyan today) means "needsattention".
#171717, so it read asa lighter band around a correctly-colored transcript.
--color-sidebarnow resolves to--color-surface-primaryin the dark theme; the light and Flexoki themes keep their ownsidebar fill, since a lighter sidebar is deliberate there and the frames only specify dark.
theme-colormeta tag cannot read CSS variables, so thepalette is duplicated in
src/common/constants/chromeColors.ts(previously three hardcodedcopies: main process,
ThemeContext, andindex.html's pre-JS boot script). It mirrors eachtheme's
--color-sidebar, the fill both surfaces actually sit against, and a test compares itagainst the boot copy, the static meta tag, and
public/manifest.json(the installed PWA'ssplash and OS chrome, which still held the pre-parity
#1e1e1e) so none of them can drift.horizontal scrollbar was consuming 11px of its 28px height (now
scrollbar-none), and footeritems were shrinking instead of being clipped, which collapsed the repo slug to zero width while
its icon stayed (items are now
shrink-0, and the project label caps its width instead). Thecomposer's new bordered box also costs 16px of inner width, which pushed the pill row's 340px
clamp past what a 375px viewport leaves, so the clamp (and its coupled container query) drops to
320px.
App.commandPaletteplay tests were failing on this branch before the parity pass.The header now renders the workspace title that the sidebar row also shows, so
findByTextmatched two elements; the helper waits on all matches instead.
rfc/20260725_review-1.4-layouts.md+rfc/assets/review-1.4-layouts/(25 PNGs, ~960 KB): per-area design reference covering top-level layouts, sidebar states, menus and selectors, chat column + footer, and right panel, each with screenshots, Figma deep links, designer intent notes, a design-to-code mapping table, and tracked not-yet-implemented deviations (Cost tab naming, Explorer tab/Panels button, sidebar Refine, footer configurability, sentence-style creation configurator, header action set, drift glyph style).Validation
WorkspaceMenuBar.test.tsxinto the newWorkspaceFooterBar.test.tsx(scratch / repo-backed / multi-project cases).tests/ui/chatfailures are pre-existing onmainin the dev container (happy-dom color parsing), verified via stash.dev-server-sandboxinstance against the checked-in Figmaexports, at both desktop (1512px) and narrow (375px) widths, including a repo-backed workspace
with a live PR so the slug, drift, and PR badge all render real data.
compared against the rendered
getComputedStylevalue in the dark theme, and the chrome, page,transcript, and composer interior all report
rgb(9, 9, 11). Verified at desktop and phonewidths, in the editing state, and in the light theme. The chrome palette was checked the same way
in all four themes:
--color-sidebarrendersrgb(9, 9, 11),rgb(245, 245, 245),rgb(242, 240, 229),rgb(28, 27, 26), matchingCHROME_COLORSentry for entry.its right edge lands exactly on the box's content edge (send included) with no page overflow, and
390px is unchanged.
FocusedComposerstory asserts the composer's rendered border color changes when thetextarea takes focus, so the box's focus state cannot silently disappear again (and the arbitrary
has-[]variant is proven to compile). It has no Pixel snapshot; the assertion is on computedstyle, not appearance.
WorkspaceFooterBar.test.tsxcovers the repo-slug/project-label fallback branches andlast-prompt gating alongside the existing scratch / repo-backed / multi-project cases.
ProjectPage.autofocus.test.tsxfails on the base branch too (hasConfiguredProviderexportmissing under bun module mocking), verified via stash.
Risks
workspace-menu-bar(tests, tutorials) needs the footer. In-repo references were updated; external automation selecting by test id may need the same.ProjectPage/WorkspaceMenuBarvisual snapshots will shift, as expected. The palette changemakes that much wider: the composer row renders on every screen and the chrome change touches
every
bg-sidebarconsumer, so essentially all dark-theme snapshots move. The full Storybooksuite is at its pre-existing baseline (the same 5
Task/CodeExecutionsmoke tests fail withthese commits stashed, a known local circular-import issue that CI's built Storybook passes).
bg-sidebarconsumers are floating surfaces rather than chrome (the workspace drag ghost,the skill count badge, the SQL samples dropdown). They would have lost contrast against a
page-colored fill, so they move to
bg-dark, the fill the repo's other popovers already use.Linescontrol writes the sharedgitStatusIndicatorModekey, so toggling it in the footeralso changes the sidebar and divergence dialog. That is intentional (one drift mode per user),
but it is a wider blast radius than a footer-local control.
back to the project label otherwise. Reading the slug straight from the git remote needs a new
backend accessor plus a cached store, so it is tracked as a deviation rather than done here.
Initial layout implementation generated with Claude Code; footer,
composer, and palette parity passes done with
muxagainst the checked-in Figma exports.Generated with
mux• Model:anthropic:claude-opus-5• Thinking:max• Cost:$152.25