diff --git a/apps/web/components/quick-chat/quick-chat-modal.tsx b/apps/web/components/quick-chat/quick-chat-modal.tsx index 96656f4b9c..cc09086aff 100644 --- a/apps/web/components/quick-chat/quick-chat-modal.tsx +++ b/apps/web/components/quick-chat/quick-chat-modal.tsx @@ -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 diff --git a/apps/web/e2e/tests/chat/mobile-quick-chat-entry.spec.ts b/apps/web/e2e/tests/chat/mobile-quick-chat-entry.spec.ts index 1ab7d1e8d6..8f232ec3d3 100644 --- a/apps/web/e2e/tests/chat/mobile-quick-chat-entry.spec.ts +++ b/apps/web/e2e/tests/chat/mobile-quick-chat-entry.spec.ts @@ -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(); diff --git a/apps/web/e2e/tests/chat/quick-chat.spec.ts b/apps/web/e2e/tests/chat/quick-chat.spec.ts index f78a79e387..58c882a082 100644 --- a/apps/web/e2e/tests/chat/quick-chat.spec.ts +++ b/apps/web/e2e/tests/chat/quick-chat.spec.ts @@ -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(); diff --git a/docs/plans/quick-chat-backdrop-strength/plan.md b/docs/plans/quick-chat-backdrop-strength/plan.md new file mode 100644 index 0000000000..64dd784c32 --- /dev/null +++ b/docs/plans/quick-chat-backdrop-strength/plan.md @@ -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. diff --git a/docs/plans/quick-chat-backdrop-strength/task-01-quick-chat-backdrop-strength.md b/docs/plans/quick-chat-backdrop-strength/task-01-quick-chat-backdrop-strength.md new file mode 100644 index 0000000000..dca318723b --- /dev/null +++ b/docs/plans/quick-chat-backdrop-strength/task-01-quick-chat-backdrop-strength.md @@ -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. diff --git a/docs/specs/ui/README.md b/docs/specs/ui/README.md index 946bc89bdc..f856689368 100644 --- a/docs/specs/ui/README.md +++ b/docs/specs/ui/README.md @@ -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) diff --git a/docs/specs/ui/requirements/quick-chat-elevation.md b/docs/specs/ui/requirements/quick-chat-elevation.md index 2448e64b8a..1182034ffd 100644 --- a/docs/specs/ui/requirements/quick-chat-elevation.md +++ b/docs/specs/ui/requirements/quick-chat-elevation.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. diff --git a/docs/specs/ui/system-design/quick-chat-elevation.md b/docs/specs/ui/system-design/quick-chat-elevation.md new file mode 100644 index 0000000000..b0e4a86950 --- /dev/null +++ b/docs/specs/ui/system-design/quick-chat-elevation.md @@ -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.