Commit Graph

49 Commits

Author SHA1 Message Date
soroush.asadi d1bd279eba feat(iap): native Myket in-app billing plugin (AIDL) + wire purchase/consume
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 24s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m8s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 1m1s
Implements real Myket IAB for the Capacitor app (Myket has no purchase
deep-link like Bazaar — it uses the classic Google Play IAB v3 AIDL bound to
the Myket app):

- AIDL: com.android.vending.billing.IInAppBillingService (Myket-compatible).
- MyketBillingPlugin (Capacitor): binds ir.mservices.market via
  "ir.mservices.market.InAppBillingService.BIND", runs getBuyIntent →
  startIntentSenderForResult, verifies INAPP_DATA_SIGNATURE with the RSA key
  (Security.java, SHA1withRSA), returns the purchaseToken; consume() too.
- MainActivity registers the plugin + forwards the purchase activity result.
- Manifest: ir.mservices.market.BILLING permission + <queries> for Android 11+
  package visibility.
- build.gradle: enable buildFeatures.aidl (AGP 8 disables it by default).
- storeBilling: Myket goes through the plugin (RSA key embedded); after server
  verify, BuyCoins consumes the purchase so coins can be re-bought.

Bazaar (deep-link) and web (ZarinPal) paths unchanged. Needs on-device testing
with the Myket app installed + published products.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 20:59:56 +03:30
soroush.asadi 6641741669 feat: photo upload at level 3 + report a player (nudity avatar / chat insult)
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 2m58s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m9s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 1m0s
Photo upload:
- Lower the custom profile-photo gate from level 25 to level 3 (client const +
  i18n hint + server gate in ProfileService.Update). The level-25 "Expert" title
  is unrelated and unchanged.

Report a player:
- New ReportReason type + service.reportUser(targetId, reason, details?).
- Report entry points: a "گزارش تخلف" button + reason picker (nudity / insult /
  other) in the public-profile modal, and a flag button in the chat header
  (reports the peer for an insulting chat) with a confirmation toast.
- Mock records reports to localStorage; SignalR POSTs /api/report.
- Server: POST /api/report → ProfileService.ReportUser stores the report in the
  write-only ledger (kind="report", ref="{targetId}|{reason}|{details}") so no
  schema change is needed (server uses EnsureCreated, not migrations).
- i18n: report.* keys (fa + en).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 19:12:02 +03:30
soroush.asadi ad5b42db06 feat(profile): "set your city" gamification box → one-time 500-coin reward
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 28s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m10s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 1m6s
- New searchable city picker (src/lib/iran-cities.ts, ~60 Iranian cities,
  fa/en search) shown as a gold reward card at the top of the profile Basic tab.
- First time a non-empty city is set, the player earns 500 coins (CITY_REWARD),
  granted server-authoritatively. Collapses to a compact summary afterwards with
  a "change city" option (no re-reward).
- Frontend: UserProfile.city + cityRewardClaimed; mock-service grants on first
  set; session/service updateProfile accept `city`; celebratory toast + sfx.
- Backend (.NET): ProfileDto.City/CityRewardClaimed (JSON blob → no migration);
  ProfileService.Update grants +500 once and writes a "city" ledger entry.
