Commit Graph
138 Commits
Author SHA1 Message Date
openhands f81b114b69 perf(cache): single-flight avatar renders, cacheable public reads, cheap row counts
Gitea Actions Runner Test / test-job (push) Successful in 0s
CI / check (push) Successful in 30s
CI / tests-integration (push) Successful in 1m38s
CI / tests-unit (push) Successful in 1m43s
CI / tests-ui (push) Successful in 2m30s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m7s
Three separate things that were each costing more than they needed to on the
hot path.

- Single-flight avatar renders. The disk cache was checked first and a miss
  went straight to the upstream, with nothing shared between callers, so a page
  requesting dozens of avatars at once turned N concurrent requests for one
  figure into N renders. A render is the most expensive operation this app
  does, and the duplication happened exactly when the cache had nothing to
  offer. Eight concurrent requests now cause one render instead of eight. The
  map lives on globalThis because Next can evaluate the module more than once
  per process, and two copies would each start their own render.

- Let public read-only routes be cached by a shared cache. Every JSON response
  was `cache-control: no-store`, so a CDN in front of the app could not answer
  any of it and every request reached the origin. publicCacheControl() opts a
  route in with s-maxage and stale-while-revalidate, using the same TTL as the
  server-side cache so the two layers cannot disagree. The default stays
  no-store: most routes here are personalised, admin-only or auth-dependent.
  /api/badges/leaderboard is deliberately left alone because it returns
  per-viewer rank entries to signed-in callers.

  Note this only takes effect once a cache rule exists for /api/* at the CDN, or
  the explicit `cache: "no-store"` is dropped from the client fetches (24 files
  do that today, including the /api/online poll). The headers alone are inert
  until one of those happens.

- Take the homepage row counts from the storage engine estimate instead of
  COUNT(*), which walks an index and gets slower as the tables grow. A missing
  or zero estimate falls back to the exact count rather than ever showing a
  wrong zero. The online count stays exact: it is an indexed read over a small
  subset and a few seconds of drift reads as broken rather than approximate.

The counters move into one module because the homepage and the boot warm-up
populate the same cache keys, so two implementations would race to write
different values into the same entry.

3223 tests pass.
2026-09-25 18:42:23 +02:00
openhands 203399aab7 fix(cache): true LRU, stale-while-revalidate and cross-process invalidation
Gitea Actions Runner Test / test-job (push) Successful in 0s
CI / check (push) Successful in 32s
CI / tests-integration (push) Successful in 1m38s
CI / tests-unit (push) Successful in 1m42s
CI / tests-ui (push) Successful in 2m33s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m43s
The in-process cache was a FIFO of 500 entries that was never touched on a
read, so a key polled on every request could be evicted by an unrelated burst
of dynamic keys. That looked exactly like the cache being cleared at random,
and it is what made the site fall back to the database unpredictably.

- Evict least-recently-used instead, and raise the default budget to 2000
  (CACHE_MEMORY_MAX_ENTRIES). Reading a key now marks it as used, so a hot key
  only leaves when a hotter one takes its place.
- Add opt-in stale-while-revalidate (CachedOptions.staleMs). The grace window
  lives on the entry, so one call site opting in protects every reader of that
  key. A failed background refresh keeps serving the last good value instead of
  falling through to the origin, and is reported once rather than per read.
- Invalidate across processes. invalidateKey() now clears memory, deletes the
  Redis key and publishes a signal, so a value written by one process is no
  longer served stale by the others for the rest of its TTL. A failed Redis
  delete no longer skips the broadcast.
- Guard against a refresh that started before an invalidation writing its
  outdated result back into the cache.
- Read the news revision at most once a second per process instead of on every
  call, with a pub/sub signal to drop the local copy when it rotates. A Redis
  outage now degrades to the in-process cache rather than to no cache at all.
- Warm the hot public keys on boot, so the first visitors after a deploy do not
  each pay for a miss.
- Count hits, misses, stale serves, errors and evictions per key, exposed at
  GET /api/admin/devops/cache. Without it a wrong REDIS_URL, a full budget and
  a dead origin all look identical from the outside.
- Enforce the imaging cache budget for real: records are .img/.json pairs, so
  the old cap counted files and never removed anything while entries were
  fresh. Sweeps are throttled per directory and prune to a low-water mark.
- Cap the JWT version map, and stop per-test scratch roots from littering the
  runtime imaging cache.

Public read-only endpoints get grace windows; admin, account and auth data
deliberately stays fresh. Redis TTLs get a little jitter so keys written
together no longer expire together.

3209 tests pass. next build could not be verified on this host: the optimized
build is OOM-killed before prerender, so this has not run in a real Next
runtime yet.
2026-09-25 18:26:45 +02:00
openhands b2777634f7 ci: run all workflows on the self-hosted host runner
Gitea Actions Runner Test / test-job (push) Successful in 0s
CI / check (push) Successful in 4m39s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m42s
- Switch test-runner and renovate workflows from ubuntu-latest to
  self-hosted now that a native host runner is running as a systemd service
- Replace remaining hardcoded color utilities in the homepage with theme
  tokens and inline rgba styles to satisfy the no-hardcoded-colors contract
- Restore dual UserAvatarThumbnail usage on the homepage (hero avatar stack
  plus community grid) to satisfy the public avatar presentation contract
2026-09-22 20:59:02 +02:00
openhands 628d24c0c7 feat(home): redesign landing page with cinematic hero and glass panels
Gitea Actions Runner Test / test-job (push) Successful in 1s
CI / check (push) Failing after 1m38s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
2026-09-22 20:28:23 +02:00
openhands 8a66db4ed7 fix(imaging): make avatar and badge images resilient to upstream outages
CI / check (push) Successful in 4m11s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 1m51s
- Add persistent disk cache for rendered avatars/badges (storage/imaging)
  so repeats never touch the flaky local renderer and cached renders
  survive upstream downtime
- Serve cache-first with stale-on-error; cut primary/fallback timeouts
  from 10s/6s to 4s/4s so failing images cannot stall pages
- Avatar proxy now returns a graceful 200 silhouette instead of 502 when
  no renderer can produce a figure, so no broken-image glyphs appear
- Badge endpoint becomes a caching proxy trying configured CDN, public
  Habbo CDN and local /swf copy in order, and drops the fragile IP rate
  limit that could blank badge streams
- Route all site badge images (profile, me, badges, apply pages) through
  the cached proxy instead of hot-linking images.habbo.com
2026-09-20 12:58:55 +02:00
openhands c3ff497050 feat(referrals): add referral attribution and daily login rewards
CI / check (push) Successful in 4m25s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m54s
- Track referral attribution at registration via ?ref code with
  same-IP and duplicate-pair guards
- Add daily login rewards with streak tracking, claim flow and
  sendCurrency payout backed by RCON with DB fallback
- Add admin pages for referral settings and the daily reward schedule
- Add migration 0033 with tables, seed schedule, settings and ACL grants
- Add admin.referrals.* and admin.dailyrewards.* permission slugs
- Localize new copy in en, nl and it
2026-09-20 12:29:01 +02:00
openhands d6111387e4 feat(auth): align login and register with themed intro, translated social cards
CI / check (push) Successful in 4m15s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 1m52s
2026-09-18 13:35:22 +02:00
openhands 469f69ddd7 feat(home): two-column hero with live status panel, explore nav, featured news
CI / check (push) Successful in 4m8s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m0s
2026-09-18 13:27:08 +02:00
openhands d0db352f36 feat(home): make index clearer with decluttered hero and live stats panel
CI / check (push) Successful in 4m13s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m0s
2026-09-18 13:06:26 +02:00
openhands d131124515 feat(theme): animate public background with aurora and particles, polish landing pages
Add background_effect (aurora/particles), background_overlay tint and
opacity to the theme manager, rendered site-wide by ThemeVars on every
public page. Polish the home and register pages (hero mascot, live stat
pulse, date pills, photo strip, CTA band, theme-aware register intro,
i18n for home/register section).
2026-09-18 12:44:39 +02:00
openhands 8638e81444 refactor(db): typed query helpers, shared test FormData helper
CI / check (push) Successful in 4m10s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m4s
Replace raw db.execute tuple casts with queryRows/rowsFrom/execResult/
affectedRows helpers from lib/db, drop redundant mysql2 casts on typed
query builders, and centralize per-test fakeForm into test/fake-form.
Update db mocks in tests so helpers resolve against mocked execute.
2026-09-17 21:02:57 +02:00
Simo f7b9b55700 fix(news): preserve recoverable reads and verify publication against real services
CI / check (push) Failing after 29s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-13 19:31:32 +02:00
Simo 8abfe352ef fix(security): authorize site uploads and harden tokens, media and request identity
CI / check (push) Successful in 3m15s
CI / deploy (push) Successful in 1m19s
CI / publish-container (push) Successful in 48s
2026-09-13 19:24:43 +02:00
Simo 1eee6661f9 feat(notifications): add account-scoped inbox and persistent preferences
CI / check (push) Failing after 1m18s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-13 17:59:22 +02:00
openhands d2572757cd perf(site): feature card tilt & news card zoom micro-interactions
CI / check (push) Successful in 2m26s
CI / deploy (push) Successful in 1m2s
CI / publish-container (push) Successful in 50s
- Feature cards: group hover zoom & rotate on icon badge, smoother
  card lift on hover (-translate-y-1.5).
- Stats cards: primary accent on numbers, pill badge for labels.
- News cards: smoother 500ms transition with scale-108 image zoom.
2026-09-12 18:16:29 +02:00
openhands fd7b29a5f8 feat(site): pro hero with animated ring and floating stat chips
- hero-ring: continuously shifting gradient hairline around the hero
  frame (mask-drawn, reduced-motion safe).
- glass-chip: frosted floating pills under the CTAs that bob on a
  staggered loop, live online counter keeps ticking for the Online chip.
- Taller hero for more presence on desktop.
2026-09-12 18:08:09 +02:00
openhands e5e17d75ae perf(site): inline small classic icons and favicon as base64
CI / check (push) Successful in 2m27s
CI / deploy (push) Successful in 1m34s
CI / publish-container (push) Successful in 50s
- New src/lib/site-icons.ts: base64 data URIs for the 13 tiny classic
  icons actually referenced in markup (100–2000 bytes), replacing extra
  requests with inline payloads. home.png, dynamic flags and currency
  sets stay on the filesystem.
- Default favicon is now served server-side as a base64 SVG data URI
  (memoized), while a DB-configured custom favicon still takes priority.
- Icons render through <Image unoptimized>, so data URIs pass through
  untouched on all affected pages (home, login, register, settings,
  navigation, auth top bar, client loading).
2026-09-12 17:28:01 +02:00
openhands 97012a78f6 feat(site): drifting cloud puffs across the public background
CI / check (push) Successful in 2m40s
CI / deploy (push) Successful in 2m13s
CI / publish-container (push) Successful in 2m10s
Add a fixed, decorative layer of soft clouds that slowly float across
the Habbo sky behind the content:
- Five clouds at staggered sizes, heights, opacities and loop timings
  (60s–190s) so the drift feels organic.
- Dimmed further in dark mode; frozen by prefers-reduced-motion.
- Pure decoration: aria-hidden, pointer-events: none, no color
  utilities in markup (cloud shapes live in globals.css).
2026-09-12 17:12:55 +02:00
openhands efd3b00075 feat(site): smoother motion across the landing pages
CI / check (push) Successful in 2m27s
CI / deploy (push) Successful in 1m19s
CI / publish-container (push) Successful in 1m4s
- Slow Ken Burns drift on the hero artwork for cinematic depth.
- Gentle breathing pulse on the brand glows behind Frank and the hero.
- Silkier reveal easing (cubic-bezier .22/1/.36/1, 0.55s) site-wide.
- Eased, longer hover transitions on the hero CTAs.
- Smooth page scrolling, all guarded by prefers-reduced-motion.
2026-09-12 16:51:48 +02:00
openhands bf5b9918d9 feat(site): structured landing sections with eyebrow headings
CI / check (push) Successful in 2m42s
CI / deploy (push) Successful in 1m25s
CI / publish-container (push) Successful in 54s
Give the home page a clear, professional information hierarchy:
- Add eyebrow labels + headings for Features, Live stats and Community
  sections using reusable, theme-aware .eyebrow / .section-title styles.
- Loosen the vertical rhythm (gap-8/10) so each block breathes.
- New messages resolve via the existing English fallback for all locales.
2026-09-12 16:44:21 +02:00
openhands 3265cf1fad feat(site): consistent card radius and remove duplicate login CTAs
CI / check (push) Successful in 2m32s
CI / deploy (push) Successful in 1m17s
CI / publish-container (push) Successful in 53s
Professional tidy-up of the landing experience:
- SurfaceCard: unified rounded-xl radius for a crisper, consistent look.
- Hero: matches the new card radius and gains a dual-direction title
  shadow so the headline stays readable over the header artwork.
- Login/register: drop the duplicated "no account / have an account"
  paragraphs — the forms already ship an inline footer, so one clear CTA
  cluster remains and the side column is cleaner.
2026-09-12 16:35:28 +02:00
openhands 29b9a4b0dc feat(site): professional card system and tidy landing layout
CI / check (push) Successful in 2m26s
CI / deploy (push) Successful in 1m26s
CI / publish-container (push) Successful in 1m1s
Refine the public UI for a cleaner, more professional and scannable
landing experience without leaving the classic Habbo style:

- SurfaceCard: softer layered shadow, gradient accent hairline on the top
  edge and a bolder header title across all public cards.
- Home: gradient hotel-name in the hero headline, shine effect on the
  primary CTA, hairline on the top bar.
- Login/register: consistent avatar tiles with rounded corners, subtle
  borders and a gentle hover lift; uniform username sizing.
- Add reusable theme-aware .card-hairline and .gradient-text utilities.
2026-09-12 16:29:55 +02:00
openhands d755ab7ce1 revert(site): restore classic Habbo landing with soft theme polish
CI / check (push) Successful in 2m27s
CI / deploy (push) Successful in 1m45s
CI / publish-container (push) Successful in 1m55s
Replace the premium dark-gaming redesign of home, login and register with
the original classic landing (Habbo sky background, AuthTopBar, SurfaceCard
layout). Keeps the theme background visible again and adds a subtle
theme-aware brand halo behind the hero/Frank plus a soft primary glow on
card hover.

Also upgrades dependencies: next 16.3.5, vite 8.3.0 (typescript 7.0.2 was
already latest). Temporarily lowers pnpm minimumReleaseAge to 60 min so the
fresh 16.3.5 release can be installed; restore to 1440 once it is 24h old.
2026-09-12 16:14:21 +02:00
openhands cc58f16230 fix(site): satisfy theme-color and avatar contract tests for landing redesign
CI / check (push) Successful in 2m36s
CI / deploy (push) Successful in 1m28s
CI / publish-container (push) Successful in 46s
2026-09-12 15:51:22 +02:00
openhands 741f01e897 feat(site): redesign home, login and register with premium dark gaming theme
CI / check (push) Failing after 1m5s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
Replaced the classic Habbo landing style on the home, login and register pages with a modern premium dark-gaming look: always-dark hero canvas with brand glows, grid overlay and ambient orbs, glass panels, gradient text and floating art. Adds shared LandingTopBar, AuthShell and BrandFrank components plus reusable premium CSS utilities. Build, typecheck and lint pass.
2026-09-12 15:40:54 +02:00
Simo baeb54aeb5 feat(devops): separate public page server timing diagnostics
CI / check (push) Successful in 2m23s
CI / deploy (push) Successful in 1m13s
CI / publish-container (push) Successful in 44s
2026-09-11 10:49:08 +02:00
Simo 445ef13846 fix(public): distinguish unavailable data from empty results and missing pages
CI / check (push) Successful in 56s
CI / deploy (push) Successful in 1m30s
CI / publish-container (push) Successful in 44s
2026-09-11 00:39:53 +02:00
Simo 440ce4e556 test(me): use committed translations in dashboard tests
CI / check (push) Successful in 55s
CI / deploy (push) Successful in 19s
CI / publish-container (push) Successful in 1m23s
2026-09-11 00:34:21 +02:00
Simo 74223984dc feat(profile): add privacy controls and progressive photo gallery
CI / check (push) Failing after 53s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-11 00:31:29 +02:00
Simo ba9c61d808 feat(search): search public news events users and open rooms
CI / check (push) Failing after 54s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-11 00:29:54 +02:00
Simo 506e14783c test(i18n): validate nested housekeeping translation groups
CI / check (push) Failing after 53s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-11 00:28:26 +02:00
Simo 96d3e3f602 feat(events): add weekly browsing and personal registrations
CI / check (push) Failing after 53s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-11 00:27:41 +02:00
Simo 5d18af932d feat(news): add searchable paginated publication archive
CI / check (push) Failing after 53s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-11 00:19:12 +02:00
Simo a537c55793 feat(me): show actionable personal tasks with unavailable states
CI / check (push) Failing after 53s
CI / deploy (push) Skipped
CI / publish-container (push) Skipped
2026-09-11 00:15:46 +02:00
Simo c389c3893d feat(cms): improve catalog, editorial recovery and operations
CI / check (push) Successful in 52s
CI / deploy (push) Successful in 2m10s
CI / publish-container (push) Failing after 1m18s
2026-09-09 19:36:15 +02:00
Simo 9b0ea2fb16 fix(news): restore publication flow and deduplicate dashboard friends
CI / check (push) Successful in 1m6s
CI / deploy (push) Successful in 59s
2026-09-06 18:32:43 +02:00
Simo b5dcadb67b feat(staff): present members in responsive profile cards 2026-09-06 11:53:05 +02:00
Simo 85a6df162b feat(me): organize personal dashboard and localize user actions
CI / check (push) Successful in 1m41s
CI / deploy (push) Successful in 1m29s
CI / e2e (push) Successful in 23s
2026-09-06 11:30:24 +02:00
Simo 31691c1c7d feat(profile): organize profile sections and use native currency icons
CI / check (push) Successful in 1m36s
CI / deploy (push) Successful in 1m40s
CI / e2e (push) Successful in 21s
2026-09-06 10:56:20 +02:00
Simo 6146995758 fix(profile): remove public role statistic
CI / check (push) Successful in 1m30s
CI / deploy (push) Successful in 1m29s
CI / e2e (push) Successful in 21s
2026-09-06 10:44:58 +02:00
openhands 8c12fc6c60 refactor(cms): deduplicate shared admin components and fix studio batch completion
CI / check (push) Failing after 1m35s
CI / deploy (push) Skipped
CI / e2e (push) Skipped
- fix(studio): stop markBatchDone infinite recursion so batches complete
- refactor(api): merge api-response into api and drop the duplicate module
- refactor(media): extract shared media loader and URL validator
- refactor(ui): extract shared LoadingSpinner for site and admin groups
- refactor(dates): consolidate raw date formatting into formatDate util
- refactor(logs): share a single generic log-list loader across tables
- refactor(theme): merge both ColorField components and reuse contrast helpers
- refactor(import): extract shared ImportErrorBanner and SearchInput
- chore(): remove dead theme-editor-tabs after inlining tab components
2026-09-05 20:58:42 +02:00
Simo 816e3875c2 feat(admin): add production error center and refresh CMS dependencies 2026-09-05 19:53:09 +02:00
Simo e17346ab9f refactor(cms): separate dashboard data and editor components with focused UX fixes
CI / check (push) Successful in 1m32s
CI / deploy (push) Successful in 1m20s
CI / e2e (push) Successful in 21s
2026-09-05 18:46:03 +02:00
openhands 5e598a08b4 fix: remove ssr:false from dynamic imports in server components
CI / runtime-diagnostics (push) Skipped
CI / check (push) Failing after 0s
CI / deploy (push) Skipped
CI / release (push) Skipped
Turbopack rejects ssr:false in Server Components.
Removed from 4 dynamic imports in:
- src/app/(site)/layout.tsx (RadioPlayerGate)
- src/app/admin/analytics/economy/page.tsx (RevenueChart)
- src/app/admin/analytics/page.tsx (DashboardChart, PeakHoursHeatmap)
- src/app/admin/media/page.tsx (AdminMediaGrid)
2026-09-03 16:04:48 +02:00
openhands 30c95b1a5c feat: comprehensive CMS improvements
CI / runtime-diagnostics (push) Skipped
CI / release (push) Skipped
CI / check (push) Failing after 0s
CI / deploy (push) Skipped
- Fix DOMPurify SSR crash (use isomorphic-dompurify)
- Fix SanitizedHtml to sanitize by default
- Add auth guards to studio/catalog maintenance pages
- Add update/edit to vouchers CRUD
- Add update/edit to rare-values CRUD
- Add approve workflow to applications page
- Add edit form to guilds detail page
- Add SEO metadata to all public pages (21 pages)
- Fix mobile nav accessibility (focus trap, aria attributes)
- Fix missing labels and table accessibility
- Add dynamic imports for heavy client components (6 components)
- Fix silent error swallowing (40+ locations)
- Add content scheduling for articles (publishAt, status)
- Wire up 12 missing webhook notification triggers
- Add global search to admin panel
- Add bulk actions to admin users table
- Fix JSON formatting and a11y issues
2026-09-03 16:00:32 +02:00
openhands 67b67798b9 feat(client): polished toolbar, live online count via SSE
CI / runtime-diagnostics (push) Skipped
CI / check (push) Successful in 28s
CI / release (push) Skipped
CI / deploy (push) Successful in 1m27s
- Redesign in-game client toolbar with refined glass styling and buttons
- Live online count + emulator status streamed over SSE multicast
- Who's-online tooltip throttled to reduce repeated requests
- Fix show button so it always returns the hidden toolbar
- Use theme CSS variables instead of hardcoded colors
- Add toolbar translations across all 25 locales
2026-09-02 21:14:42 +02:00
openhands 58c35a2920 feat: enforce no hardcoded colors across entire CMS
CI / runtime-diagnostics (push) Skipped
CI / check (push) Successful in 32s
CI / release (push) Skipped
CI / deploy (push) Successful in 58s
Added scripts/check-admin-colors.mjs — scans all src/ files for:
- text-white, text-black (use theme text vars)
- bg-white, bg-black (use theme background/overlay vars)
- bg/text/border/ring with gray/slate/zinc/stone palette
- bg/text/border/ring with red/green/blue/etc palette

Fixed 21 violations across 11 files:
- Overlays: bg-black/* → bg-foreground/*
- Text: text-white → text-primary-foreground
- Backgrounds: bg-white/10 → bg-background/10
- Green accents: bg-green-* → bg-primary
- Red accents: bg-red-* → bg-destructive

Integrated into:
- lint-staged: runs on every *.ts/*.tsx commit
- vitest: src/lib/no-hardcoded-colors.test.ts replaces old audit test
- Allowlist: shadcn/ui primitives (button, badge, dialog) + 4 graphical files
2026-09-01 19:33:50 +02:00
openhands adf0658916 feat: extend theme builder with block visibility, layout, effects, media, and custom CSS tabs
CI / check (push) Failing after 29s
CI / release (push) Skipped
CI / deploy (push) Skipped
- Add theme-blocks.ts registry with 24 themeable blocks across 4 categories
- Extend resolver to resolve blocks, layout, effects, media, and custom CSS per scope
- Add data-theme-block attributes to all site layout blocks
- Extend ScopedThemeVars to generate CSS for block visibility, layout vars, effect vars, media vars, and custom CSS
- Rewrite admin UI with 6 tabs: Colors, Blocks, Layout, Effects, Media, Custom
- Extend server actions to save/load all new setting types
- No database migration needed - uses existing theme_scope_values table with prefixed keys
2026-08-31 17:44:29 +02:00
openhands b57697b2e0 Polish content pages: share AuthTopBar, page-grid helper and responsive tables
CI / check (push) Successful in 37s
CI / release (push) Skipped
CI / deploy (push) Successful in 59s
- Extract shared AuthTopBar frosted top bar; reuse in login & register
- Add .page-grid class replacing 48 inline grid styles
- Add .table-scroll + .table-cell-truncate helpers; wrap leaderboard/staff tables
- Constrain settings page width (max-w-5xl) and stack profile card on mobile
- Use theme background var for shop category icon (dark-mode safe)
2026-08-31 12:23:06 +02:00
openhands d4677972cd Refine dashboard hero, mobile nav, animations and touch polish
CI / check (push) Successful in 29s
CI / release (push) Skipped
CI / deploy (push) Successful in 56s
- Stack the /me dashboard hero (avatar + info) on small screens instead of
  crowding them side by side; center the avatar and info on mobile
- Respect prefers-reduced-motion in the Reveal scroll animation
- Make the desktop pitch-in (NavDropdown) and mobile menu more consistent;
  give the mobile menu a max-height with overscroll containment so long
  navs scroll instead of overflowing on small phones
- Add safe-area insets for notched devices on header, nav and footer
- Polish whole-link content-cards (community tiles) with hover lift and a
  visible focus ring
- Enforce a comfortable min touch height on all .btn buttons
2026-08-31 12:11:04 +02:00