fix: strengthen quick chat backdrop (#3124)

This commit is contained in:
Carlos Florêncio
2026-08-28 19:22:30 +00:00
committed by GitHub
parent f56fd8e180
commit 2015ecb0cd
8 changed files with 399 additions and 49 deletions
@@ -179,7 +179,7 @@ export const QuickChatModal = memo(function QuickChatModal({ workspaceId }: Quic
className="!left-0 !top-0 !h-dvh !max-h-dvh !w-screen !max-w-none !translate-x-0 !translate-y-0 flex flex-col gap-0 p-0 pt-safe pb-safe shadow-2xl sm:!left-1/2 sm:!top-1/2 sm:!h-[85vh] sm:!max-h-[85vh] sm:!w-[var(--quick-chat-width)] sm:!max-w-[calc(100vw-2rem)] sm:!-translate-x-1/2 sm:!-translate-y-1/2"
style={{ "--quick-chat-width": `${width}px` } as CSSProperties}
showCloseButton={false}
overlayClassName="bg-black/20"
overlayClassName="bg-black/20 sm:bg-black/40 sm:backdrop-blur-sm"
onEscapeKeyDown={(event) => {
// A pending, expanded clarification (or an open suggestion popup,
// or the reverse-search overlay) handles this Escape itself and
@@ -17,6 +17,7 @@ import { assertNoDocumentHorizontalOverflow } from "../../helpers/layout-asserti
const TASK_LISTING_VIEW_STORAGE_KEY = "kandev.taskListing.view.v1";
test.describe("Quick Chat entry points on mobile", () => {
// @covers AC-UI-QUICK-CHAT-ELEVATION-001.4 AC-UI-QUICK-CHAT-ELEVATION-001.7
test("opens from the home header and closes with the touch control", async ({ testPage }) => {
await testPage.goto("/");
await testPage.waitForLoadState("networkidle");
@@ -26,6 +27,17 @@ test.describe("Quick Chat entry points on mobile", () => {
const dialog = testPage.getByRole("dialog", { name: "Quick Chat" });
await expect(dialog.getByTestId("quick-chat-setup")).toBeVisible({ timeout: 10_000 });
const overlay = testPage.locator('[data-slot="dialog-overlay"]');
await expect(overlay).toBeAttached();
const mobileBackdropStyles = await overlay.evaluate((element) => {
const styles = getComputedStyle(element);
return {
backgroundColor: styles.backgroundColor,
backdropFilter: styles.backdropFilter,
};
});
expect(mobileBackdropStyles.backgroundColor).toMatch(/\/\s*0\.2\)/);
expect(mobileBackdropStyles.backdropFilter).toBe("none");
await assertNoDocumentHorizontalOverflow(testPage);
await dialog.getByTestId("quick-chat-close").tap();
+4 -1
View File
@@ -54,18 +54,21 @@ async function dragQuickChatTab(page: Page, source: Locator, target: Locator) {
}
test.describe("Quick Chat", () => {
test("adds elevation when opened over the page", async ({ testPage }) => {
// @covers AC-UI-QUICK-CHAT-ELEVATION-001.1 AC-UI-QUICK-CHAT-ELEVATION-001.2 AC-UI-QUICK-CHAT-ELEVATION-001.5 AC-UI-QUICK-CHAT-ELEVATION-001.6
test("adds a stronger elevation backdrop when opened over the page", async ({ testPage }) => {
const dialog = await openQuickChatSetup(testPage);
const overlay = testPage.locator('[data-slot="dialog-overlay"]');
await expect(overlay).toBeVisible();
const styles = await Promise.all([
overlay.evaluate((element) => getComputedStyle(element).backgroundColor),
overlay.evaluate((element) => getComputedStyle(element).backdropFilter),
dialog.evaluate((element) => getComputedStyle(element).boxShadow),
]);
expect(styles[0]).not.toBe("rgba(0, 0, 0, 0)");
expect(styles[0]).not.toBe("transparent");
expect(styles[1]).not.toBe("none");
expect(styles[2]).not.toBe("none");
await testPage.keyboard.press("Escape");
await expect(dialog).not.toBeVisible();
@@ -0,0 +1,96 @@
---
created: 2026-08-28
status: done
requirements:
- REQ-UI-QUICK-CHAT-ELEVATION-001
system_design:
- ../../specs/ui/system-design/quick-chat-elevation.md
legacy_specs: []
---
# Implementation Plan: Strengthen Quick Chat backdrop
## Overview
Strengthen the backdrop of the shared Quick Chat and Quick Terminal dialog on
tablet and desktop widths. The work is one frontend vertical slice: apply the
surface-local darkening and blur, extend the existing desktop rendered test,
and rerun the existing mobile entry coverage to prove phone behavior remains
unchanged.
## Scope
### In scope
- Make the shared Quick Chat dialog backdrop more visible with darker
semitransparency and light blur on tablet and desktop widths.
- Keep the existing panel shadow, dimensions, position, content, state,
dismissal, and focus behavior unchanged.
- Preserve the existing full-screen phone composition and touch close path.
### Out of scope
- Changing the shared `Dialog` or `DialogOverlay` defaults.
- Changing the separate new-Quick-Chat picker dialog.
- Changing Quick Chat or Quick Terminal state, persistence, content, or tab
behavior.
- Adding a new mobile composition or a user-facing setting.
## Technical approach
Update [`quick-chat-modal.tsx`](../../../apps/web/components/quick-chat/quick-chat-modal.tsx)
to retain `bg-black/20` on phones and use the stronger local overlay class
`sm:bg-black/40 sm:backdrop-blur-sm` from the `sm` breakpoint upward, while
retaining the existing `shadow-2xl` and responsive classes. Extend the existing
elevation test in
[`quick-chat.spec.ts`](../../../apps/web/e2e/tests/chat/quick-chat.spec.ts) to
assert the rendered backdrop filter in addition to its non-transparent
background and the panel shadow. Keep
[`mobile-quick-chat-entry.spec.ts`](../../../apps/web/e2e/tests/chat/mobile-quick-chat-entry.spec.ts)
as the mobile regression suite.
## Tests
| Acceptance criterion | Evidence |
| --- | --- |
| `AC-UI-QUICK-CHAT-ELEVATION-001.1`, `.2`, `.5` | Desktop `Quick Chat` elevation scenario in `apps/web/e2e/tests/chat/quick-chat.spec.ts` |
| `AC-UI-QUICK-CHAT-ELEVATION-001.3`, `.6` | Same desktop scenario after Escape closes the dialog |
| `AC-UI-QUICK-CHAT-ELEVATION-001.4`, `.7` | Existing mobile entry and close scenarios in `apps/web/e2e/tests/chat/mobile-quick-chat-entry.spec.ts` |
## E2E tests
- Desktop: run the existing elevation scenario in `quick-chat.spec.ts` with
the `chromium` project. It verifies the user-visible backdrop and close
lifecycle through the real portal.
- Mobile: run `mobile-quick-chat-entry.spec.ts` with the `mobile-chrome`
project. It verifies the existing phone-native full-screen flow, explicit
close control, and no horizontal overflow.
## Work orders
- [x] [Task 01: Strengthen Quick Chat backdrop](task-01-quick-chat-backdrop-strength.md)
## Verification results
Task 01 completed.
- `cd apps && pnpm install --frozen-lockfile` - passed.
- `pnpm --filter @kandev/web run typecheck` - passed.
- `pnpm e2e:run --project chromium tests/chat/quick-chat.spec.ts -- --grep
"stronger elevation backdrop"` - passed, 1 test.
- `pnpm e2e:run --project mobile-chrome
tests/chat/mobile-quick-chat-entry.spec.ts` - passed, 4 tests.
- RED proof: the desktop test failed before the production class change because
the overlay computed `backdrop-filter` to `none`.
- Review follow-up: phones retain `bg-black/20` with no filter, while the
stronger `sm:bg-black/40 sm:backdrop-blur-sm` treatment starts at `sm`.
- Review follow-up RED proof: the mobile assertion failed against the unscoped
treatment with `oklab(0 0 0 / 0.4)` and `blur(8px)`.
- Focused mobile style regression - passed, 1 test.
## Risks
- A backdrop that is too dark or too blurred can reduce page context. Keep the
panel readable and use the existing restrained design-system treatment.
- The overlay must remain scoped to the shared Quick Chat surface so other
dialogs and the separate picker do not change.
@@ -0,0 +1,121 @@
---
id: "01-quick-chat-backdrop-strength"
title: "Strengthen Quick Chat backdrop"
status: done
wave: 1
depends_on: []
plan: "plan.md"
requirements:
- REQ-UI-QUICK-CHAT-ELEVATION-001
acceptance_criteria:
- AC-UI-QUICK-CHAT-ELEVATION-001.1
- AC-UI-QUICK-CHAT-ELEVATION-001.2
- AC-UI-QUICK-CHAT-ELEVATION-001.3
- AC-UI-QUICK-CHAT-ELEVATION-001.4
- AC-UI-QUICK-CHAT-ELEVATION-001.5
- AC-UI-QUICK-CHAT-ELEVATION-001.6
- AC-UI-QUICK-CHAT-ELEVATION-001.7
system_design:
- ../../specs/ui/system-design/quick-chat-elevation.md
---
# Task 01: Strengthen Quick Chat backdrop
## Summary
Apply a stronger, surface-local backdrop treatment to the shared Quick Chat
dialog so conversations and Quick Terminal tabs read as elevated on tablet and
desktop pages. Extend the existing desktop rendered regression and run the
existing mobile Quick Chat scenarios to preserve the full-screen phone flow.
## In scope
- Update the `DialogContent` overlay class in
`apps/web/components/quick-chat/quick-chat-modal.tsx`.
- Extend the existing elevation scenario in
`apps/web/e2e/tests/chat/quick-chat.spec.ts` to cover light backdrop blur.
- Verify the existing mobile entry, close, containment, and overflow behavior.
## Out of scope
- Changing shared dialog primitives or unrelated dialog overlays.
- Changing the new-Quick-Chat picker, Quick Chat state, terminal state, tab
behavior, or mobile composition.
## Acceptance
1. Tablet and desktop Quick Chat opens above a clearly visible darkened and
lightly blurred backdrop while its existing panel shadow and geometry remain
unchanged.
2. Closing Quick Chat removes the dialog and backdrop, preserving the current
focus and interaction lifecycle.
3. The existing mobile Quick Chat entry and explicit close control remain
usable with no document horizontal overflow.
## Verification
```bash
cd apps && pnpm install --frozen-lockfile
pnpm --filter @kandev/web run typecheck
cd web
pnpm e2e:run --project chromium tests/chat/quick-chat.spec.ts -- --grep "elevation"
pnpm e2e:run --project mobile-chrome tests/chat/mobile-quick-chat-entry.spec.ts
```
The desktop rendered assertion should be run RED before the overlay class is
changed, then GREEN after the minimal frontend change. The managed E2E runner
rebuilds production assets before browser verification.
## Files likely touched
- `apps/web/components/quick-chat/quick-chat-modal.tsx`
- `apps/web/e2e/tests/chat/quick-chat.spec.ts`
Existing mobile evidence:
- `apps/web/e2e/tests/chat/mobile-quick-chat-entry.spec.ts`
## Dependencies
None.
## Risks
- Keep the stronger treatment scoped to `QuickChatModal`; do not alter global
dialog defaults or the separate picker dialog.
- Avoid changing the phone full-screen geometry because the panel naturally
covers the backdrop there.
## Parallelism
`sequential`
## Inputs
- `docs/specs/ui/requirements/quick-chat-elevation.md`
- `docs/specs/ui/system-design/quick-chat-elevation.md`
- `docs/plans/quick-chat-backdrop-strength/plan.md`
- `apps/web/AGENTS.md`
- `.agents/skills/e2e/SKILL.md`
- `.agents/skills/mobile-parity/SKILL.md`
## Results
Implemented the responsive surface-local
`bg-black/20 sm:bg-black/40 sm:backdrop-blur-sm` treatment in `QuickChatModal`,
extended the desktop rendered regression to assert the backdrop filter, and
added a mobile regression for the lighter no-filter phone treatment.
Verification passed:
- `pnpm --filter @kandev/web run typecheck`
- Desktop elevation E2E: 1 test passed.
- Mobile Quick Chat E2E: 4 tests passed.
- Focused mobile backdrop E2E: 1 test passed.
The desktop regression was confirmed RED before the production class change:
the computed overlay filter was `none`.
The mobile regression was confirmed RED against the unscoped treatment: the
computed backdrop was `oklab(0 0 0 / 0.4)` with `blur(8px)` instead of the
lighter phone treatment.
+1
View File
@@ -167,6 +167,7 @@ system. The UI system owns only independent, reusable presentation contracts.
- [Sidebar Task Focus](system-design/sidebar-task-focus.md)
- [PR Task Status Summary](system-design/pr-task-status-summary.md)
- [Prompt History Panel](system-design/prompt-history-panel.md)
- [Quick Chat and terminal elevation](system-design/quick-chat-elevation.md)
- [Quick Chat and Terminal Tabs](system-design/quick-terminal.md)
- [Responsive Plan Formatting](system-design/responsive-plan-formatting.md)
- [Task Confirmation Warning Hierarchy](system-design/confirmation-warning-hierarchy.md)
@@ -2,67 +2,70 @@
status: active
system: ui
created: 2026-08-04
updated: 2026-08-28
owners:
- kandev
---
# Quick Chat elevation Requirements
# Quick Chat and terminal elevation Requirements
## Overview
Quick Chat opens over the current page with a transparent backdrop, so the floating panel can blend into the page and its opened state is not immediately clear. Users need a restrained visual separation that makes the panel feel elevated while preserving the surrounding page as context.
The shared Quick Chat surface opens over the current page and can show either a
conversation or a Quick Terminal tab. Its current backdrop is too weak on
dark pages, so the open state is not immediately clear. Users need a stronger
but restrained visual separation that preserves the surrounding page as
context.
The UI system owns this presentation contract because the backdrop, panel
elevation, responsive geometry, and dismissal behavior are independent of the
conversation and terminal state owned by other systems.
## Terminology
- **Quick Chat surface:** The shared responsive dialog rendered by
`QuickChatModal` for conversations and Quick Terminal tabs.
- **Backdrop treatment:** The semitransparent darkening and light blur rendered
behind the Quick Chat surface on tablet and desktop widths.
## Requirements
### REQ-UI-QUICK-CHAT-ELEVATION-001: Quick Chat elevation
**Intent:** Quick Chat opens over the current page with a transparent backdrop, so the floating panel can blend into the page and its opened state is not immediately clear. Users need a restrained visual separation that makes the panel feel elevated while preserving the surrounding page as context.
**Intent:** The shared Quick Chat surface must read as an elevated temporary
surface without removing the current page from view.
#### Acceptance criteria
- **AC-UI-QUICK-CHAT-ELEVATION-001.1:** When Quick Chat opens at tablet or desktop widths, the page behind it is visually de-emphasized by a subtle semitransparent backdrop.
- **AC-UI-QUICK-CHAT-ELEVATION-001.2:** The Quick Chat panel remains above the backdrop with its existing elevation shadow, dimensions, position, content, and interaction behavior unchanged.
- **AC-UI-QUICK-CHAT-ELEVATION-001.3:** Closing Quick Chat removes the backdrop and restores the page's normal appearance and interaction.
- **AC-UI-QUICK-CHAT-ELEVATION-001.4:** On phone widths, Quick Chat keeps its existing full-screen composition, explicit close control, and viewport containment. The backdrop does not need to be visible because the panel covers the viewport.
- **AC-UI-QUICK-CHAT-ELEVATION-001.5:** **GIVEN** Quick Chat is closed on a tablet or desktop viewport, **WHEN** the user opens Quick Chat, **THEN** the Quick Chat dialog is visible above a non-transparent backdrop and its computed panel shadow is not `none`.
- **AC-UI-QUICK-CHAT-ELEVATION-001.6:** **GIVEN** Quick Chat is open on a tablet or desktop viewport, **WHEN** the user closes it, **THEN** the dialog and backdrop are removed so the page is fully visible again.
- **AC-UI-QUICK-CHAT-ELEVATION-001.7:** **GIVEN** a phone viewport, **WHEN** the user opens Quick Chat from an existing mobile entry point, **THEN** the full-screen dialog remains usable, the explicit close control remains reachable, and the document has no horizontal overflow.
## Migrated source detail
## Why
Quick Chat opens over the current page with a transparent backdrop, so the floating panel can
blend into the page and its opened state is not immediately clear. Users need a restrained visual
separation that makes the panel feel elevated while preserving the surrounding page as context.
## What
- When Quick Chat opens at tablet or desktop widths, the page behind it is visually de-emphasized by
a subtle semitransparent backdrop.
- The Quick Chat panel remains above the backdrop with its existing elevation shadow, dimensions,
position, content, and interaction behavior unchanged.
- Closing Quick Chat removes the backdrop and restores the page's normal appearance and interaction.
- On phone widths, Quick Chat keeps its existing full-screen composition, explicit close control,
and viewport containment. The backdrop does not need to be visible because the panel covers the
viewport.
## Scenarios
- **GIVEN** Quick Chat is closed on a tablet or desktop viewport, **WHEN** the user opens Quick Chat,
**THEN** the Quick Chat dialog is visible above a non-transparent backdrop and its computed panel
shadow is not `none`.
- **GIVEN** Quick Chat is open on a tablet or desktop viewport, **WHEN** the user closes it,
**THEN** the dialog and backdrop are removed so the page is fully visible again.
- **GIVEN** a phone viewport, **WHEN** the user opens Quick Chat from an existing mobile entry
point, **THEN** the full-screen dialog remains usable, the explicit close control remains
reachable, and the document has no horizontal overflow.
- **AC-UI-QUICK-CHAT-ELEVATION-001.1:** When the Quick Chat surface opens at
tablet or desktop widths, the page behind it shall be visibly de-emphasized
by a dark semitransparent backdrop with a light background blur.
- **AC-UI-QUICK-CHAT-ELEVATION-001.2:** The Quick Chat surface shall remain
above the backdrop with its existing elevation shadow, dimensions, position,
content, and interaction behavior unchanged.
- **AC-UI-QUICK-CHAT-ELEVATION-001.3:** When Quick Chat closes, the system shall
remove the backdrop and restore the page's normal appearance and interaction.
- **AC-UI-QUICK-CHAT-ELEVATION-001.4:** On phone widths, Quick Chat shall keep
its existing full-screen composition, explicit close control, and viewport
containment. The backdrop does not need to be visible because the panel
covers the viewport.
- **AC-UI-QUICK-CHAT-ELEVATION-001.5:** **GIVEN** Quick Chat is closed on a
tablet or desktop viewport, **WHEN** the user opens Quick Chat, **THEN** the
dialog shall be visible above a non-transparent backdrop with a non-default
background filter, and its computed panel shadow shall not be `none`.
- **AC-UI-QUICK-CHAT-ELEVATION-001.6:** **GIVEN** Quick Chat is open on a
tablet or desktop viewport, **WHEN** the user closes it, **THEN** the dialog
and backdrop shall be removed so the page is fully visible again.
- **AC-UI-QUICK-CHAT-ELEVATION-001.7:** **GIVEN** a phone viewport, **WHEN** the
user opens Quick Chat from an existing mobile entry point, **THEN** the
full-screen dialog shall remain usable, the explicit close control shall
remain reachable, and the document shall have no horizontal overflow.
## Out of scope
- Changing Quick Chat size, position, responsive composition, content, sessions, or persistence.
- Adding a new backdrop component, user setting, animation, or navigation behavior.
- Changing the separate new-Quick-Chat picker dialog or configuration-chat popover.
## Implementation plan
[Quick Chat elevation implementation](../../../plans/quick-chat-elevation/plan.md)
- Changing Quick Chat size, position, responsive composition, content, tabs,
sessions, or persistence.
- Adding a new backdrop component, user setting, animation, or navigation
behavior.
- Changing the separate new-Quick-Chat picker dialog or configuration-chat
popover.
- Changing the shared `Dialog` or `DialogOverlay` defaults for other dialogs.
@@ -0,0 +1,114 @@
---
status: current
system: ui
requirements:
- REQ-UI-QUICK-CHAT-ELEVATION-001
---
# Quick Chat and terminal elevation System Design
## Purpose and boundaries
The UI system owns the visual elevation contract for the shared Quick Chat
surface. `QuickChatModal` presents ordinary conversations, configuration
conversations, and Quick Terminal tabs through one responsive Radix dialog.
Conversation lifecycle, terminal lifecycle, workspace scoping, and persisted
tab order remain owned by their existing systems. The separate new-Quick-Chat
picker is not part of this design.
## Requirement mapping
| Requirement | Design sections |
| --- | --- |
| `REQ-UI-QUICK-CHAT-ELEVATION-001` | [Surface composition](#surface-composition), [Responsive behavior](#responsive-behavior), [Verification](#verification) |
## Components and responsibilities
- [`QuickChatModal`](../../../../apps/web/components/quick-chat/quick-chat-modal.tsx)
owns the shared dialog composition and passes the local backdrop treatment
to `DialogContent`.
- [`DialogContent`](../../../../apps/packages/ui/src/dialog.tsx) owns the Radix
portal, overlay placement, focus management, dismissal, and panel stacking.
Its global overlay default is unchanged.
- `QuickChatContent` and the existing tab/content components keep ownership of
conversation and terminal rendering. They do not receive backdrop state.
- The existing mobile tab-strip close control remains the explicit close path
for the phone composition.
## Surface composition
`QuickChatModal` continues to render the shared `DialogContent` with its
existing responsive geometry and `shadow-2xl` panel elevation. It supplies a
surface-local responsive overlay class that keeps the existing lighter phone
layer and combines a stronger dark layer with a light background blur from the
`sm` breakpoint upward, such as
`bg-black/20 sm:bg-black/40 sm:backdrop-blur-sm`.
The class is applied only through this `DialogContent` instance. The shared
`DialogOverlay` default and unrelated dialogs remain unchanged. The overlay
continues to cover the page and block interaction below the dialog through the
existing Radix modal behavior.
## Control flow
1. A Quick Chat or Quick Terminal launcher updates the existing Quick Chat
state to open the shared dialog.
2. Radix mounts the overlay and dialog in the existing portal. The overlay
darkens and lightly blurs the page, while the panel remains above it.
3. Tab selection, terminal input, conversation input, and all existing close
handlers continue to operate inside the unchanged panel content.
4. Escape or an explicit close action changes the existing open state to
closed. Radix removes the overlay and content and restores focus through
the existing dialog lifecycle.
## Responsive behavior
At tablet and desktop widths, the overlay is visible around the centered,
resizable panel. The backdrop treatment does not change panel dimensions,
position, content scroll ownership, or pointer and keyboard behavior.
At phone widths, the panel remains `h-dvh`, `w-screen`, and full-screen with
its existing safe-area padding. The panel covers the backdrop, so the contract
checks phone usability, the explicit close control, viewport containment, and
zero document-level horizontal overflow rather than expecting visible page
dimming.
The nearest shipped mobile exemplar is the existing Quick Chat mobile entry
flow in
[`mobile-quick-chat-entry.spec.ts`](../../../../apps/web/e2e/tests/chat/mobile-quick-chat-entry.spec.ts),
which proves the full-screen dialog, touch close control, and overflow
behavior. This styling change does not introduce a new mobile composition or
touch interaction.
## Failure and recovery
If a browser does not support backdrop filters, the dark semitransparent layer
still provides the required separation. No fallback changes dialog state,
focus return, Escape handling, or page interaction blocking.
## State and persistence
No new state, API, persistence, or migration is introduced. The overlay exists
only while the existing Quick Chat dialog is open.
## Security and accessibility
The existing Radix modal overlay remains the interaction barrier. The change
does not add an independently interactive element, alter focus trapping, or
change accessible names and close controls.
## Verification
- The desktop Quick Chat E2E scenario opens the existing setup flow and checks
that the portaled overlay has a non-transparent background and non-default
backdrop filter, that the panel shadow remains, and that closing removes
both surfaces.
- The existing mobile Quick Chat E2E scenarios remain the evidence for the
phone entry point, full-screen close control, and document overflow.
- The focused component test suite remains unchanged because the behavior is
owned by the real Radix rendering path and is verified through Playwright.
## Related decisions
None. This is a local styling change within the existing dialog contract.