Use dedicated posX/posY variables instead of reading scroll position
directly, preventing drift at boundaries. Add more demo stamps.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace mouseover (which fires repeatedly on child elements) with
mouseenter/mouseleave so hover cleanly stops scrolling. On mouse leave,
sync scroll position from scrollTop so manual scrolling is respected.
Fix inverted top/bottom boundary checks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Return nil/empty results when Spotify client is not authenticated,
preventing GraphQL errors from breaking the home page data query.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The CheckOrigin function only accepted the production domain, rejecting
localhost connections in dev. Also removed redundant error response after
a failed upgrade since the upgrader already writes its own HTTP response.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move Vue app from nginx/vue/ to top-level vue/ with its own Dockerfile,
update docker-compose configs and nginx proxy to serve from the new
container, and add initial Rust WASM crate (stp_wasm). Also fix .gitignore
to exclude Rust target/ directories.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use CSS grid stacking instead of absolute positioning so both
entering and leaving images occupy the same grid cell, keeping the
container height stable during crossfade transitions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace ad-hoc nextTick and media load handlers with a ResizeObserver
on an inner content wrapper, which fires after layout for all content
changes (new messages, image/video loads, window resize). Add scroll
position tracking so auto-scroll only triggers when user is near
bottom, and conditionally show the Bottom button only when scrolled up.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Switch sidebar to CSS grid, constrain images on mobile, add max-height to Chat, and improve Radio/Time/Timer compact styling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use Link component in Chat, CommitHistory, Stamps, Demoman, and fix Navbar to use span instead of nested anchors. Also updates Navbar inHome check for /stp route.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New professional landing page at / with bio, about section, and nav links. Previous home page now lives at /stp.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
LinkTable now supports variant (list/table) and optional title toggle, replacing the need for separate components. Updates all consumers to use the unified API.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Link wraps RouterLink or <a> with consistent styling and automatic rel attributes. InlineLink adds bold italic inline link styling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Claude Code guidance file with build commands, architecture overview,
and key patterns. Replace default Vite scaffold README with project-specific
documentation including dev proxy config and deployment notes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces direct browser-to-Gitea API calls with a backend service that
proxies and caches the feed (1-min TTL), served via the existing GraphQL
HomeData query. Commit message parsing now happens server-side.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Gitea populates secret fields (LFS_JWT_SECRET, SECRET_KEY, etc.) at
startup, causing app.ini to always show as modified. Since secrets are
already passed via environment variables, the tracked file is replaced
with an ignored app.ini and a tracked app.ini.template for reference.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace 5 separate REST calls on home page load with a single GraphQL
query. Add homeData store that fetches posts, favorites, activities,
spotify, and auth in one request. Convert all admin mutations and
auth flows to use GraphQL. Add album images to Spotify GraphQL schema.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>