diff --git a/docs/UI_MODERNIZATION_AUDIT.md b/docs/UI_MODERNIZATION_AUDIT.md index 05f589f..dca6b8d 100644 --- a/docs/UI_MODERNIZATION_AUDIT.md +++ b/docs/UI_MODERNIZATION_AUDIT.md @@ -1,6 +1,6 @@ # Cortex UI modernization audit -**Status:** UI modernization implementation complete for this slice; dedicated image-editor affordances removed; native package rebuilt and startup-verified +**Status:** UI modernization follow-up complete; dedicated image-editor affordances and preset prompt cards removed; native package rebuilt and startup-verified **Scope:** Every user-facing frontend surface, not a cosmetic theme pass ## What was audited @@ -18,7 +18,7 @@ primary problems were structural: | Area | Finding | Modernization outcome | | --- | --- | --- | | Workspace shell | The top bar conveyed almost no context and the sidebar was a loose list of text. | A clear workspace header, local-runtime status, product identity, conversation count, and a deliberate sidebar footer establish hierarchy. | -| Conversation canvas | A new chat opened into a large, empty dark region. | A compact new-thread orientation gives the canvas a clear starting point without turning it into a marketing screen. | +| Conversation canvas | A new chat opened into a large, empty dark region, then introduced generic preset prompts. | A quiet new-thread orientation gives the canvas context while leaving the user in control of the first message. | | Composer | The input was visually stranded in a full-width bottom strip. | The composer is now a centered, elevated input island with integrated local-model context, state feedback, and responsive sizing. | | Conversation controls | Saved chats, rename, and delete controls had weak grouping and feedback. | The list uses active/hover/focus states, reveal-on-focus actions, and purposeful confirmation dialogs. | | Settings and submenus | Settings read as a large collection of unrelated boxes. | Text-led categories, descriptive labels, and a unified detail pane make settings read like a native control surface. | @@ -53,7 +53,8 @@ opaque background service. runtime state, conversation navigation, and better destructive-action dialogs. - `frontend/src/components/ChatPage.tsx` adds the intentional blank-chat launch surface and docks the composer as part of the conversation canvas. It does - not advertise image transformation or image generation. + not advertise image transformation, image generation, or preset prompt + suggestions. - `frontend/src/components/MessageComposer.tsx` integrates local-model context into the composer island. - `frontend/src/components/SettingsPanel.tsx` turns settings into a structured @@ -77,7 +78,7 @@ This slice passed the release checks: 44 component tests in a single worker, 6 browser-level flows, typecheck, lint, production build, a fresh Windows package build, and a packaged launch with `GET /api/v1/health/ready` returning HTTP 200. The production bundle contains no dedicated image-transform UI -labels or selectors. +labels or selectors, and no preset starter-card selectors or labels. During the audit, the existing packaged executable exposed a separate native startup defect: Uvicorn's default console formatter dereferenced `sys.stderr` diff --git a/frontend/src/components/ChatPage.test.tsx b/frontend/src/components/ChatPage.test.tsx index 2f593ce..69bc645 100644 --- a/frontend/src/components/ChatPage.test.tsx +++ b/frontend/src/components/ChatPage.test.tsx @@ -61,14 +61,14 @@ function renderChat(api: CortexApi, threadId = "thread-a") { describe("ChatPage composer integration", () => { afterEach(() => window.sessionStorage.clear()); - it("turns a blank conversation into a useful starting surface", async () => { - const user = userEvent.setup(); + it("keeps a blank conversation free of preset prompt suggestions", async () => { renderChat(chatApi()); await screen.findByRole("heading", { name: "New thread" }); - await user.click(screen.getByRole("button", { name: /Think through a decision/i })); - expect(screen.getByLabelText("Message Cortex")).toHaveValue("Help me think through a decision step by step."); + expect(screen.queryByText("Think through a decision")).not.toBeInTheDocument(); + expect(screen.queryByText("Check a calculation")).not.toBeInTheDocument(); + expect(screen.getByLabelText("Message Cortex")).toHaveValue(""); }); it("retains the exact draft if generation acceptance fails", async () => { diff --git a/frontend/src/components/ChatPage.tsx b/frontend/src/components/ChatPage.tsx index 11c796e..4e90da8 100644 --- a/frontend/src/components/ChatPage.tsx +++ b/frontend/src/components/ChatPage.tsx @@ -391,16 +391,6 @@ export function ChatPage({

Ask a question or check a calculation using the model on this device.

-
- - -
{selectedModel && {selectedModel}} )} diff --git a/frontend/src/styles/tokens.css b/frontend/src/styles/tokens.css index 0cd4480..b138516 100644 --- a/frontend/src/styles/tokens.css +++ b/frontend/src/styles/tokens.css @@ -265,13 +265,6 @@ a { color: inherit; text-decoration: none; } .chat-welcome-mark { display: none; } .chat-welcome h1 { max-width: 560px; margin: 0; color: var(--text); font-size: clamp(1.35rem, 2vw, 1.65rem); font-weight: 650; letter-spacing: -0.04em; line-height: 1.15; } .chat-welcome > p:not(.eyebrow) { max-width: 500px; margin: 11px 0 23px; color: var(--text-muted); font-size: 0.86rem; line-height: 1.65; } -.chat-starter-list { display: grid; width: min(100%, 580px); border-top: 1px solid var(--line); text-align: left; } -.chat-starter-list button { display: grid; grid-template-columns: 34px minmax(0, 1fr); align-items: start; min-height: 65px; gap: 9px; border: 0; border-bottom: 1px solid var(--line); padding: 13px 3px; background: transparent; color: var(--text-muted); text-align: left; transition: background 150ms ease, color 150ms ease; } -.chat-starter-list button:hover { background: var(--surface-soft); color: var(--text); } -.chat-starter-list button > span:not(.chat-starter-index) { display: grid; gap: 3px; min-width: 0; } -.chat-starter-index { color: var(--accent); font-family: "Cascadia Code", "SFMono-Regular", Consolas, monospace; font-size: 0.65rem; line-height: 1.6; } -.chat-starter-list strong { color: var(--text); font-size: 0.78rem; font-weight: 660; } -.chat-starter-list small { color: var(--text-muted); font-size: 0.71rem; line-height: 1.45; } .chat-welcome-model { margin-top: 14px; color: var(--text-faint); font-family: "Cascadia Code", "SFMono-Regular", Consolas, monospace; font-size: 0.67rem; } .message-card { display: flex; flex-direction: column; width: min(100%, 760px); max-width: 100%; } @@ -481,8 +474,6 @@ input[type="range"] { width: 100%; accent-color: var(--accent); } @media (max-width: 920px) { .runtime-status { display: none; } - .chat-starter-list { max-width: 100%; } - .chat-starter-list button { min-height: 64px; } .settings-dialog { width: min(100%, 860px); } .settings-dialog-body { grid-template-columns: 190px minmax(0, 1fr); } }