Commit Graph

12 Commits

Author SHA1 Message Date
bvandeusen 50d6c42207 fix(ui): softer chrome-gradient falloff + segmented media toggle (#1478)
CI / lint (push) Successful in 2s
CI / frontend-build (push) Successful in 18s
CI / backend-lint-and-test (push) Successful in 28s
CI / integration (push) Successful in 3m49s
Two operator-flagged polish items from the Vuetify-4 review:

Gradient: reshape the nav + sub-header fade from a near-linear ramp to a
hold-then-soft-drop profile — hold high opacity (0.92 → seam 0.68) through the
bulk of the chrome, then ease to transparent over a small section at the bottom
with an intermediate stop, so it tails off softly instead of running a straight
line into a hard edge. Raising the shared --fc-chrome-seam also makes the tab
strips more legible over scrolling content.

Media toggle: FC's global VBtn { rounded: 'pill' } default made Vuetify 4
pill-round each SEGMENT of the All/Images/Videos v-btn-toggle individually, so
the rounded ends collided at the joins. Square the inner segments and clip the
group to one 8px outline — a proper segmented control.

Both are colour/border-radius only — no control height changes, so the filter
bar height and the nav offset (--fc-nav-h) are untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 15:50:33 -04:00
bvandeusen 67c7ca8603 fix(ui): measure real nav height (--fc-nav-h), stop Explore breadcrumb tucking under nav (#1481)
CI / lint (push) Successful in 3s
CI / frontend-build (push) Successful in 19s
CI / backend-lint-and-test (push) Successful in 30s
CI / integration (push) Successful in 3m44s
The app uses a plain sticky TopNav (no v-main), and the nav's height was
hardcoded as 64px in ~6 places: the Explore + Subscriptions full-height
workspaces (height: calc(100vh - 64px)) and every sticky sub-header pinned
beneath the nav (top: 64px — Gallery filter bar, Browse/Series/Settings tabs).

Vuetify 4's MD3 sizing changed the real nav height, so 64px was wrong: the
Explore workspace was sized taller than the space below the nav, overflowed the
viewport, and its breadcrumb tucked under the (taller) nav on 1080p.

TopNav now measures its own height via ResizeObserver and publishes it as
--fc-nav-h on documentElement (default 64px in app.css). Every consumer uses
var(--fc-nav-h) instead of the magic number, so the layout self-corrects to the
nav's real height and stays correct as it reflows (per-view teleported actions,
mobile breakpoint). Also tightens the new chrome-gradient seam — sub-headers now
pin at the nav's exact bottom.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 15:27:37 -04:00
bvandeusen eed42a260a fix(ui): one continuous chrome gradient across nav + sticky sub-headers (#1478)
CI / lint (push) Successful in 2s
CI / frontend-build (push) Successful in 20s
CI / backend-lint-and-test (push) Successful in 44s
CI / integration (push) Successful in 3m50s
The TopNav and each sticky sub-header pinned beneath it (Gallery's filter bar,
the Browse/Series/Settings/Subscriptions tabs bars) each painted their OWN
dark-to-transparent gradient (Gallery) or a solid surface band (the rest), so
the fade read as happening twice — dark, fade out, then dark again — instead of
one gradient flowing from the nav down through the sub-nav.

Operator asked to treat the sub-nav as part of the nav with a single gradient.
New shared .fc-chrome-continues primitive (app.css): the nav fades from opaque
to a shared --fc-chrome-seam alpha (on views flagged meta.stickyChrome), and the
sub-header continues from that exact seam alpha to transparent over its own
height. Both reference the same var so the alphas meet at the 64px boundary — no
re-darkening, no doubling. Percentage stops keep it spanning the filter bar's
expanding refine panel; the primitive's blur keeps tabs/controls legible where
the old solid bars had none. --fc-chrome-seam is the single tuning knob.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 14:42:07 -04:00
bvandeusen 2d1cddd9b7 feat(explore): 3-pane tagging workspace — gallery | viewer | tag rail
CI / lint (push) Successful in 3s
CI / frontend-build (push) Successful in 19s
CI / backend-lint-and-test (push) Successful in 30s
CI / integration (push) Successful in 3m18s
Reworks Explore from "anchor + neighbour grid + cluster tag-gap rail" into a
persistent 3-pane workspace that unfolds the image modal so you can tag while
rabbit-holing (operator concept 2026-06-26):

- LEFT  neighbour grid (larger thumbs), click = walk; breadcrumb retained.
- CENTER light viewer — reuses ImageCanvas + ImageMetaBar(:image) for the
  focused image; "Open full viewer" still launches the overlay modal.
- RIGHT  the modal's TagPanel, hosted on the anchor for modal-parity tagging
  (chips, autocomplete, suggestions + Accept, fandom-on-chip, T/"/" focus).

Reuse without destabilising the audited modal store: TagPanel and
SuggestionsPanel gain an optional `host` prop (default = modal store, so the
image modal is unchanged); the explore store implements the same small
tag-CRUD surface (current/currentImageId + reloadTags/addExistingTag/
removeTag/createAndAdd) over the anchor. ImageMetaBar gains an optional
`image` prop for the same reason.

Drops the mass/cluster tagger (TagGapPanel deleted; clusterIds/thumbById
removed) — per-image tagging feeds the per-tag reference-embedding centroid
better than bulk ops.

Nav: keep the Explore tab but bare /explore now SEEDS a random image
(GET /api/showcase?limit=1 → /explore/:id) so the tab kick-starts a rabbit
hole; explicit meta.navOrder pins nav order (Explore after Gallery) since
router.getRoutes() doesn't preserve declaration order.

Note: the backend cluster tag-gaps route/service (#94a) is now frontend-orphaned
— left in place; flag for a separate cleanup.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 01:15:11 -04:00
bvandeusen a50902071a feat(nav): pin Settings to the right edge, separated from content nav
CI / lint (push) Successful in 3s
CI / frontend-build (push) Successful in 25s
CI / backend-lint-and-test (push) Successful in 49s
CI / integration (push) Successful in 3m20s
Settings is configuration, not content, but sat mid-row (between Series and
Posts). Pull it out of the centered content links and pin it to the right as a
gear+label, matching the convention that config lives at the right edge. Mobile
is unchanged — Settings stays in the hamburger menu (navRoutes still includes
it). Operator-asked 2026-06-09.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 20:37:50 -04:00
bvandeusen 304e8aa878 fix(ui): mobile responsiveness — nav hamburger + primary-path fixes
CI / lint (push) Successful in 3s
CI / backend-lint-and-test (push) Successful in 12s
CI / frontend-build (push) Successful in 29s
CI / integration (push) Successful in 2m57s
The top nav packed brand + health + pipeline chip + ~7 inline links + an
action slot into one flex row, colliding/overflowing on phones (operator:
'almost unusable'). Below 768px the links now fold into a hamburger v-menu;
below 480px the brand text hides (glyph still brands). Plus the primary
browsing path:
- BulkEditorPanel: fixed 320px -> min(320px, 90vw) so it can't swallow the screen.
- GalleryFilterBar: <600px gives search its own full-width row (its 200px
  min-width was jamming the wrapping bar); sort grows.
- GalleryFacetPanel: <480px wraps groups + lets the side-by-side date inputs
  grow full-width.
- ArtistsView grid: minmax(min(440px,100%),1fr) so a card never overflows
  (single column on phones).
- GalleryView: hide the year/month timeline strip <600px.
ImageViewer already stacks its side panel below the image <900px (left as-is).

Secondary surfaces (Posts/Subscriptions filter bars, SubscriptionsTab table,
SeriesReader, PostCard) still need a mobile pass — follow-up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 09:06:33 -04:00
bvandeusen 00e2608ba1 feat(I3): always-on pipeline status indicator in the top nav
New /api/system/activity/summary aggregates scheduler health + per-queue
pending depths + running count + 24h failure count in one cached call (safe
to poll app-wide). PipelineStatusChip lives in the TopNav on every page: a
compact running/queued/failing chip with a scheduler-health dot that expands
to a popover (scheduler, busy queues, counts, link to downloads). Polls the
summary every 8s, paused when backgrounded. Reuses the queue-cache read via
_queues_cached(). + API test for the summary shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 13:24:11 -04:00
bvandeusen 05b398c352 fix(ui): TopNav side cells use flex: 1 1 0 (equal weight) so middle link block stays centered regardless of action-slot content
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 22:24:41 -04:00
bvandeusen 95bc761a69 fix(ui): TopNav uses 1fr/auto/1fr grid so Gallery/Showcase action buttons don't shift the centered links
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-23 21:16:37 -04:00
bvandeusen af2598451c feat(nav): health dot beside wordmark + #fc-nav-actions per-view slot
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 19:39:36 -04:00
bvandeusen 062a87e968 feat(ui): drop active-link underline + redundant page-title headers 2026-05-15 23:27:38 -04:00
bvandeusen 18ad61265e feat(ui): IR-style gradient-fade TopNav (brand, centered links, health) 2026-05-15 23:13:42 -04:00