- i18n: city.* keys (fa + en).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 18:11:45 +03:30
soroush.asadi efefbcec3d Lobby: leagues are play buttons w/ arrow; remove background music feature
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 35s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m14s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 58s
- OnlineLobbyScreen: each league row is now a tappable play button (queues a
  ranked match at that league's stake) with a forward arrow; the cheapest
  enterable league is highlighted gold. Drops the redundant separate "ranked
  random" CTA and the select-then-play step.
- Remove the background-music feature entirely: deleted the floating MusicToggle,
  the TopBar music button, and the Profile audio music toggle + style picker.
  sound.startMusic() is now an inert no-op so music never plays (sfx unchanged).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 17:23:26 +03:30
soroush.asadi deb83cf77c UX: landscape result screen, chat emojis, unread badges, remove XP text
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 4m33s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m7s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 55s
- PostMatchRewardsModal: short-height (landscape) compaction so the win/forfeit
  result fits without overflow (smaller emoji/coins/padding, max-h 94dvh, wider).
- Chat: emoji/sticker picker (owned reactions) — tap to send; hidden on focus.
- Unread messages: online-store now tracks a total `unread` (from
  listConversations); NavRail Friends icon shows a badge (unread + requests),
  refreshed every 12s on every screen; Friends «پیام‌ها» tab badged too.
  (Per-conversation unread badges already existed.)
- Remove "XP گران است" / "XP is expensive" from shop.xpHint.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 14:58:43 +03:30
soroush.asadi 24a2c251ad UX batch 2: room landscape-fit, rank vs league naming
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 3m43s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m6s
CI/CD / Deploy - local stack (db + server + web) (push) Successful in 58s
- Room: teams side-by-side in landscape so all 4 seats fit (still scrolls).
- Achievements: rename the 5 rating tiers from «لیگ» (league) to «رتبه» (rank)
  + category «رتبه» — so "league" only means the 3 playable match leagues.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 13:21:28 +03:30
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 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 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 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 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 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 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 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 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 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 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 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 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
soroush.asadi 4199a82c9d More cosmetics (rank-gated) + steeper level curve capped at 100
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
Cosmetics — many new variants, the rarer ones gated behind higher ranks:
- Card backs: +midnight/jade/onyx (buy) + crimson/aurora/obsidian/imperial
  (earned by wins/rating up to Master). Card fronts: +sunset/velvet/onyx (buy)
  + goldleaf/crystal/imperial (earned).
- Titles: +marksman, untouchable, sweeper, ruler, platinum_star, diamond_ace,
  immortal, the_one (gated by kots/streak/shutouts/hakem/rating/level/wins),
  mirrored on the server so live games grant them.
- Avatars: list expanded + rank/wins-earned tier (robot/wizard/ninja/king/
  genie/crown) via new ownedAvatarIds(); profile picker shows earned ones,
  shop sells the priced ones.
- Stickers: new Persian-text stamp pack (کوت! / دمت گرم / باریکلا / آخه؟) plus a
  rank-earned Victory pack (بردیم!/حکم) — new inline-SVG art.

Leveling: XP per level now grows (100*l + 15*l²) so each level is harder; higher
leagues grant more XP (×1.5 at 500 stake, ×2 at 1000) so you progress by playing
up. Hard cap at level 100. Mirrored in server Gamification (XpForLevel/MatchXp/
AddXp). Sim now tops out lower (level 20 vs 35 over 500 matches) as intended.

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

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 23:43:21 +03:30
soroush.asadi dfb1deee8c Leaderboard avatar+level+XP bar; mobile table overlap fixes
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 55s
CI/CD / CI - Web (tsc + next build) (push) Failing after 1m26s
CI/CD / Deploy - local stack (db + server + web) (push) Has been skipped
Leaderboard: each row now shows the player avatar (photo or emoji) with a level
badge ring and a progress-to-next-level bar (LeaderboardEntry gained
levelProgress + avatarImage; mock fills real XP for you, random for others).

Mobile table: the played-card pile now scales inward on narrow screens so it no
longer overlaps the opponents' side stacks (trickScale by viewport); seat
avatars render above the stacks (z-20) so the side player isn't hidden; side
hands nudged to the edges + top hand raised slightly on phones.

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

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 23:07:51 +03:30
soroush.asadi b66e7f77a5 100+ achievements, forfeit, leagues floor, bot humanize, 95k starter
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 40s
CI/CD / CI - Web (tsc + next build) (push) Failing after 1m20s
CI/CD / Deploy - local stack (db + server + web) (push) Has been skipped
Achievements: generator-driven, now 100+ across 7 categories (added Rulership)
mirrored client + server with identical ids/goals/coins. New tracked stats:
hakemRounds (be the hakem — incl. "7× Hakem"), roundsWon, plus losses metric.
Custom achievement-only sticker packs (Rulership 👑, Firestorm 🔥) with new
inline-SVG art (crown-gold, seven-zip, streak-fire), unlocked by hakem_7 /
streak_10. Server GameRoom tallies hakem rounds per seat + rounds won per team;
client tallies the same for vs-computer/private games (dealId-deduped).

Forfeit (surrender): a player can request forfeit; if the teammate is a bot it
auto-confirms, otherwise the human teammate gets a confirm/decline prompt
(20s timeout). Result: forfeiting with ≥1 round won = normal loss; 0 rounds = Kot.
Wired client↔server over the hub (RequestForfeit/ConfirmForfeit/DeclineForfeit
+ "forfeit" event); offline/vs-computer ends immediately in the store. Flag
button + confirm dialogs in the table.

Online count: never shows below 50 — live service floors the real count with a
drifting believable number (mock base lowered to ~50–170).

Matchmaking: real players get a longer priority window (9s) before bots fill;
bots now occasionally react after winning a trick (humanize).

Coins: starter pack is 95,000 Toman (50k coins); packs rescaled up (server + mock).

Verified: dotnet build + tsc + next build clean; sim unlocks 57 achievements/500
matches; live server: starter=95000, a 7-hakem win unlocks hakem_7 + wins_1 with
hakemRounds/roundsWon persisted. Images rebuilt on :1500/:1505.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 22:47:36 +03:30
soroush.asadi 7a18bc39e6 Achievements overhaul: 37 achievements, page with tabs, leagues, gating
CI/CD / CI - API (dotnet build + engine sim) (push) Failing after 1m40s
CI/CD / CI - Web (tsc + next build) (push) Failing after 1m21s
CI/CD / Deploy - local stack (db + server + web) (push) Has been skipped
Achievements (client + server mirror, metric-driven so the list is one source):
- 37 achievements across 6 categories (Victories, Kot, Streaks, Levels, Ranks,
  Veterancy) incl. 7–0 sweeps, kot milestones (1/5/10/25/50/100), win streaks
  (3/5/10/15), level milestones every 5 (5..50), rank floors, games/tricks.
- New AchievementsScreen with category tabs, progress bars, coin + sticker-unlock
  badges, and unlocked/locked states; summary header (unlocked count + coins).
- Some achievements unlock sticker packs: Seven–Zip→Hokm, 25 Kots→Taunts,
  100 Wins→Persian (ownedStickerPackIds now also honors profile.unlocked).
- Prestige titles added: Expert, Professional, Captain, Leader (+ existing).
- Tracks new stat shutoutWins; MatchSummary.shutout (7–0). Profile shows a
  6-item preview + "view all" link.

Leagues: 3 ranked entry tiers — Starter (100, lvl1), Pro (500, lvl10),
Expert (1000, lvl20). Higher league stakes more, so wins/losses swing bigger;
kot bonus now scales to the stake (40%). OnlineLobby shows league cards with
level gating.

Profile photo upload gated to level 25 (client button + server Update guard).

Win animation: PostMatchRewardsModal now shows an animated coins-won count-up
hero on a win.

Verified: dotnet build + tsc + next build clean; sim unlocks 26 achievements
over 500 matches; live server grants first_win/first_kot/shutout_1 and pays
2050 coins on an expert-league shutout+kot win. Images rebuilt on :1500/:1505.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 21:47:38 +03:30
soroush.asadi d66208e39e Resume: exiting a match keeps it alive instead of destroying it
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
Leaving the table (back button, browser/hardware back) no longer resets the
game — it minimizes it and stays resumable:
- game-store: add `paused` + minimize()/resume(). Single-player (AI) matches
  pause their local timers so nothing happens while away; live (server-run)
  matches keep streaming via the still-active subscription (the .NET GameRoom
  already runs the match to completion and re-broadcasts state on reconnect).
- GameScreen: an unmount effect minimizes any in-progress match no matter how
  you leave; only a finished match (reward dismissed) tears down.
- ResumeGameBar: floating "return to game" pill shown from any screen while a
  match is alive, or while a finished match still has an unseen reward.
- page.tsx: after a full reload, re-enter live mode (minimized) when the server
  re-broadcasts state, and notify when a match you left finishes while away.

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

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 20:58:05 +03:30
soroush.asadi cfed2950b2 Add ZarinPal sandbox payments for buying coins (config-driven merchant)
- ZarinpalService (request/verify) + /api/coins/pay/request (JWT) and
  /api/coins/pay/callback (verify → credit via ProfileService.BuyCoins → redirect
  back with ?pay=success); merchant id from config (sandbox default)
- Client buyCoins (live) returns the StartPay redirect URL; BuyCoinsScreen
  redirects; page.tsx handles the ?pay return (notify + refresh)
- Verified: sandbox request returns a real StartPay URL
- Documented Cafe Bazaar (Poolakey) / Myket IAB as the required store payment path

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 17:59:30 +03:30
soroush.asadi 4f2e4e14ea Server-authoritative economy: wire client to server; entry + rewards on hub
Server:
- daily (/api/daily, /api/daily/claim) + shop (/api/shop/buy) + ChargeEntry
- GameRoom (via IServiceScopeFactory) deducts ranked entry at match start and
  applies match rewards at match-over, broadcasting profile + reward over the hub
- tested: daily, shop (owned-guard), ranked entry deduction pushed over hub

Client:
- SignalrService routes profile/coins/plan/daily/shop/match to the server (Bearer);
  onProfile/onReward hub events; guest/offline fall back to local
- session-store syncs profile from hub; game-store serverReward; GameScreen shows
  live ranked reward from hub (no double submit), submits client-run games
- single source of truth in live mode (no economy divergence)

Postgres-ready via config (Provider=postgres); EnsureCreated for now.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 17:32:47 +03:30
soroush.asadi cdb8d522dd Economy: free vs paid games + buy-coins page; friends remove confirmation
- Coins only matter for ranked: free games (vs computer / private friend rooms)
  cost nothing; random ranked requires an entry (stake), gated by balance →
  routes to buy-coins when short
- Buy Coins page (CoinPack/getCoinPacks/buyCoins; mock credits now, real
  Zarinpal/IDPay TODO); TopBar coins → buy; lobby create-room is Free
- Friends: removed instant red ✕ delete; UserMinus → inline confirm before remove

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 16:28:59 +03:30
soroush.asadi fe136f7ee4 Auth: email/Google "coming soon"; mobile polish pass on the table
- AuthScreen: phone+OTP is the only active method; email & Google shown as
  disabled "coming soon" buttons (until SMTP/Gmail are configured)
- GameTable responsive: compact scoreboard, smaller seat avatars, and
  turn-indicator/timer positions tuned for small screens

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 16:11:30 +03:30
soroush.asadi 2d2352dfe8 Add in-app + real-time notifications (SignalR/mock, Iran-friendly)
- AppNotification + OnlineService.onNotification (hub event + mock periodic) —
  no FCM/APNs (blocked in Iran); uses the existing realtime channel
- notification-store + pushNotification(); 🔔 bell with unread badge in TopBar,
  notifications screen, global toaster (plays notify sfx)
- Wired events: daily reward, post-match achievements, friend requests
- Closed-app push (Pushe/Najva/Chabok) noted as a later step (needs provider keys)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 15:52:06 +03:30
soroush.asadi ceccf70de7 Wire client SignalrService to the live .NET backend
- @microsoft/signalr client implementing OnlineService: REST auth, hub
  matchmaking, server-driven game state (onState), play/trump, reactions;
  delegates not-yet-server-backed features (profile/friends/shop/chat/rooms)
  to the mock. Selected via NEXT_PUBLIC_USE_SERVER=1 (NEXT_PUBLIC_SERVER_URL)
- game-store live mode: enterServerMatch + applyServerState (maps server DTO,
  hides opponent hands, tally + SFX), inputs route to the hub; no local engine
- MatchmakingScreen auto-enters the live match when the server signals ready
- Verified end-to-end via scripts/live-test.mjs (auth -> hub -> match -> state)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 13:13:48 +03:30
soroush.asadi a3b797c8a3 Add History API routing so browser/Android back navigates screens
- ui-store syncs screens to history (push on go/goGame, hash URLs like #/profile),
  back() = history.back(), initHistory anchors a home base + restores deep links
- page.tsx listens to popstate; resolveScreen() guards transient screens
  (game/room/chat/matchmaking fall back to home when their state is gone)
- ScreenHeader + ChatScreen back buttons use history back; chat cleans up on unmount

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 12:56:14 +03:30
soroush.asadi ae239f4c51 Split card design into front+back, add sound effects & background music
Card design:
- Separate cardFront + cardBack (each own/equip independently)
- Fronts: classic (free), ivory/rosegold (buy), parchment/mint (earned)
- Backs: classic (free), sapphire/emerald (buy), ruby/royal (earned)
- PlayingCard `front` prop; table applies front to all faces, back to opponents
- Profile has front + back pickers; shop has both sections

Audio:
- Web Audio synth engine (no asset files): SFX for card/deal/trump/trick,
  win/lose, message, notify, award, levelup, purchase, kot + ambient music
- Toggles in profile (Audio) + mute button in game HUD; prefs persisted
- Wired across game-store, rewards, daily, shop, chat

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 11:49:19 +03:30
soroush.asadi db4eade619 Add designed sticker packs (SVG art) to the reactions system
- 15 hand-designed inline-SVG stickers (faces, Hokm: حکم/کُت/crown/ace,
  Persian: chai/آفرین/rose, taunts: clown/zzz/ضعیف) in components/online/Sticker.tsx
- Sticker packs: faces (free), hokm (earned @rating 1300), persian & taunt (buy)
- In-game tray now tabbed Emoji | Stickers; stickers broadcast as "sticker:<id>"
  and render as large animated bubbles per seat
- Shop sells sticker packs; profile.ownedStickerPacks; gamification helpers
  ownedStickers/ownedStickerPackIds; mock opponents send stickers too

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 11:15:28 +03:30
soroush.asadi f9425dea01 Add reactions (Sheklak), fix hakem card visibility during trump choice
- Reactions/emotes in-game: tray of owned emojis + animated per-seat bubbles
  (feature named "شکلک / Sheklak"). Packs: starter (free), champion/legend
  (earned by rating/wins), emotions/taunt (purchasable in shop)
- OnlineService.sendReaction/onReaction; mock echoes you + random opponents
- Fix: human hakem's 5 cards were blurred behind the trump-chooser overlay —
  raise hand to z-50 during choosing-trump so cards stay readable

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 11:02:25 +03:30
soroush.asadi 13ec0d4300 Turn timer + auto-play, disconnect/reconnect, cosmetics, queue & paid plan
- Turn timer (20s) for play/trump; system auto-plays a smart move on timeout
- Disconnect handling (mock): wait-for-return countdown, system covers turns
- Cosmetics: titles, card-back styles, custom profile-image upload, badges;
  pickers in Profile; shop sells card styles; reward modal shows new titles
- Paid plan (pro): free players queue when server busy, pro skips; upgrade flow
- OnlineService extended (upgradePlan, richer profile patch); mock implements
  queue + plans; gamification adds TITLES + CARD_STYLES

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 10:49:54 +03:30
soroush.asadi 5776036d78 Add friend chat; replace betting wording (شرط) with entry coins
- Friend-to-friend chat outside the game (ChatScreen) with mock replies,
  per-friend history, unread tracking; chat button on each friend row
- OnlineService + mock + online-store extended with chat (list/get/send/markRead)
- Reframe gambling term: "شرط"/"Stake" -> "سکه ورودی"/"Entry coins";
  free entry labeled رایگان/Free

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 10:21:44 +03:30
soroush.asadi e2d0a602b6 Build Hokm card game: offline vs-AI + online social/gamification (mock backend)
- Pure-TS Hokm engine (deal, hakem, trump, tricks, scoring, Kot) + AI bots
- Persian-luxury RTL UI (Next 16 / React 19 / Tailwind v4 / Framer Motion / Zustand)
- Online platform behind OnlineService seam (mock now, .NET SignalR later):
  auth (phone OTP + email/Google), profiles, friends, private rooms with
  partner pick, ranked matchmaking, leaderboard, shop
- Gamification: ranks/leagues, coins, XP/levels, daily rewards, achievements
- i18n fa/en, PWA manifest, engine + gamification sims

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 10:11:00 +03:30