# 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 (150–200ms 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 1–2px 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 2–3 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