Files
Oxicloud/docs/DESIGN-SYSTEM.md
DioCrafts 54639d466a chore(frontend): remove the legacy vanilla-JS frontend and its tooling
The SvelteKit app under /frontend has fully superseded the legacy
vanilla-JS/CSS frontend in /static, which was only ever served by a
debug `cargo run` / `PROFILE=dev` and never shipped to production.
Remove it together with the whole subsystem that existed only to
support it (~54k lines).

Frontend & assets:
- Delete /static (js/, css/, *.html, sw.js, basemaps/, locales symlink).
- Relocate the brand/PWA assets (logo/, favicon.ico, manifest.webmanifest)
  to frontend/static/ so they ship with the SPA. This also fixes the
  favicon, which app.html referenced but was missing from the prod bundle.
- Migrate the Nextcloud login-flow redirects from /nextcloud-error.html
  to the SvelteKit /nextcloud/error route.

Web layer:
- Simplify resolve_static_path: drop the PROFILE=dev branch; always prefer
  the Vite static-dist/ build, fall back to the configured path.
- Resolve i18n locales from the served SPA dir with a frontend/static
  fallback so `just dev` works without a prior build.

Build:
- Prune build.rs from 1262 to ~70 lines (git metadata only); the Rust asset
  pipeline and the OXICLOUD_RUST_ASSETS rollback flag are gone.
- Drop the now-unused build-dependencies (oxc_*, lightningcss).
- Remove the COPY static lines from the Dockerfile (cacher + builder).

Tooling & docs:
- Delete biome.json, jsconfig.json, tools/check-*.py, identifier.sh.
- Remove the legacy front-* justfile recipes; repoint the design-system
  scripts (locales, dead-tokens, brand-drift, token-docs) at the frontend,
  and drop check-contrast/check-headings (coupled to the old token
  taxonomy / multi-page HTML).
