Commit Graph

132 Commits

Author SHA1 Message Date
soroush.asadi 494683b63b UX batch: lobby trim, private stake, coin shop, minimal toast
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 3m13s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m6s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 58s
- Lobby: remove private-room CTA (it's on Home now) → fits without scroll.
- Home: private rooms now cost 150 coins/player (stake 150).
- Buy Coins: drop the "secure payment" note; redesign packs as game-shop coin
  boxes (coin pile + amount + gold buy-price CTA), 2/3/4-col responsive.
- Notifications: minimal single-line corner toast, explicit ✕ close, hidden
  during play so it never disturbs the game.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 13:09:19 +03:30
soroush.asadi 3d3241b976 UNO polish: center nav-rail items, drop per-page XP bar, shop category tabs
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 6m33s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m6s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 1m0s
- NavRail: vertically center items in the side rail (was top-aligned).
- ScreenHeader: showXp defaults off — the level/XP bar no longer clutters every
  sub-page (it lives on Home's chip + the Profile page).
- Shop: category tabs (avatars / fronts / backs / reactions / stickers / titles
  / XP) so only one category shows at a time — no more endless scroll.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 11:53:10 +03:30
soroush.asadi 34678c4e0e Home: center the content in a max-width stage (fixes desktop right-stacking)
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 3m46s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m7s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 58s
The Home screen wasn't centered like the sub-pages, so on desktop/tablet its
content drifted to the RTL start edge with dead felt on the left. Wrap it in a
centered max-w-3xl/landscape:max-w-5xl stage, vertically center the mode cards,
and size them up for tablet/desktop (min-h + larger max-w).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 11:17:59 +03:30
soroush.asadi 5e726e88ba UNO refactor: panel-ize Auth card + Room friend-picker modal
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 3m24s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m8s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 59s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 10:42:49 +03:30
soroush.asadi ac05a7b679 UNO refactor (stage 2): responsive list/grid screens + chat
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 46s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m9s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 51s
Make all menu screens use the width on desktop/landscape and the UNO panels:
- Shop item grid 3→up to 6 cols; BuyCoins packs 2→4 cols on lg.
- Lobby: panel league pick (2-col) + 2-col CTA buttons.
- Achievements / Notifications / Leaderboard / Friends lists → responsive
  grids (1 col mobile, 2 cols on lg); glass→panel on section containers.
- Chat: centered max-w-3xl column on desktop, green send button.
All responsive for mobile + desktop. tsc + build clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 10:35:56 +03:30
soroush.asadi 5c00f44fdc UNO refactor (stage 2): Profile → tabbed 2-panel layout
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 4m6s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m7s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 59s
Restructure ProfileScreen UNO-style: tabs (نمایه / مجموعه / تنظیمات).
- Basic: player card (avatar/level/name/rank/coins/XP/VIP) BESIDE a stats grid
  + «زندگیِ حکم» ribbon + achievements summary (landscape 2-column).
- Collection: avatar / title / card-front / card-back pickers in panels.
- Settings: social + audio + sign-out.
All glass cards → .panel; every handler/feature preserved. New profile.tab*/
lifeRibbon i18n.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 09:29:11 +03:30
soroush.asadi 5b2fddee4a UNO home: mode cards + bottom nav bar
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 23s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m4s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 58s
Rebuild HomeScreen to UNO's home layout: top bar (avatar+coins) + 3 big glossy
3D mode cards in the center (Online[gold,live-count badge] / vs-Computer[teal] /
Private Room[violet]) + a bottom icon nav bar (NavRail bottom variant, drops the
redundant home item). Speed toggle + language sit in a slim controls row. Online
card shows live player count; room card creates a private room then enters it.
New menu.room/menu.roomDesc i18n.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 06:59:15 +03:30
soroush.asadi 8efd357289 UNO refactor (stage 1): emerald felt theme + kit + full Home redesign
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 32s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m5s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 58s
- Theme: retint to lit emerald card-table felt + gold (body radial felt, green
  glass panels). New component kit in globals.css: glossy chunky 3D btn-gold +
  btn-green, .panel, .ribbon. Card backs pinned to classic navy.
- Home fully redesigned UNO-style: nav rail + branding + two big 3D play
  buttons (gold online / green-glass vs-computer) + speed toggle; dropped the
  redundant 4 tiles (the rail covers them). Fits landscape (short: variants).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 04:21:50 +03:30
soroush.asadi 08d81cba65 UNO refactor (stage 1): hub shell with nav rail + internal-scroll panel
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 22s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m4s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 58s
Rebuild ScreenShell into a UNO-style app shell: a persistent NavRail (vertical
side rail in landscape, bottom tab bar in portrait — Home/Profile/Shop/Friends/
Leaderboard/Achievements, active highlighted gold) + a content panel that owns
its own scroll so the page never scrolls as a whole and uses the width in
landscape. Reskins all 10 menu screens at once. Transient screens (auth,
matchmaking, room) opt out via hideNav. New nav.home i18n key.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 01:56:52 +03:30
soroush.asadi 78dea770d7 Landscape: add short-height variant; fix Home column overflow on landscape phones
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 32s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m5s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 58s
Root cause: a landscape phone is wide (>=640px) but short, so width-based sm:
roominess inflated the title/buttons while the screen height was small -> the
right column overflowed (vs-Computer card cut off). Add a height-based
`short:` variant (@media max-height:520px) and compact Home's branding +
action cards under it so the column fits short landscape viewports.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 01:21:21 +03:30
soroush.asadi cc63312305 site: drop PWA manifest from marketing site (SEO site, not an app)
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 3m24s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m5s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 51s
Remove the web-app manifest link + manifest.ts route so bargevasat.ir no longer
triggers an "install/add to home screen" prompt. It's a plain marketing/SEO
site now. Only the game app (app.bargevasat.ir) remains a PWA.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 00:44:31 +03:30
soroush.asadi 3e37085d18 Landscape: whole-app landscape-first + Home 2-column landscape layout
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 47s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m7s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 1m0s
- Move orientation lock + RotatePrompt to app root → whole app is landscape-
  first now (UNO-style), not just the game. Generalized rotate copy.
- Home: portrait unchanged; in landscape it becomes a 2-column app layout
  (col A = branding + play actions, col B = tiles + footer) that fits the
  short height with no scroll (landscape: Tailwind variants, overflow-hidden).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 00:33:21 +03:30
soroush.asadi e8b3172197 Game: landscape-first table with rotate-phone prompt + orientation lock
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 1m14s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m9s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 59s
Hokm plays best wide (UNO-style). On phones held in portrait, the game screen
shows a "rotate your phone" overlay (with a play-anyway escape hatch so OS
rotation-lock can't trap anyone). Best-effort screen.orientation.lock('landscape')
on Android/PWA; iOS/desktop reject it harmlessly. i18n rotate.* (fa+en).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 23:53:21 +03:30
soroush.asadi c1ecdff729 Mobile: remove floating MusicToggle overlay (overlapped cards/tiles)
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 6m16s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m11s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 1m2s
The fixed-position music button covered content on mobile. Removed it from
the global overlay; mute now lives in the TopBar icon group (Home), and the
in-game HUD + Profile settings already have their own audio controls.
Tightened the TopBar icon row (p-1.5, gap-1, profile max-w-44%) so the extra
button still fits 360px phones.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 23:36:19 +03:30
soroush.asadi 7e9d83e79a Mobile: single-row logo+title on Home; add Sign Out to Profile
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 6m1s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m11s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 59s
- Home: logo and «برگ وسط» now sit on one row (prevents overflow), with
  «بازی حکم آنلاین» as a small subtitle beneath the title next to the logo.
- Profile: add a خروج (Sign Out) button at the bottom (when signed in).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 23:20:37 +03:30
soroush.asadi 48460c6282 Mobile: redesign TopBar profile chip + trim oversized Home actions
CI/CD / CI - API (dotnet build + engine sim) (push) Has been cancelled
CI/CD / CI - Web (tsc + next build) (push) Has been cancelled
CI/CD / Deploy - local stack (db + server + web) (push) Has been cancelled
- Profile chip: replace cramped fixed-width (w-[88px]) 3-line stack with a
  clean 2-line layout (name on top; level · xp-bar · % on a flexing row),
  capped at max-w-[46%] so it never crowds the icon group or overflows.
- Hero "Play online" title text-2xl→text-xl on phones (sm:text-2xl), truncate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 23:16:20 +03:30
soroush.asadi 6ed9279ac8 site: pin deps to Nexus-available versions + regenerate lockfile via Nexus
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 8m41s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m9s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 11m29s
The Docker build 404'd on @types/react@19.2.17 (not in the Nexus mirror; npmjs
is blocked upstream). Pin shared deps to the exact versions the main app uses
(@types/react 19.2.16, etc.) and regenerate package-lock.json against the Nexus
registry so every resolved tarball is one Nexus can serve.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 10:56:43 +03:30
soroush.asadi af3274ae9f Mobile: compact Home vertical rhythm so footer fits without scroll
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 6m32s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m7s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 26s
Logo/title/hero/tiles/footer spacing now scales down on small screens
(sm: breakpoints) so the menu fits common phone viewports — the sign-in/
language footer was being pushed below the fold.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 07:59:07 +03:30
soroush.asadi 29b410eefc Mobile sweep: fix matchmaking slot overflow + profile avatar picker art
CI/CD / CI - API (dotnet build + engine sim) (push) Has been cancelled
CI/CD / CI - Web (tsc + next build) (push) Has been cancelled
CI/CD / Deploy - local stack (db + server + web) (push) Has been cancelled
- MatchmakingScreen: the 4 fixed w-16 slots (~292px) overflowed 320px phones;
  now grid-fluid (w-full, gap-2 sm:gap-3, max-w-xs) so they always fit.
- ProfileScreen avatar picker now renders <Avatar id> (god/legend medallions)
  instead of raw emoji — consistent with the displayed avatar and shop.

Swept Achievements/Leaderboard/BuyCoins/Auth/Shop/Profile/Lobby/Room — already
responsive (ScreenShell + min-w-0/truncate/shrink-0 throughout); no other
overflow found.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 07:55:08 +03:30
soroush.asadi c4513f7b0c Mobile: make in-game/post-match overlays scroll-safe on short screens
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 6m27s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m7s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 27s
- GameTable Backdrop (Hakem/Trump/Round/Match-over): scroll when taller than the
  viewport via overflow-y-auto + min-h-full centering — no more clipped panels.
- DailyRewardModal: cap height + scroll (was overflow-hidden, clipped the 7-day grid).
- PostMatchRewardsModal: max-h uses dvh (mobile chrome safe).
- ScreenShell: add overflow-x-hidden so a too-wide child can't scroll horizontally.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 07:46:20 +03:30
soroush.asadi 5d38312ef0 Marketing site (bargevasat.ir) + admin-editable store links + subdomain split
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 4m40s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m7s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 41s
- New standalone Next.js marketing site under site/ (static export, SEO):
  landing, download/install guide (Bazaar/Myket/iOS-PWA/web), FAQ (JSON-LD),
  privacy, terms, support, /admin link editor. fa RTL, sitemap/robots/manifest.
- Backend: SiteLinksService (JSON-file persisted) + GET /api/site/links (public)
  + POST /api/admin/site/links (X-Admin-Token). ADMIN_TOKEN + Site__DataDir via env.
- compose: hokm-site service (:1520) + hokm_data volume for links JSON.
- CI deploy job builds + deploys the site container.
- deploy/SUBDOMAIN_SPLIT.md: nginx blocks, cert reissue, DNS, ENV split.
- Exclude site/ from root tsc + web docker context.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 07:19:43 +03:30
soroush.asadi 8d0d4dc991 Notifications: deep-link on tap + swipe-to-dismiss
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 5m49s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m10s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 49s
Each notification now navigates to its related screen when tapped (toast or
list): friend_request/invite -> Friends, achievement/reward -> Achievements,
daily -> opens the daily-reward modal, coin-purchase success -> Shop. An
explicit per-notification 'route' overrides the kind default.

List rows are swipeable (drag aside) and have an X to dismiss individually,
plus a Clear-all button; the toast can be flicked up to dismiss or tapped to
open. New store actions: markRead/remove/clearAll + openNotification navigator.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 21:38:43 +03:30
soroush.asadi 72efc03e2d Shop: every item is coin-priced; level/rank/achievement only gate the purchase
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 6m29s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m8s
CI/CD / Deploy - local stack (db + server + web) (push) Has been cancelled
No more earned-only (rank/wins) cosmetics — every avatar, card back/front,
reaction & sticker pack now has a coin price. Rank/wins/achievement become
purchase requirements (coin · coin+rank · coin+rank+achievement), enforced
client (mock + ShopScreen lock label) and server (ProfileService.ItemGate,
keyed by kind:id). Ownership = default + purchased only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 21:27:25 +03:30
soroush.asadi ccfc9b0536 Redesign avatars as a gods/legends pantheon (custom SVG medallions)
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 3m7s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m9s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 2m24s
Replaced the childish animal emoji avatars with custom inline-SVG "deity
medallions" (gradient disc + gold ring + heraldic emblem) — Athena, Zeus,
Poseidon, Horus, Odin, Thor, Cyrus, Simorgh, Ishtar, Nike, etc. IDs unchanged
so owned avatars keep working; Avatar renders the art (emoji fallback for legacy
ids). Shop now shows the art + the god name (was generic "Avatar").

Files: components/online/avatarArt.tsx (new art + pantheon map), Avatar.tsx
(render art), ShopScreen Preview (avatar → <Avatar/>), mock-service avatar shop
names from AVATAR_ART.

Verified: tsc + next build clean; web rebuilt on :1500.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 18:16:17 +03:30
soroush.asadi fd7bef36d8 fix: never cache HTML shell (no more stale bundles); tidy trick offsets
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 2m33s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m6s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 2m21s
- nginx: serve the HTML shell with Cache-Control no-store so a new deploy (new
  chunk hashes) is picked up immediately — fixes the recurring stale-bundle
  "page couldn't load" at the source. Hashed /_next/static stays immutable.
- Trick offsets set to a clean symmetric cross.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 08:04:14 +03:30
soroush.asadi 3dd22aee1e fix: post-purchase crash in CelebrationOverlay (read of null current)
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 2m22s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m5s
CI/CD / Deploy - local stack (db + server + web) (push) Has been cancelled
Card read useCelebrationStore(s=>s.current)! but AnimatePresence keeps it
mounted through the exit animation; after dismiss() sets current=null it
re-rendered and threw "Cannot read properties of null (reading 'levelAfter')",
crashing the page after every purchase/XP/daily celebration. Pass the
celebration as a prop so the exiting card keeps its data.

Verified: tsc + next build clean; web rebuilt on :1500.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 07:48:45 +03:30
soroush.asadi b0668e6e31 fix: center trick pile; add error boundary (surface post-buy crash)
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 1m51s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m4s
CI/CD / Deploy - local stack (db + server + web) (push) Has been cancelled
- Trick area: smaller offsets (±50/52) + retuned scale so the played pile sits
  centered in the felt instead of flung out to the side seats.
- ErrorBoundary around screens + overlays: a render error now shows a recoverable
  in-app message with the cause (and logs componentStack) instead of the browser's
  blank "page couldn't load" — helps pinpoint the post-purchase crash.

Verified: tsc + next build clean; web rebuilt on :1500.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 07:27:34 +03:30
soroush.asadi 12177d2a33 fix(mobile): smaller trick cards on phones; drop duplicate XP bar on Profile
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 52s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m4s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 2m21s
- Game table: played-card pile now uses sm cards on phones (vw<480) + slightly
  tighter scale, so the center trick no longer crowds/overlaps the side seats'
  avatars on a tall portrait screen.
- Profile: the screen showed two XP bars (the global header bar + the identity
  card's detailed bar). Hide the header bar on Profile (showXp=false).

Verified: tsc + next build clean; web rebuilt on :1500.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 07:08:12 +03:30
soroush.asadi 3e0c0ed876 fix(topbar): coin balance was clipped — compact large numbers + shrink bar
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 50s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m4s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 2m22s
The Home top bar overflowed on narrow screens; in RTL the coins pill is the
far-left item so its leading digits got clipped (showed "04,240" for 104,240).
- CoinsPill: compact big balances (104,240 → 104K, 1.2M), shrink-0 +
  whitespace-nowrap; exact value in the tooltip.
- TopBar: tighter gaps, profile pill min-w-0 (shrinks/truncates first), icon+coins
  group shrink-0 so it never gets squeezed.

Verified: tsc + next build clean; web rebuilt on :1500.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 06:57:45 +03:30
soroush.asadi 1fba9c2f96 fix(mobile): reward + shop-detail modals scroll on short phones
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 3m0s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m9s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 2m21s
Deep-dive responsive audit. The post-match rewards modal used overflow-hidden
and the shop detail sheet had no height cap — both could clip content (long
reward lists / sticker packs) on short or landscape phones. Added
max-h-[90vh]/[88vh] + overflow-y-auto. Audit confirmed Leaderboard, Lobby,
PublicProfile rows/modals already handle min-w-0/truncate/scroll correctly.

Verified: tsc + next build clean; web rebuilt on :1500.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 04:32:14 +03:30
soroush.asadi dcea0bc87c fix: auto-recover from stale-bundle chunk errors; responsive touch-ups
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 7m15s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m7s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 4m39s
- The "This page couldn't load" after a redeploy was a stale bundle: a tab open
  across a deploy requests JS chunks that no longer exist (ChunkLoadError). Added
  a global error/unhandledrejection guard that reloads once to fetch the fresh
  bundle (sessionStorage-guarded against loops, cleared after a healthy run).
- Reaction tray width → w-[min(270px,86vw)] so it never overflows narrow phones.

Verified: tsc + next build pass; web image rebuilt on :1500.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 00:51:36 +03:30
soroush.asadi 0847d2c7cf fix(deploy): don't let docker compose build require runtime JWT_KEY
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 5m58s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m5s
CI/CD / Deploy - local stack (db + server + web) (push) Has been cancelled
docker compose build interpolates the whole file, so the ${JWT_KEY:?} guard
failed the build step when ENV_FILE lacked JWT_KEY. Default it empty (${JWT_KEY:-})
so build/db steps succeed, and enforce the secret at runtime instead: the server
throws on boot in Production if Jwt:Key is missing/dev/<32 chars.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 00:41:26 +03:30
soroush.asadi ed3e11b64b Music mute everywhere + card-draw SFX
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 7m17s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m7s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 0s
- MusicToggle: global floating button (enable/disable music from any screen;
  hidden on the table, which has its own audio control in its HUD). Uses
  sound-store toggleMusic.
- Card sounds now use a synthesized card-draw "swish" (filtered noise burst with
  a downward sweep) for cardPlay (+ soft landing tap) and deal (a flurry),
  replacing the old beep tones.

Verified: tsc + next build pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 00:21:27 +03:30
soroush.asadi 36600fa494 docs: HANDOFF — one-game, music, prod config, 100 gated gifts
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 6m40s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m7s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 1s
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 00:04:03 +03:30
soroush.asadi 38ac8b06d1 100 gated gifts (level/rating-locked) + requirement system
CI/CD / CI - API (dotnet build + engine sim) (push) Has been cancelled
CI/CD / CI - Web (tsc + next build) (push) Has been cancelled
CI/CD / Deploy - local stack (db + server + web) (push) Has been cancelled
Adds ~100 new purchasable gifts that are LOCKED until a level/rating gate is met,
then buyable with coins — value scales with the gate:
- 45 gift avatars (types.ts), 35 gift titles + 20 gift card backs (gamification.ts),
  all reusing existing renderers. Tier (1-5) encoded in the id (-t<n>-).
- Gate model: GIFT_TIERS (shared) → reqLevel/reqRating on AvatarDef/TitleDef/
  CardBackDef + ShopItem. Tiers: t1 free, t2 Lv10, t3 Lv20, t4 Lv35, t5 Rating1700.
- Shop UI: locked cards dim + show the requirement (Lock + "Level 20"), buy
  disabled until met; mock buyItem enforces it offline.
- Server enforces generically — ProfileService parses the tier from the id and
  checks the player's level/rating (no 100-entry mirror). Mirrors GIFT_TIERS.
- i18n shop.reqLevel/reqRating (fa+en).

Verified: tsc + sim + next build + dotnet build all pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 00:02:28 +03:30
soroush.asadi e49df07c0f Prod hardening: one-game-per-player, selectable music, bargevasat.ir config
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 7m47s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m9s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 1s
- One running game per player: server rejects a 2nd matchmake while in a live
  room (re-syncs the existing game); client guards Home vs-computer + Lobby
  random/create — resumes the running match + notifies instead of starting another
  (game-store hasActiveMatch()).
- Background music is now selectable: santoor (سنتی, calm Persian loop) and
  playful (bouncy UNO-like) — sound.ts TRACKS + setMusicTrack (persisted),
  sound-store musicTrack, picker in Profile → Audio. i18n added.
- Production config for bargevasat.ir (prepare-only; no live deploy):
  appsettings.Production.example (CORS + ZarinPal + IAB to the domain),
  docker-compose.caddy.yml + Caddyfile (auto-HTTPS reverse proxy
  bargevasat.ir→web, api.bargevasat.ir→server), ENV_FILE PRODUCTION block,
  PRODUCTION.md go-live + Cafe Bazaar publish/IAB checklist. Fixed IAB package
  name to match Capacitor appId (com.bargevasat.app).

Verified: tsc + next build + dotnet build all pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 23:05:52 +03:30
soroush.asadi 265d878f22 docs: mark match-intro + chat/daily polish DONE in HANDOFF
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 7m27s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m10s
CI/CD / Deploy - local stack (db + server + web) (push) Has been cancelled
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 22:27:57 +03:30
soroush.asadi 82b2bc0648 Polish: daily reward via celebration overlay + premium chat to recipient
CI/CD / CI - API (dotnet build + engine sim) (push) Has been cancelled
CI/CD / CI - Web (tsc + next build) (push) Has been cancelled
CI/CD / Deploy - local stack (db + server + web) (push) Has been cancelled
- Daily reward now routes through the global CelebrationOverlay: new "daily"
  variant + coins count-up; claiming closes the daily modal and fires
  celebrate({variant:"daily", coins}). Unifies the "you earned X" moment.
- Premium (pro) gold chat is now visible to the OTHER player: ChatMessage gains
  senderPro; server resolves each participant's plan once (SocialService.IsPro)
  and stamps it on ChatMessageDto; ChatScreen styles incoming bubbles with
  .premium-chat when senderPro. Mock marks ~half its friends pro so it's visible
  offline too.

Verified: tsc + next build + dotnet build all pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 22:26:28 +03:30
soroush.asadi 03dfbe1e67 Match intro "players joining" loading screen + i18n fix; checkpoint
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 7m38s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m9s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 1s
- MatchIntroOverlay: UNO-style pre-game reveal — the 4 seats animate into the
  table (with "?" placeholders until each player's data streams in for live
  matches), a 3-2-1-GO countdown, then the table shows. Wired via game-store
  matchIntroPending/consumeIntro, rendered online-only in GameScreen.
- Fix: intro.found / intro.getReady / intro.go existed only in the Persian dict;
  added the English strings (would have shown raw keys to EN users).
- Checkpoint of the in-progress UI/social batch (CoinsPill, shop titles section,
  friend-request rate limit, etc.) — all green.

Verified: tsc + next build + scripts/sim.ts + dotnet build server/Hokm.slnx all pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 21:58:54 +03:30
soroush.asadi cb27a16dc1 feat: UNO-style table, social hub, cosmetics, speed mode, store IAB
Game table & play
- UNO-style restyle: suit-aware bolder cards (+xl size), pulsing playable glow,
  big "YOUR TURN" pill, active-seat ring, trick-win particle burst, round
  confetti, match coin-rain.
- Per-league turn time via turnMsForStake: 15s starter/AI, 10s pro, 7s expert;
  mirrored server-side in GameRoom.TurnMs.
- Speed (Blitz) mode for vs-AI/private: 5s turns, race to 5, ~halved pacing.
- Matchmaking waits ~15s (randomized 12-18s) then fills bots; elapsed timer + hint.

Rewards / gifts
- Richer post-match modal (floating coins, XP bar), celebration overlay reveals
  the unlocked sticker pack, boosted daily rewards (client+server synced),
  themed 7-day daily with special day-7.

Social
- Public profile modal (identity, stats, achievement board) from leaderboard /
  friends / discover / end-of-game roster; rate-limited add-friend (10/hour).
- Social hub: Friends / Discover (player search + suggestions) / Messages inbox.
- Profile gender (shown in finder/profile) + social links with public/friends/
  hidden visibility, enforced server-side.

Cosmetics
- Distinct card backs: per-design pattern families (stripes/argyle/grid/dots/
  rays/scales/crosshatch/royal/filigree/gem) + luxury motifs (lib/cardBack.ts),
  consistent on table/shop/profile; +Peacock/Rose-Gold backs.
- Purchasable titles (shop Titles section); title shown under the seat on the
  table and in discover/public profile.
- 10 new sticker packs (banter/kol-kol, Persian trends, court cards, moods).
- Persistent level+XP bar on Home and every inner screen.

Payments
- Buy-coins gateway opens in a new tab (no SPA dead-end) + focus refresh.
- Store IAB scaffolding: Cafe Bazaar deep-link purchase + redirect-token capture,
  Myket native-bridge contract, server-side IabService.Verify for both stores,
  config-driven via Iab__* env. POST /api/coins/iab/verify (JWT).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 18:39:24 +03:30
soroush.asadi e450a6a2ed docs: add HANDOFF.md (full project state) + point CLAUDE.md at it
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 21s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m1s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 1s
Single source of truth for any agent/session continuing the project: run
instructions (dev + Docker stack), architecture, the client<->server
gamification sync rule, full feature status, CI/CD + Nexus HTTP-mirror cert
workaround, gotchas, and the TODO list.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 10:47:51 +03:30
soroush.asadi b739b503eb Forfeit = 2x coin loss + 0 XP (no kot); end-of-game roster + add friend
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 21s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m0s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 0s
Forfeit penalty reworked (client + server gamification, in sync):
- Surrendering team loses DOUBLE the entry coins; winner takes the stake.
- Forfeiter earns NO XP. No kot is applied or mentioned anymore.
- MatchSummary/Dto carry a `forfeit` flag; GameRoom.FinalizeForfeit →
  ApplyRewardsAsync(team) with Forfeit=true (dropped the kot path).
- Forfeit confirm dialogs now alert the real penalty (double coins, no XP).

End-of-game roster: SeatPlayerDto/ServerSeatPlayer + game-store SeatPlayer gain
userId/isBot. New <MatchPlayersList> lists everyone at the table on the final
screen (PostMatchRewardsModal + AI MatchOverlay) with a tactile "Add" button to
send a friend request to real (non-bot, non-self) players ("Sent" after).

Verified: tsc + sim + dotnet + next build clean; stack rebuilt :1500/:1505.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 10:40:14 +03:30
soroush.asadi 6bbdbac23b UNO-style UX rollout: Lobby, Matchmaking, Profile
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 21s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m2s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 0s
- Lobby: the two hero actions (random / create room) are now tactile press-3d
  rounded-3xl with tinted icon chips.
- Matchmaking: seat slots use the Avatar frame with a gold border when filled
  (dashed placeholder when empty + spring pop-in); cancel/start/upgrade buttons
  are tactile.
- Profile: added a level badge on the avatar (casual-game style).

Verified: tsc + next build clean; web rebuilt :1500.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 10:07:51 +03:30
soroush.asadi b661385a00 Celebration animations for purchases, XP gains & achievement unlocks
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 28s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m1s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 0s
- New global celebration system: celebration-store (queue) + CelebrationOverlay
  (animated: count-up XP, filling bar, level-up pop, achievement cards; plays
  levelUp/award sounds; tap or auto-dismiss). Rendered in page.tsx.
- Shop: every purchase now celebrates — XP packs animate XP gain + level-up,
  cosmetics show a "purchased!" pop. Newly-unlocked achievements (diffed from
  the profile before/after) animate too.
- XP purchases now actually evaluate achievements: gamification.evaluateAchievements
  (client) + Gamification.EvaluateAchievements (server, called in ShopBuy xp path)
  unlock level milestones + grant their coins.

Verified live: buying XP took L1→L5, unlocked level_5 server-side and credited its
reward. tsc + dotnet + next build clean; images rebuilt :1500/:1505.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 09:52:28 +03:30
soroush.asadi be8c758425 Shop redesign: tactile cards + product detail sheet
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 26s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m1s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 0s
Answers "what's in this pack / how much XP": shop items now carry contents
(sticker ids / emojis), xp amount, and a fa/en description. Cards are tactile
(press-3d), show the artwork + name + a quick hint (item count or +XP) + price,
with an owned check badge. Tapping a card opens a detail sheet that shows the
full contents (every sticker/emoji rendered), the XP granted, a description,
and a Buy button (gold when affordable, "need coins" otherwise).

Verified: tsc + next build clean; web rebuilt :1500.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 09:04:46 +03:30
soroush.asadi 96c8abbeb3 CI/Docker: use SSL-free Nexus endpoints (mirror serves partial chain)
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 6m21s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m3s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 1s
The HTTPS Nexus serves an incomplete cert chain that container trust stores
reject (NU1301 PartialChain / UNABLE_TO_GET_ISSUER), failing CI restore/install.
- NuGet has no strict-ssl flag → point CI + Dockerfile + compose at the plain-HTTP
  Nexus (http://171.22.25.73:8081, allowInsecureConnections) — no TLS, no cert check.
- npm: add --strict-ssl=false to the CI web-check install (Dockerfile already had it);
  Docker npm registry default also moved to the HTTP Nexus.
- ENV_FILE.example documents NUGET_INDEX/NPM_REGISTRY overrides.

Local dev (Windows trusts the cert) + image base pulls (Docker trusts it) are
unaffected — only in-container package feeds switch to HTTP.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 08:53:46 +03:30
soroush.asadi 4b33ea318a Home menu UNO-style UX refactor (tactile, hero Play)
CI/CD / CI - API (dotnet build + engine sim) (push) Failing after 1m40s
CI/CD / CI - Web (tsc + next build) (push) Failing after 1m19s
CI/CD / Deploy - local stack (db + server + web) (push) Has been skipped
Keep the Persian-luxury palette, adopt casual card-game UX:
- New .press-3d primitive (solid underside that compresses on tap, reduced-motion
  aware) for tactile buttons.
- Home: a large glowing hero "Play online" button (Play icon + chevron), a
  tactile vs-computer card, and chunkier mode tiles with color-tinted icon chips
  (teal/sky/gold/rose). All handlers + i18n unchanged.

Verified: tsc + next build clean; web rebuilt :1500.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 08:45:43 +03:30
soroush.asadi 7499c222e9 Mobile UI polish pass (game-ui-design + mobile-app-ui-design)
CI/CD / CI - API (dotnet build + engine sim) (push) Failing after 1m40s
CI/CD / CI - Web (tsc + next build) (push) Failing after 1m19s
CI/CD / Deploy - local stack (db + server + web) (push) Has been skipped
Grounded in the two installed design skills:
- Safe-area insets (notch/home-bar): .safe-top/.safe-bottom/.safe-x helpers
  applied to the game-table HUD + bottom hand + reaction button, and to
  ScreenShell + HomeScreen (covers Profile/Shop/Leaderboard/etc.).
- Touch targets ≥44px: table HUD buttons (mute/forfeit/exit) and the reaction
  button now meet the 44/48px minimum.
- HUD readability: seat name/level labels (which float over the felt) get a
  text-shadow (.hud-shadow) and stronger contrast.

Verified: tsc + next build clean; web image rebuilt on :1500.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 06:38:46 +03:30
soroush.asadi 1ea3b2b8d2 Remove fake/periodic notifications (spam)
CI/CD / CI - API (dotnet build + engine sim) (push) Failing after 1m41s
CI/CD / CI - Web (tsc + next build) (push) Failing after 1m19s
CI/CD / Deploy - local stack (db + server + web) (push) Has been skipped
The mock emitted random "a friend is online / event is live" notifications on a
35s timer and the live service forwarded them. Dropped both — only real
notifications now fire (friend requests, achievements, daily reward, payment,
match-ended, and server hub events).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 00:38:08 +03:30
soroush.asadi fd33f85e9c Store XP packs (expensive), winner 2x XP, premium perks
CI/CD / CI - API (dotnet build + engine sim) (push) Failing after 1m40s
CI/CD / CI - Web (tsc + next build) (push) Failing after 1m20s
CI/CD / Deploy - local stack (db + server + web) (push) Has been skipped
- XP packs in the store (coin-priced, intentionally expensive): xp1 200/5k,
  xp2 600/12k, xp3 1500/25k. Consumable (grant XP, can level up) — server
  ShopBuy handles kind "xp" via an authoritative XpPacks map + Gamification.GrantXp;
  mock mirrors. New shop section + shop.xp/xpHint i18n.
- Every game grants XP and the WINNER earns 2x: matchXp is now
  base*(won?2:1)*leagueFactor (was a flat +80 win bonus). Mirrored server-side.
- Premium (pro) perks: 1.5x XP multiplier (applied in applyMatchResult /
  ApplyMatch by plan), plus animated shimmering gold chat bubbles for your own
  messages (premium-chat CSS; ChatScreen gates on plan).

Verified: tsc + next + dotnet build clean; sim passes; live server — buying xp2
took L1→L3 and deducted 12k coins under the new curve. Images rebuilt :1500/:1505.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 00:08:19 +03:30