diff --git a/404.html b/404.html index 15227c1..662e665 100644 --- a/404.html +++ b/404.html @@ -19,7 +19,7 @@

404

This page is not here.

The address may be outdated or mistyped.

Return home
- + diff --git a/README.md b/README.md index 47c4eec..accdb5d 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ The hub is a static site built with semantic HTML, CSS, and Vanilla JavaScript E │ ├── shared/ │ │ ├── file.js │ │ ├── pdf.js +│ │ ├── tool.css │ │ └── save.js │ ├── pdf/ │ │ ├── index.html @@ -104,6 +105,8 @@ The hub is a static site built with semantic HTML, CSS, and Vanilla JavaScript E `js/main.js` initializes shared theme and internationalization behavior. `js/theme.js` owns Light, Dark, and System selection, OS color-scheme observation, and persistence. `js/i18n.js` resolves all six supported languages from browser preferences, applies `data-i18n` bindings without reloading, updates metadata and ``, and gives persisted manual selection precedence. Repository links are centralized in `js/config.js`. +The concise [UX consistency audit](./docs/ux-consistency-audit.md) records the shared interaction patterns, resolved drift, and intentional tool-specific exceptions established before v1.0.0 hardening. + The category hubs are: - `/tools/pdf/` diff --git a/about/index.html b/about/index.html index 4e44d24..6ae8b98 100644 --- a/about/index.html +++ b/about/index.html @@ -44,7 +44,7 @@

Local-first and open

The project favors static, understandable code and a privacy model that anyone can verify through source and network inspection.

