docs(14.1-ui): define cloud local parity contract
This commit is contained in:
@@ -0,0 +1,223 @@
|
|||||||
|
---
|
||||||
|
phase: 14.1
|
||||||
|
slug: cloud-local-file-parity-hardening
|
||||||
|
status: draft
|
||||||
|
shadcn_initialized: false
|
||||||
|
preset: none
|
||||||
|
created: 2026-06-26
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 14.1 — UI Design Contract
|
||||||
|
|
||||||
|
> Visual and interaction contract for frontend phases. Generated by gsd-ui-researcher, verified by gsd-ui-checker.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Design System
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| Tool | none |
|
||||||
|
| Preset | not applicable |
|
||||||
|
| Component library | none — custom Vue components styled with Tailwind utilities |
|
||||||
|
| Icon library | local `AppIcon` stroke set plus existing inline loading spinner |
|
||||||
|
| Font | Tailwind default sans / system UI stack |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Spacing Scale
|
||||||
|
|
||||||
|
Declared values (must be multiples of 4):
|
||||||
|
|
||||||
|
| Token | Value | Usage |
|
||||||
|
|-------|-------|-------|
|
||||||
|
| xs | 4px | Icon gaps, inline badge spacing |
|
||||||
|
| sm | 8px | Compact control spacing, pill padding |
|
||||||
|
| md | 16px | Default control gaps, card padding increments |
|
||||||
|
| lg | 24px | Section padding, header/action separation |
|
||||||
|
| xl | 32px | Page gutters on desktop detail views |
|
||||||
|
| 2xl | 48px | Major section separation |
|
||||||
|
| 3xl | 64px | Reserved for full-page spacing only |
|
||||||
|
|
||||||
|
Exceptions: `36px` minimum dense icon-button targets inside `StorageBrowser.vue` rows; `44px` minimum for modal and confirmation actions; sticky browser headers keep `12px` vertical padding with `16px` mobile and `24px` desktop horizontal padding.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Typography
|
||||||
|
|
||||||
|
| Role | Size | Weight | Line Height |
|
||||||
|
|------|------|--------|-------------|
|
||||||
|
| Body | 14px | 400 | 1.5 |
|
||||||
|
| Label | 12px | 600 | 1.4 |
|
||||||
|
| Heading | 18px | 600 | 1.2 |
|
||||||
|
| Display | 24px | 600 | 1.2 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Color
|
||||||
|
|
||||||
|
| Role | Value | Usage |
|
||||||
|
|------|-------|-------|
|
||||||
|
| Dominant (60%) | `#F9FAFB` | App background, empty areas, muted surfaces |
|
||||||
|
| Secondary (30%) | `#FFFFFF` | Cards, sticky browser header, detail panels, sidebars |
|
||||||
|
| Accent (10%) | `#4F46E5` | Primary actions, active navigation, focus rings, selected states |
|
||||||
|
| Destructive | `#DC2626` | Delete and irreversible confirmations only |
|
||||||
|
|
||||||
|
Accent reserved for: primary preview/open/analyze controls, active breadcrumb/tree states, selection highlights, inline links, and focus indicators. Provider identity uses `providerColor()` / `providerBg()` only in compact metadata chips or icons; it must never recolor the whole detail surface.
|
||||||
|
|
||||||
|
Warning and stale states use the existing amber family (`amber-50/200/500/800`), success uses green, and failure uses red. These semantic colors stay secondary to the indigo accent.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Copywriting Contract
|
||||||
|
|
||||||
|
| Element | Copy |
|
||||||
|
|---------|------|
|
||||||
|
| Primary CTA | `Analyze file` when no analysis exists; otherwise the first content action is `Preview` or `Open` and analysis becomes `Re-analyze` |
|
||||||
|
| Empty state heading | `No analysis yet` |
|
||||||
|
| Empty state body | `Analyze this file to extract text and topics.` Follow with a subtle source note for cloud files: `Preview, download, and analysis still run through DocuVault.` |
|
||||||
|
| Error state | `This file could not be fully analyzed.` Follow with the next step: `Retry analysis or re-analyze to refresh the result.` |
|
||||||
|
| Destructive confirmation | `Re-analyze this file? Existing extracted text and topics stay visible until the new analysis finishes.` |
|
||||||
|
|
||||||
|
Visible copy rule: user-facing text must say `Re-analyze` everywhere. `Re-classify` is not allowed in rendered UI.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Registry Safety
|
||||||
|
|
||||||
|
| Registry | Blocks Used | Safety Gate |
|
||||||
|
|----------|-------------|-------------|
|
||||||
|
| shadcn official | none | not applicable |
|
||||||
|
| Third-party registries | none | no third-party registry use is permitted for this phase |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Shared Surface Contract
|
||||||
|
|
||||||
|
| Surface | Contract |
|
||||||
|
|---------|----------|
|
||||||
|
| Browser | `StorageBrowser.vue` remains the single file browser for local and cloud rows/cards. No parallel grid, card stack, or cloud-only action strip may be introduced. |
|
||||||
|
| Detail | Extract a shared detail surface from `DocumentView.vue`; local and cloud detail routes become thin data providers that pass props and handle emitted actions. |
|
||||||
|
| Source metadata | Cloud ownership is communicated only through subtle metadata: provider chip, location line, and current/stale status. The cloud detail view must not look like a separate product surface. |
|
||||||
|
| Status translation | `cloudConnections.translateAnalysisStatus()` is the single analysis-status translation source. Components do not translate statuses locally. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Route And Navigation Contract
|
||||||
|
|
||||||
|
1. Local document navigation stays at `/document/:id`.
|
||||||
|
2. Cloud rows open a dedicated detail route, named `cloud-file-detail` or an equivalent explicit named route under `/cloud/:connectionId/...`.
|
||||||
|
3. Cloud route params use `connectionId` plus opaque provider item identity. Vue Router handles encoding; frontend code must not split or infer structure from provider IDs.
|
||||||
|
4. Clicking a cloud row opens detail first. It does not auto-preview and does not auto-download.
|
||||||
|
5. Preview/Open and Download are explicit actions from the detail header and any mirrored row action slots.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Browser Parity Contract
|
||||||
|
|
||||||
|
| Element | Rule |
|
||||||
|
|--------|------|
|
||||||
|
| Row click | Local and cloud file rows both navigate to a detail view. |
|
||||||
|
| File title area | Filename on the first line, topic badges directly beneath when present, action affordance inline with the title row. |
|
||||||
|
| Analysis affordance | Analyze / Re-analyze / Retry analysis occupies the same relative slot for local and cloud rows. Cloud-specific affordances stay inline in the name cell rather than moving into a separate cloud-only toolbar. |
|
||||||
|
| Status badges | Current, stale, queued, working, failed, and skipped badges appear in the same relative zone across local and cloud rows. Use green for current, amber for stale/skipped, blue or violet for active work, red for failure. |
|
||||||
|
| Disabled actions | Unsupported preview/download/analyze actions stay in the same action positions and use shared disabled styling plus a backend-provided reason. |
|
||||||
|
| Selection styling | Cloud multi-select keeps the existing violet selection treatment. Introducing a second color language for cloud parity is not allowed. |
|
||||||
|
|
||||||
|
Row density stays unchanged: text remains `14px`, metadata remains `12px`, and icon buttons keep the existing dense treatment.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Detail Layout Contract
|
||||||
|
|
||||||
|
The shared detail surface uses this section order for both local and cloud files:
|
||||||
|
|
||||||
|
1. Back navigation
|
||||||
|
2. Header block: filename, metadata line, subtle source metadata, primary action cluster
|
||||||
|
3. Status and source notice area
|
||||||
|
4. Topics section
|
||||||
|
5. Extracted text section
|
||||||
|
6. Secondary controls and inline error/help copy
|
||||||
|
|
||||||
|
Header rules:
|
||||||
|
|
||||||
|
- Display title uses `24px` semibold with wrapping allowed for long filenames.
|
||||||
|
- Metadata line stays `12-14px` muted gray and includes date, size, and MIME/type information.
|
||||||
|
- Cloud-specific source metadata is a low-emphasis secondary line or compact chip group below the metadata line.
|
||||||
|
- Primary action cluster aligns right on desktop, stacks below the title on narrow screens, and keeps the content action before analysis actions.
|
||||||
|
|
||||||
|
Card rules:
|
||||||
|
|
||||||
|
- Detail sections stay white with `border-gray-200` and `rounded-xl`.
|
||||||
|
- Internal section padding is `20-24px`.
|
||||||
|
- Section headings use `18px` semibold for top-level detail sections and `14px` semibold for compact labels.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Detail State Contract
|
||||||
|
|
||||||
|
| State | Required UI |
|
||||||
|
|-------|-------------|
|
||||||
|
| Not analyzed | Show the shared detail shell, `Analyze file` as the primary analysis CTA, empty topics copy, and empty extracted-text copy. Cloud source metadata is still visible. |
|
||||||
|
| Queued / downloading / extracting / classifying | Show a working status badge and progress copy. Existing extracted text/topics remain visible if they already exist. Do not blank the page while work runs. |
|
||||||
|
| Indexed / current | Show topics, extracted text, content actions, and a secondary `Re-analyze` action. |
|
||||||
|
| Stale | Keep prior extracted text and topics visible, add an amber stale badge/banner, and promote `Re-analyze` to the primary analysis action. |
|
||||||
|
| Partial result | Render any successful section normally and place the failure message plus `Retry analysis` beside the failed section. Example: extracted text present, topics section failed. |
|
||||||
|
| Failed with no usable data | Show the shared error treatment inside the detail surface and expose `Retry analysis` in the same action slot used by `Analyze file` / `Re-analyze`. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Preview, Download, And Unsupported-State Contract
|
||||||
|
|
||||||
|
1. Preview and Download stay adjacent in the detail header action cluster.
|
||||||
|
2. If preview is supported, `Preview` or `Open` is the first content action.
|
||||||
|
3. If preview is unsupported but download is supported, Preview remains visible but disabled, with helper copy `Preview unavailable` plus the backend reason. Download remains active.
|
||||||
|
4. Preview never triggers an automatic download.
|
||||||
|
5. No cloud UI may expose provider URLs, provider hostnames, raw tokens, or cache object keys.
|
||||||
|
6. Any content action copy that differs between local and cloud must be justified by ownership or capability, not by layout convenience.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Re-Analyze And Retry Contract
|
||||||
|
|
||||||
|
1. `Re-analyze` is the label for explicit refresh of an already-analyzed file in both local and cloud detail/browser surfaces.
|
||||||
|
2. Re-analyzing a current cloud file requires confirmation using the copy in the Copywriting Contract.
|
||||||
|
3. `Retry analysis` is reserved for failed work. It must not be used for current or stale-but-readable results.
|
||||||
|
4. `Analyze file`, `Retry analysis`, and `Re-analyze` occupy one shared action slot per surface; they swap by state instead of accumulating as separate buttons.
|
||||||
|
5. When a retry or re-analyze starts, the previous extracted text and topics remain visible until new results replace them.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Accessibility And Feedback Contract
|
||||||
|
|
||||||
|
1. Dense row icon buttons may use `36px` targets; modal, footer, and primary actions use `44px` minimum targets.
|
||||||
|
2. Disabled actions must remain keyboard-focusable only when they can surface an explanatory reason; otherwise they are non-interactive and accompanied by inline explanatory text.
|
||||||
|
3. Status banners use semantic color plus icon plus text; color alone is insufficient.
|
||||||
|
4. Focus indicators use the indigo ring pattern already present in the app.
|
||||||
|
5. Long filenames, provider locations, and error reasons must wrap instead of truncating inside the detail header and status areas.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verification Anchors
|
||||||
|
|
||||||
|
The implementation must be testable against these UI outcomes:
|
||||||
|
|
||||||
|
- Paired local/cloud browser assertions verify identical row title structure, topic placement, status placement, and analysis-action slots.
|
||||||
|
- Paired local/cloud detail assertions verify identical section order, action order, and stale/partial/failed rendering rules.
|
||||||
|
- Cloud row click opens detail instead of immediate preview/download.
|
||||||
|
- Unsupported preview keeps Download active and never auto-downloads from the Preview trigger.
|
||||||
|
- No rendered output or API-fed UI state leaks provider URLs, credentials, or cache object keys.
|
||||||
|
- Visible UI contains `Re-analyze` and no surviving `Re-classify` copy.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Checker Sign-Off
|
||||||
|
|
||||||
|
- [ ] Dimension 1 Copywriting: PASS
|
||||||
|
- [ ] Dimension 2 Visuals: PASS
|
||||||
|
- [ ] Dimension 3 Color: PASS
|
||||||
|
- [ ] Dimension 4 Typography: PASS
|
||||||
|
- [ ] Dimension 5 Spacing: PASS
|
||||||
|
- [ ] Dimension 6 Registry Safety: PASS
|
||||||
|
|
||||||
|
**Approval:** pending
|
||||||
Reference in New Issue
Block a user