feat: delta/instant upload + frontend UI/UX polish

Bundles the backend+frontend delta-upload (content-dedup) feature with a
batch of frontend fixes from this session.

Upload / dedup:
- Client-hashed delta & instant upload (deltaUpload, hashWasm vendor shim)
- Backend dedup batch endpoint (dedup_service, dedup_handler, routes)
- session store owned-hash helpers; unit tests + upload-strategy bench

Frontend UI/UX:
- Colour file-type icons in grid/list (per-type tinted tiles + glyph hue)
- Robust thumbnail fallback; PDFs now show their type icon (backend
  generates no PDF thumbnails) instead of a blank tile
- Fix PDF preview: load via a same-origin blob: iframe — the API URL is
  blocked by the global X-Frame-Options: DENY in the browser's framed
  PDF viewer, matching the existing CSP `frame-src blob:` design
- Groups: localized virtual-group description (no DB schema-note leak),
  add nav.groups to the 15 missing locales, fix primary-button contrast
- Repoint --color-text-light → --color-on-accent (was faint grey on accent)
- Nudge the admin role badge off the user-menu header divider

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
DioCrafts
2026-06-20 16:33:08 +02:00
parent f8490ad96e
commit d98e3117b2
35 changed files with 901 additions and 101 deletions
+23 -1
View File
@@ -236,7 +236,11 @@
--color-text-gray: var(--color-text-muted);
--color-text-medium: var(--color-text-muted);
--color-text-faint2: var(--color-text-faint);
--color-text-light: var(--color-text-faint);
/* "Light" = light-coloured (near-white) text for accent/dark fills, NOT a
* faint tier. Every consumer is a primary button (background: --color-primary),
* so this must resolve to the on-accent foreground, not muted grey — which
* rendered muddy and failed contrast on the orange accent. */
--color-text-light: var(--color-on-accent);
--color-text-placeholder: var(--color-text-faint);
/* Accent (orange) — mostly mode-agnostic. */
@@ -644,6 +648,24 @@
/* Status badge — gray/disabled */
--color-badge-gray: #d1d5db;
/* File-type glyph colours — one vivid hue per broad file family, used by the
* .file-icon--* buckets (resourceList.css) so the grid/list type icons read
* as colourful tiles instead of flat monochrome. Tile tints are derived from
* these with color-mix(), so only the foreground hue lives here. Dark-mode
* shades are lightened for contrast against the dark tile fill. */
--file-kind-folder: light-dark(#3b82f6, #60a5fa);
--file-kind-pdf: light-dark(#ef4444, #f87171);
--file-kind-doc: light-dark(#2563eb, #60a5fa);
--file-kind-sheet: light-dark(#16a34a, #4ade80);
--file-kind-slides: light-dark(#ea580c, #fb923c);
--file-kind-archive: light-dark(#d97706, #fbbf24);
--file-kind-code: light-dark(#7c3aed, #a78bfa);
--file-kind-image: light-dark(#0891b2, #22d3ee);
--file-kind-video: light-dark(#c026d3, #e879f9);
--file-kind-audio: light-dark(#db2777, #f472b6);
--file-kind-text: light-dark(#475569, #94a3b8);
--file-kind-generic: light-dark(#64748b, #94a3b8);
/* (Removed: the legacy dark-mode badge tokens that lived here had zero
* consumers — the light-dark() badge tokens above are the single source.) */