add UI/UX improvements design spec

Content-first redesign covering showcase stagger animation and ghost
badges, gallery source tag filtering, modal two-panel hierarchy,
series reader immersive mode, and settings tab structure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-19 23:11:49 -04:00
parent bf20eeab5c
commit 998d573298
@@ -0,0 +1,183 @@
# UI/UX Improvements Design
**Date:** 2026-03-19
**Approach:** Content-First Redesign — every UI element is evaluated against the principle that content leads, chrome follows. The black/transparent brand is preserved throughout.
---
## Design Principles
1. **Content leads, chrome follows.** No UI element competes with image/video for attention. Overlays, badges, and controls recede by default and surface when needed.
2. **Black and transparent is the brand.** No light surfaces. Depth through opacity layers and subtle borders, not color changes.
3. **Motion has a purpose.** Transitions communicate state, not decoration. Fast and snappy.
4. **Density is a choice.** Settings is dense. Showcase is sparse. Each page gets appropriate density.
5. **No orphaned interactions.** Every action gets in-context feedback — not a toast, but a brief fade label right where the action happened.
---
## 1. Showcase
**Goal:** Discovery feeling — energetic, surprising, content-first.
### Changes
**Staggered entry animation.**
On page load and shuffle, images stagger in with a subtle fade + translate-up per column (150200ms per item, offset by column index). Creates the feeling of content surfacing, not a grid appearing. Animation is CSS-based with a JS-assigned `--stagger-index` custom property on each item.
**Tag overlays replaced with ghost badge.**
Each showcase item gets a single small semi-transparent pill badge in the bottom-right corner showing tag count (e.g. `#3`). No text, no emoji, no color — just faint opacity. On desktop: visible only on hover. On touch: always visible. Clicking the image opens the modal where full tags are accessible.
**Navbar hint refinement.**
"Press R to shuffle" moves from a permanently rendered hint to a tooltip-style label that appears only when hovering over the `.nav-hint` text itself. The element remains in the DOM (for accessibility) but is visually hidden at rest via `opacity: 0`, transitioning to `opacity: 1` on hover. Reduces permanent chrome without hiding the affordance.
### No structural changes
Masonry layout, modal integration, shuffle API, and column logic all unchanged.
---
## 2. Gallery & Tag Overlays
**Goal:** Keep tag chips visible on gallery items for navigation but reduce visual noise.
### Changes
**Source tags filtered from gallery items.**
`_gallery_item.html` currently filters out `archive` kind tags. Extend the filter to also exclude `source` kind tags. One-line template change.
```
Before: selectattr('kind', 'ne', 'archive')
After: rejectattr('kind', 'in', ['archive', 'source'])
```
**Date label refinement.**
`.image-date` span gets reduced opacity at rest (e.g. 0.5), full opacity on hover. Stops competing with the image at a glance.
**Video play indicator refinement.**
Play overlay gets a minimal centered circle + triangle treatment. Refined sizing and opacity — reads clearly without dominating the thumbnail.
**Selection mode visual consistency.**
Selection checkbox overlay on items uses semi-transparent treatment with accent color on selected state. Consistent with the overall dark visual language.
### No changes
Timeline sidebar, infinite scroll, bulk editor functionality, gallery header all unchanged.
---
## 3. Image Modal
**Goal:** Clear hierarchy — image dominates, metadata lives quietly alongside it.
### Layout
**Formal two-panel split.**
- Left ~65%: image viewer (already roughly this, formalized with explicit layout)
- Right ~35%: metadata sidebar — fixed width, scrollable if content overflows, subtle left border as divider
### Right Panel — Section Order
The modal currently contains only three content areas: series info/add-to-series, tag chips, and the tag input form. No hidden metadata fields (filename, dimensions, etc.) exist. The redesign reorganizes these same elements:
1. **Series block** (top, conditional)
Only rendered when the image is in a series OR series exist to add it to.
- If in a series: compact single-row — page number input, "of", series name link, Save button
- If not in a series: "Add to Series" collapsed behind a toggle button (not always expanded)
2. **Tags block**
Current tag chips. Each chip shows a remove `×` on hover only — not always visible. Reduces visual noise at rest.
3. **Add tag input** (bottom of tag block)
Autocomplete unchanged. Input sits flush below the tag list, not separated by excessive spacing.
### Feedback
All actions (tag added, tag removed, page number saved) display a brief in-context fade label next to the triggering element. Appears immediately, fades out after 1.5s. No toast notifications.
### No changes
Navigation arrows (prev/next), ESC to close, video playback, API calls all unchanged.
---
## 4. Series Reader
**Goal:** Immersive reading experience — UI surfaces when needed, recedes while reading.
### Changes
**Scroll progress bar.**
A 12px full-width bar fixed at the very top of the viewport. Fills from left to right as you scroll through the series. Uses `--btn-primary` accent color. Always visible, extremely unobtrusive.
**Auto-hiding header.**
Reader header fades out 23 seconds after scrolling begins. Reappears instantly on scroll-stop, mouse move, or any keyboard interaction. Implemented with a CSS opacity transition + JS scroll/mousemove listeners and a debounced timeout.
**Active thumbnail tracking in sidebar.**
As the user scrolls the main reading area, the currently-visible page is detected (IntersectionObserver on `.reader-page` elements). The matching thumbnail in the sidebar gets:
- Left border accent (`--btn-primary`)
- Slightly elevated opacity
- Smooth scroll-into-view within the sidebar
**Single global page indicator.**
Remove the per-image `page / total` `.page-indicator` div from each `.reader-page`. Replace with one fixed-position label in the bottom-right corner of the viewport, updated by the same IntersectionObserver that drives the sidebar tracking.
### No changes
Jump-to-page select, back button, image lazy loading, sidebar toggle button all unchanged.
---
## 5. Settings Page
**Goal:** Reduce scrolling, surface important controls, push rarely-used tools out of the way.
### Tab Structure
Three tabs replacing the current flat scroll layout:
| Tab | Contents |
|-----|----------|
| **Overview** | System stats, Import Queue Status, active batch progress, import trigger buttons |
| **Import** | Import filter settings, filter scan/delete tools, duplicate detection |
| **Maintenance** | Thumbnail regeneration, artist tag reapply, orphaned tag cleanup, Celery worker status |
### Tab Implementation
- Pure frontend — JS show/hide, no server changes
- Active tab persisted in URL hash (`/settings#import`) for deep-linking and refresh persistence
- On page load, read hash and activate matching tab (default: Overview)
- Tab bar uses same filter pill visual language as the tag list page for consistency
### Visual Hierarchy Within Tabs
- **Overview tab**: Full-width cards, prominent stat values, clear action buttons
- **Import tab**: Two-column grid — left column: import filter settings form; right column: filter scan/delete tools and duplicate detection
- **Maintenance tab**: Visually subdued cards — slightly lower contrast to signal lower priority. Single column: thumbnail regeneration (all + missing), artist tag reapply, orphaned tag cleanup, Celery worker status
### Inline styles removed
All `style="..."` attributes on settings elements replaced with proper CSS classes.
### No changes
All existing API endpoints, form logic, and functionality unchanged. Layout and organization only.
---
## Files Affected
| File | Change |
|------|--------|
| `app/templates/_gallery_item.html` | Filter source tags; refine date label and video overlay |
| `app/templates/showcase.html` | Stagger animation; ghost badge; navbar hint refinement |
| `app/templates/_gallery_modal.html` | Two-panel layout; section hierarchy; conditional series block |
| `app/templates/reader.html` | Progress bar; auto-hide header; single page indicator |
| `app/templates/settings.html` | Tab structure; section reorganization; remove inline styles |
| `app/static/style.css` | New classes for all of the above |
| `app/static/js/showcase.js` | Stagger animation logic; ghost badge rendering |
| `app/static/js/view-modal.js` | In-context feedback; series block toggle |
| `app/static/js/reader.js` | Progress bar; header auto-hide; active thumbnail tracking — **new file** (reader logic currently inline in `reader.html`; extract to this file) |
---
## Out of Scope
- No new API endpoints
- No database changes
- No changes to import pipeline, Celery tasks, or tag logic
- No changes to the gallery infinite scroll or timeline sidebar
- No changes to bulk select functionality