11 KiB
phase, slug, status, shadcn_initialized, preset, created, reviewed_at
| phase | slug | status | shadcn_initialized | preset | created | reviewed_at |
|---|---|---|---|---|---|---|
| 14.1 | cloud-local-file-parity-hardening | approved | false | none | 2026-06-26 | 2026-06-26T18:51:13Z |
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 |
Dense row icon buttons use 32px targets inside StorageBrowser.vue rows. Sticky browser headers use 16px vertical padding with 16px mobile and 24px desktop horizontal padding. Modal, footer, confirmation, and primary actions use 48px minimum targets.
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 file or Open file 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 file, 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
- Local document navigation stays at
/document/:id. - Cloud rows open a dedicated detail route, named
cloud-file-detailor an equivalent explicit named route under/cloud/:connectionId/.... - Cloud route params use
connectionIdplus opaque provider item identity. Vue Router handles encoding; frontend code must not split or infer structure from provider IDs. - Clicking a cloud row opens detail first. It does not auto-preview and does not auto-download.
Preview file/Open fileand 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:
- Back navigation
- Header block: filename, metadata line, subtle source metadata, primary action cluster
- Status and source notice area
- Topics section
- Extracted text section
- Secondary controls and inline error/help copy
The filename plus primary action cluster is the first visual anchor on detail screens.
Header rules:
- Display title uses
24pxsemibold with wrapping allowed for long filenames. - Metadata line stays
12-14pxmuted 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-200androunded-xl. - Internal section padding is
24px. - Section headings use
18pxsemibold for top-level detail sections and14pxsemibold 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
Preview fileand Download stay adjacent in the detail header action cluster; when inline opening is the correct capability, the label becomesOpen file.- If preview is supported,
Preview fileorOpen fileis the first content action. - If preview is unsupported but download is supported,
Preview fileremains visible but disabled, with helper copyPreview unavailableplus the backend reason. Download remains active. Preview filenever triggers an automatic download.- No cloud UI may expose provider URLs, provider hostnames, raw tokens, or cache object keys.
- 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
Re-analyzeis the label for explicit refresh of an already-analyzed file in both local and cloud detail/browser surfaces.- Re-analyzing a current cloud file requires confirmation using the copy in the Copywriting Contract.
Retry analysisis reserved for failed work. It must not be used for current or stale-but-readable results.Analyze file,Retry analysis, andRe-analyzeoccupy one shared action slot per surface; they swap by state instead of accumulating as separate buttons.- When a retry or re-analyze starts, the previous extracted text and topics remain visible until new results replace them.
Accessibility And Feedback Contract
- Dense row icon buttons use
32pxtargets; modal, footer, and primary actions use48pxminimum targets. - Dense icon-only row actions require a tooltip and a visible text fallback anywhere hover is unavailable or the action collapses into a menu.
- 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.
- Status banners use semantic color plus icon plus text; color alone is insufficient.
- Focus indicators use the indigo ring pattern already present in the app.
- 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 filetrigger. - No rendered output or API-fed UI state leaks provider URLs, credentials, or cache object keys.
- Visible UI contains
Re-analyzeand no survivingRe-classifycopy.
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: approved