- Repoint docs/DESIGN-SYSTEM.md links; remove 5 superseded docs/plan/*.

Backend dead code:
- Remove the dead `folder_repo` field from FileBlobWriteRepository.
- Remove the deprecated GET /api/folders/{id}/listing endpoint
  (superseded by /resources).

Verified: cargo clippy (all-features/all-targets) clean, cargo test
--workspace 448 passed, cargo fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 03:20:10 +02:00

106 lines
5.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OxiCloud Design System
The single source of truth for how the frontend looks, behaves, and stays
accessible. Pairs with [TOKENS.md](TOKENS.md) (auto-generated token reference)
and [UIUX-ROADMAP.md](UIUX-ROADMAP.md) (the work plan).
---
## 1. Design tokens
Everything visual routes through a token in
[`static/css/base/variables.css`](../frontend/src/lib/styles/base/variables.css). Six scales,
plus a curated color system. **Never hand-write a raw px/hex for these** — consume
a token so the next change happens in one place.
| Axis | Tokens | Notes |
| --- | --- | --- |
| Spacing | `--space-0 … --space-24` | 4px grid (+ half-steps 2/6/10/14). |
| Radius | `--radius-xs … --radius-4xl`, `--radius-full` | `--radius` aliases `--radius-2xl`. |
| Type | `--text-2xs … --text-6xl`, `--leading-*`, `--weight-*`, `--tracking-*` | rem-based (honors zoom). `.heading-page/-section/-card` utilities decouple role from element. |
| Z-index | `--z-base … --z-max` | Semantic layers with gaps; no magic numbers. |
| Motion | `--motion-fast/base/moderate/slow`, `--ease-standard/-emphasized/...` | `--ease-standard` is the decelerate default for entrances. |
| Elevation | `--shadow-xs … --shadow-2xl` | Composed recipes layered on the `--color-shadow-*` alphas. |
**Color.** One brand accent (orange `#ff5e3a`), one neutral slate ramp, and five
semantics (success/warning/danger/info + accent), each unified to a single hue.
Text tiers collapse to a handful that all clear **WCAG AA (4.5:1)** — verified by
[`scripts/check-contrast.mjs`](../scripts/check-contrast.mjs). Use
`--color-accent-text` (not `--color-accent`) for accent *text/links*.
Governance: **one brand accent, one neutral ramp, five semantics — no new hero
hues.** Run `node scripts/gen-token-docs.mjs` after editing tokens.
---
## 2. Accessibility rules (non-negotiable)
These are enforced/aided by CI scripts and must hold for every new surface.
- **Keyboard.** Everything interactive is reachable and operable by keyboard.
Use `<button>`/`<a>` (not clickable `<div>`s). Nav exposes `aria-current="page"`.
- **Focus.** A global `:focus-visible` ring lives in
[`base/a11y.css`](../frontend/src/lib/styles/base/a11y.css). Never `outline: none` without a
paired `:focus-visible` style. Mouse focus stays ring-free; keyboard focus never.
- **Contrast.** Every text/background pair clears 4.5:1 in **light AND dark** —
`node scripts/check-contrast.mjs` fails the build otherwise.
- **Landmarks + skip link.** `<nav aria-label>`, `role="main"`/`<main id="main">`,
a skip link as the first focusable element, and `lang` on `<html>`.
- **Headings.** Exactly one `h1` per page, no skipped levels —
`node scripts/check-headings.mjs`.
- **Motion.** `@media (prefers-reduced-motion: reduce)` neutralizes animation
globally. Also honor `prefers-contrast` and `forced-colors`.
- **Dialogs.** `role="dialog"` + `aria-modal` + `aria-labelledby`, focus trapped
while open, focus restored to the trigger on close (see
[`modal.js`](../frontend/src/lib/components/Modal.svelte)).
- **Icon-only buttons.** Always an `aria-label`; decorative icons get
`aria-hidden="true"`.
- **Touch targets.** ≥44×44px on phones.
---
## 3. Brand
- **Mark.** The cloud glyph ([`logo-plain.svg`](../frontend/static/logo/logo-plain.svg)).
Always rendered from the real SVG (never a stock `fa-cloud`). On surfaces it
sits in an accent-gradient tile via the `.brand-mark` component.
- **Wordmark.** "OxiCloud", weight 700, tight tracking. The accent-coloured
"Oxi" lockup is the ownable treatment.
- **Accent.** Orange→coral `#ff5e3a → #ff2d55` — warm and distinctive in a
blue-dominated cloud-storage market; nods to Rust oxidation. It is the *only*
brand/primary hue (blue/indigo/purple were demoted to the single info ramp).
- **Logo gradient.** One token (`--color-logo-gradient`) everywhere.
- **Clear-space / min-size.** Keep ≥ the tile's corner-radius of padding around
the mark; don't render the wordmark below ~16px.
- **Don't:** recolor the mark, stretch it, place it on a low-contrast background,
or introduce a second "primary" hue.
- **Maskable / OG.** [`logo-maskable.svg`](../frontend/static/logo/logo-maskable.svg) (PWA,
safe-zone) and [`og-image.svg`](../frontend/static/logo/og-image.svg) (social). Export
both to PNG for full platform support (see roadmap).
---
## 4. CI guardrails (what keeps the score from regressing)
Run all the dependency-free checks with **`just frontend-check`**:
| Script | Enforces |
| --- | --- |
| `check-contrast.mjs` | WCAG AA on every text/bg + semantic token pair (light + dark). |
| `check-headings.mjs` | One `h1`, no skipped levels, per HTML page. |
| `check-locales.mjs` | Locale completeness + `{placeholder}` integrity across all 16 locales. |
| `check-dead-tokens.mjs` | Reports tokens defined but never referenced (cleanup aid). |
| `check-brand-drift.mjs` | Locks the logo SVG hash + `--color-logo-gradient` against silent change. |
| `gen-token-docs.mjs` | Regenerates [TOKENS.md](TOKENS.md). |
**Build pipeline.** `build.rs` (release) bundles + content-hashes + minifies all
CSS/JS into `static-dist/` using the Rust crates **lightningcss** and **oxc** — no
npm. It also injects early `<link rel="preload">` / `<link rel="modulepreload">`
hints for the hashed bundles. Debug builds (`cargo run`) serve raw `static/`
unprocessed, so any source CSS must be valid as-authored (e.g. `@custom-media`
is off the table — it has no native browser support).
Still to wire (genuinely need npm devDependencies / browsers): stylelint rules
banning raw px/hex outside `:root`, axe-core + Playwright (keyboard,
visual-regression, dark-parity, cross-browser), and Lighthouse-CI perf budgets.