Remove dead admin UI code, redesign dashboard followers/following and upload experiences, and add schema audit tooling with repair migrations for forum and upload drift.
- Add Nova UI library: Button, TextInput, Textarea, FormField, Select,
NovaSelect, Checkbox, Radio/RadioGroup, Toggle, DatePicker,
DateRangePicker, Modal + barrel index.js
- Replace all native <select> in Studio with NovaSelect (StudioFilters,
StudioToolbar, BulkActionsBar) including frosted-glass portal and
category group headers
- Replace native checkboxes in StudioGridCard, StudioTable, UploadSidebar,
UploadWizard, Upload/Index with custom Checkbox component
- Add nova-scrollbar CSS utility (thin 4px, semi-transparent)
- Fix portal position drift: use viewport-relative coords (no scrollY offset)
for NovaSelect, DatePicker and DateRangePicker
- Close portals on external scroll instead of remeasuring
- Improve hover highlight visibility in NovaSelect (bg-white/[0.13])
- Move search icon to right side in NovaSelect dropdown
- Reduce Studio layout top spacing (py-6 -> pt-4 pb-8)
- Add StudioCheckbox and SquareCheckbox backward-compat shims
- Add sync.sh rsync deploy script
- Infinite loop carousels for Similar Artworks & Trending rails
- Mouse wheel horizontal scrolling on both carousels
- Author avatar shown on hover in RailCard (similar + trending)
- Removed "View" badge from RailCard hover overlay
- Added `id` to Meilisearch filterable attributes
- Auto-prepend Scout prefix in meilisearch:configure-index command
- Added author name + avatar to Similar Artworks API response
- Added avatar_url to ArtworkListResource author object
- Added direct /art/{id}/{slug} URL to ArtworkListResource
- Fixed race condition: Similar Artworks no longer briefly shows trending items
- Fixed user_profiles eager load (user_id primary key, not id)
- Bumped /api/art/{id}/similar rate limit to 300/min
- Removed decorative heart icons from tag pills
- Moved ReactionBar under artwork description
- ArtworkDownloadController: fix resolveDownloadUrl() to use correct CDN
path: original/{h1}/{h2}/{hash}.{file_ext} (was wrong originals/h1/h2/h3/orig.webp)
Wrap incrementDownloads() in try/catch so Redis failure can't break the response
- ArtworkPage: move ArtworkAuthor from left column to right sidebar
Sidebar now stacks: Author → Actions → Awards (sticky top-24)
Mobile block follows same order above main content
- ArtworkActions: replace four stacked text buttons with a compact 4-col icon grid
Like (heart, rose when active), Save (star, amber when active),
Share (network icon), Report (flag icon, red on hover)
Download remains full-width orange CTA
- ArtworkAuthor: add icons to Profile (person) and Follow buttons
Follow shows circle-check icon; Following state shows user-plus icon