- + diff --git a/css/base.css b/css/base.css index 9ab1b08..c57dd48 100644 --- a/css/base.css +++ b/css/base.css @@ -15,6 +15,7 @@ --focus: #1673c9; --status-muted: #74766f; --shadow-sm: 0 1px 2px rgb(23 24 22 / 5%); + --preview-backdrop: #d7d8da; --radius-sm: 0.4rem; --radius-md: 0.75rem; --radius-lg: 1.15rem; @@ -48,6 +49,7 @@ --focus: #66b5ff; --status-muted: #9b9e96; --shadow-sm: 0 1px 2px rgb(0 0 0 / 20%); + --preview-backdrop: #2b2e29; } *, *::before, *::after { box-sizing: border-box; } diff --git a/css/categories.css b/css/categories.css index 32cbfae..43c3a00 100644 --- a/css/categories.css +++ b/css/categories.css @@ -11,6 +11,7 @@ .category-tool { display: flex; min-width: 0; min-height: 12rem; flex-direction: column; align-items: flex-start; padding: var(--space-5); color: inherit; text-decoration: none; } .category-tool__top { display: flex; width: 100%; align-items: center; justify-content: space-between; gap: var(--space-4); margin-bottom: auto; } .category-tool h2 { margin: var(--space-5) 0 var(--space-2); font-size: clamp(1.3rem, 3vw, 1.75rem); } +.category-tool > .status { margin-bottom: auto; } .category-tool p { margin: 0; color: var(--text-secondary); } a.category-tool { transition: border-color var(--transition-fast), transform var(--transition-fast); } a.category-tool:hover { border-color: var(--border-strong); transform: translateY(-2px); } diff --git a/css/components.css b/css/components.css index 7154455..380f713 100644 --- a/css/components.css +++ b/css/components.css @@ -12,13 +12,15 @@ max-width: 100%; text-align: center; text-decoration: none; + cursor: pointer; transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast); } .button--primary { background: var(--text-primary); color: var(--bg-primary); } -.button--primary:hover { background: var(--accent-strong); color: var(--text-inverse); } +.button--primary:hover:not(:disabled) { background: var(--accent-strong); color: var(--text-inverse); } .button--secondary { border-color: var(--border); background: var(--bg-secondary); } -.button--secondary:hover { border-color: var(--border-strong); background: var(--bg-subtle); } +.button--secondary:hover:not(:disabled) { border-color: var(--border-strong); background: var(--bg-subtle); } +.button:disabled { border-color: var(--border); background: var(--bg-subtle); color: var(--status-muted); cursor: not-allowed; } .control { min-height: 2.5rem; @@ -32,7 +34,8 @@ .control[data-language-select] { width: 9rem; max-width: 9rem; } -.control:hover { border-color: var(--border-strong); } +.control:hover:not(:disabled) { border-color: var(--border-strong); } +.control:disabled { border-color: var(--border); background: var(--bg-subtle); color: var(--status-muted); cursor: not-allowed; } .control-label { display: inline-flex; min-width: 0; align-items: center; gap: var(--space-2); color: var(--text-secondary); font-size: 0.75rem; font-weight: 650; } .surface { border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--bg-secondary); box-shadow: var(--shadow-sm); } .status { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--status-muted); font-size: 0.7rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; white-space: nowrap; } diff --git a/docs/ux-consistency-audit.md b/docs/ux-consistency-audit.md new file mode 100644 index 0000000..cd6c766 --- /dev/null +++ b/docs/ux-consistency-audit.md @@ -0,0 +1,53 @@ +# UX consistency audit + +Sprint 10 audited the homepage, About, Privacy, all five category hubs, the PDF hub, and the six production file tools at source level. The review covered file input, source and empty states, queues, settings, actions, progress, errors, results, save behavior, privacy messaging, shared chrome, responsive behavior, themes, and accessibility. + +## Inventory and resolutions + +| Pattern | Pages/tools | Finding | Resolution | +| --- | --- | --- | --- | +| Shared tool foundation | All six file tools | Common styles were owned by Images to PDF; PDF to Images also imported Split CSS. | Moved file input, source, queue, mode, form, action, progress, and status rules to `tools/shared/tool.css`; removed sibling stylesheet dependencies. | +| File input | All six file tools | The interaction was already a full-area native label with keyboard focus and drag/drop, but the image accept filter existed only at runtime. | Preserved the shared semantic pattern and added the supported image formats to static markup. Busy inputs now expose the same disabled visual treatment as their actual state. | +| Privacy note | All six file tools | Placement and localization were already consistent. | Preserved exactly one local-processing note beside each drop zone. | +| Empty state | Images to PDF, Merge PDF | Queue copy repeated ordering instructions already present near the input. | Shortened empty copy in all six languages. `[hidden]` remains explicitly protected in shared CSS. | +| Source summary | Split, PDF to Images, Organizer, Metadata | Split and PDF to Images shared a full source card; Organizer and Metadata use toolbar summaries suited to larger workspaces. | Consolidated the full source card and added an explicit compact source-state variant for the two complex workspaces. | +| Queue/list | Images to PDF, Merge PDF | Both used the same visual grammar under an image-specific list class name. | Renamed the shared presentation class to `file-list`; item content remains tool-specific. | +| Settings | Images to PDF, Merge, Split, PDF to Images | Labels, controls, help, checks, and sidebars were already structurally shared, but some selectors were duplicated. | Consolidated field/mode rules and retained each tool's necessary controls. | +| Primary actions | All six file tools | Shared sizing existed, but disabled buttons still reacted to hover. | Standardized pointer, hover, disabled color, border, background, and cursor behavior. | +| Secondary/destructive actions | Queues, Organizer, Metadata | Remove actions were restrained and context-specific; disabled icon/page actions relied mainly on opacity. | Preserved restrained destructive hover/color treatment and gave disabled actions explicit theme-aware colors. | +| Loading/progress | All six file tools | Progress and live status were colocated with actions, but status feedback appeared as unstructured text. | Kept existing progress semantics and converted non-empty status messages to one bordered, theme-aware neutral/error/warning/success pattern. | +| Error state | All six file tools | Errors used localized text and live regions without alerts or unsafe HTML, but visual treatment varied by tone. | Standardized error, warning, and success tokens and panels; field-level errors retain `role="alert"`. | +| Result/save | Organizer, Metadata, other production tools | Organizer and Metadata duplicated the same output grid. Other tools intentionally save immediately through the shared picker/download fallback. | Added a shared responsive `tool-output` pattern for Organizer and Metadata; retained immediate saving elsewhere. | +| Header | All production pages | Header structure was consistent; some category-page brand links lacked the established accessible name. | Applied the same home-link name throughout; preserved the shared navigation and language/theme controls. | +| Footer | Tool and category pages | Link sets differed, and planned category hubs omitted footer navigation. | Standardized order to Tools, Privacy, About, Source on all production pages. | +| Category hubs | PDF, Image, Privacy, Scan/OCR, Media | Available and planned semantics were correct, but planned-card title alignment differed. | Kept available tools as links and planned tools as non-interactive articles; aligned their status/title rhythm. | +| Light/Dark | Organizer and tool states | The thumbnail surround used one light hardcoded backdrop; warning/success state ownership was inconsistent. | Added theme tokens for the non-document preview surround and centralized tool feedback colors. PDF canvas white remains intentionally unchanged. | +| Responsive/i18n | All production pages and six locales | Sprint 9 foundations were sound; shared output/source rules had drifted across sibling stylesheets. | Preserved language-specific line breaking, shrinkable flex/grid children, wrapping buttons, stacked outputs, mobile metadata rows, and header control wrapping. | +| Reduced motion | Shared and tool-specific transitions | Existing protection was complete. | Preserved the global reduced-motion override and tool-specific transition removals. | + +## Accessibility checklist + +- [x] Skip links and main targets are present on every production page. +- [x] Full-area file labels activate native inputs by pointer and keyboard. +- [x] File inputs have descriptions and accepted-type declarations. +- [x] Drag-active, focus-visible, disabled, and busy/loading affordances remain explicit. +- [x] Every production tool exposes a polite live status region. +- [x] Real progress elements retain localized accessible names. +- [x] Queue and page icon controls retain localized names and keyboard equivalents. +- [x] Form labels, help references, field alerts, radio legends, and metadata checkboxes remain associated. +- [x] No browser `alert()` or unsafe translated HTML sink was introduced. +- [x] Header/footer landmarks and brand links are consistent. + +## Intentional exceptions + +- Organizer keeps a page grid because queue rows cannot represent page previews, rotation, and page-level actions clearly. +- Metadata keeps a responsive semantic table on wider screens and structured rows on narrow screens. +- Split and PDF to Images use full source cards; Organizer and Metadata use compact summaries inside their existing workspaces. +- The PDF preview canvas stays white because it represents document content, while only its surrounding backdrop follows the theme. +- PDF to Images allows safe source replacement by cancelling the active conversion first; other tools disable source replacement while busy. +- Tools continue to save through the established picker/download fallback. A separate “Ready to save” panel would add a second action without improving the existing flow. +- Category navigation may scroll horizontally on very narrow screens by design; the page body itself must not overflow. + +## Validation boundary + +Automated checks cover architecture, semantics, resources, six-language keys, known overflow anti-patterns, CSP, and functional regressions. Browser automation remained subject to the known Windows sandbox ACL limitation during this Sprint. If visual control is unavailable, real human browser review at 360, 390, 768, 1024, and 1440 CSS pixels in Light/Dark themes remains required before v1.0.0 release approval. diff --git a/index.html b/index.html index 9a852dd..5a16e8d 100644 --- a/index.html +++ b/index.html @@ -143,7 +143,7 @@

Open by design.