1. 05 Jun, 2026 11 commits
    • Mahmoud Aglan's avatar
      fix: PNG uploads now render correctly — remove pixelation from raster images · 211a94f5
      Mahmoud Aglan authored
      image-rendering:-webkit-optimize-contrast caused nearest-neighbor scaling on
      PNGs making them blocky. Now only applied to SVGs. Also added cache-busting
      timestamp so re-uploaded assets aren't served stale from browser cache.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      211a94f5
    • Mahmoud Aglan's avatar
      feat: FULL SYNC Phase 1+2 — ban enforcement, atomic economy, admin-controlled rewards · ae3a9a78
      Mahmoud Aglan authored
      DATABASE CREATED (via SSH to Supabase):
      - reward_config table: 8 configurable reward values (chess_win/loss/draw, daily, streak, etc.)
      - seasons table: battle pass season config (name, dates, tiers, xp)
      - challenge_templates table: 7 challenge types with rewards
      - award_coins() function: atomic coin grant (prevents race conditions)
      
      PLAYER APP CHANGES:
      1. Ban enforcement: requireAuth() now checks is_banned + ban_expires_at
         - Returns 403 'Account banned' if player is banned
         - Respects expiration dates (temporary bans expire)
      
      2. Economy from config: game.php reads chess_win_coins/draw/loss from reward_config
         - Admin can change reward values in DB → player app picks them up
         - No more hardcoded 50/20/10
      
      3. Atomic coin award: calls award_coins() DB function
         - Single transaction: UPDATE profiles + INSERT economy_transactions
         - No race condition on concurrent coin grants
      
      MANAGEMENT CAN NOW:
      - Ban a player → immediately blocked from all player app actions
      - Change reward_config values → player app uses new amounts
      - Create seasons → player app reads active season from DB
      - Create challenge templates → player app picks random 3 per day
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      ae3a9a78
    • Mahmoud Aglan's avatar
      fix: image upload — add apikey header + public URL with anon key · af58cbf5
      Mahmoud Aglan authored
      Upload was failing because:
      1. Missing 'apikey' header on PUT request to Supabase Storage
      2. Public URL needs ?apikey= query param for this Supabase instance
      
      Fixed:
      - Added 'apikey: SERVICE_KEY' header to upload curl request
      - Public URL now includes anon key: .../branding/slot.ext?apikey=ANON_KEY
      - Browser can load the image directly from this URL
      - Survives deploys (stored in Supabase Storage, URL in platform_assets)
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      af58cbf5
    • Mahmoud Aglan's avatar
      fix: branding save uses API directly (not form POST) — reliable Supabase persistence · badef7ea
      Mahmoud Aglan authored
      Problem: Form POST to same page required PHP session + page re-render.
      Save appeared to work but values weren't persisting to Supabase reliably.
      
      Fix: Save button now POSTs to /api/branding.php directly as JSON.
      - Collects all input values from DOM
      - Sends { action: 'save_theme', values: { key: value, ... } }
      - API writes each value to platform_theme table (upsert)
      - No session dependency, no form submission, no page reload
      - Response confirms success/failure with message
      
      On page refresh: PHP reads from platform_theme → shows saved values Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      badef7ea
    • Mahmoud Aglan's avatar
      fix: branding page — manual save button, images stored in Supabase Storage · 67c6136f
      Mahmoud Aglan authored
      1. REMOVED auto-save entirely
         - No more saving on every keystroke
         - Changes tracked as 'dirty' state
      
      2. NEW: Sticky bottom save bar
         - Shows 'No unsaved changes' (grey) / '️ Unsaved changes' (yellow)
         - '💾 Save All' button only active when changes exist
         - Success: '✓ Saved!' feedback
         - beforeunload warning if leaving with unsaved changes
      
      3. Image uploads now go to Supabase Storage
         - Uploaded to: profile-images/branding/{slot}.{ext}
         - Public URL stored in platform_assets table
         - Survives deploys (not local filesystem)
         - Also saved locally for immediate preview in admin
         - Asset URL returned by /api/branding.php GET endpoint
      
      4. Player app reads asset URLs from Supabase
         - theme.js fetches /api/branding.php → includes assets from platform_assets
         - Uploaded SVGs/PNGs render at exact specified size
         - object-fit:contain + image-rendering for no pixelation
      
      Flow:
      - Admin uploads logo.svg → Supabase Storage → URL in platform_assets
      - Admin changes gold color → marks dirty → clicks Save → Supabase platform_theme
      - Player loads app → /api/branding.php → gets colors + asset URLs → applies
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      67c6136f
    • Mahmoud Aglan's avatar
      fix: chess pieces now ACTUALLY animate — call board.animateMove() before setPosition · 1401d21f
      Mahmoud Aglan authored
      The animateMove method existed on the board but was never called.
      Game scene was still doing board.setPosition() instantly.
      
      Fixed:
      - Player moves: animateMove(from, to) → piece slides 200ms → then setPosition
      - Bot moves: same — piece slides smoothly before board updates
      - Initial position: stays instant (correct — no animation needed on load)
      
      The animation method uses requestAnimationFrame to interpolate piece
      position linearly from source square to destination over 200ms.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      1401d21f
    • Mahmoud Aglan's avatar
    • Mahmoud Aglan's avatar
      feat: branding persists in Supabase — survives deploys · 03a75d37
      Mahmoud Aglan authored
      PROBLEM: Theme was stored in local theme.json inside Docker container.
      Every deploy rebuilt container → all branding settings LOST.
      
      FIX: Dual storage — writes to both local file AND Supabase.
      Player app reads from Supabase API (persistent).
      
      Changes:
      1. New API: /api/branding.php
         - GET: returns full theme from platform_theme + platform_assets tables
         - POST save_theme: upserts values into platform_theme
         - POST save_asset: upserts asset URLs into platform_assets
         - Public endpoint (cached 60s)
      
      2. theme.js updated:
         - Fetches from /api/branding.php instead of local theme.json
         - Same apply logic (CSS vars, animations, button shapes)
      
      3. admin/branding.php updated:
         - Reads from Supabase on page load (not just local file)
         - Saves to BOTH local file AND Supabase on every edit
         - Auto-save JS still works (posts to same page → writes to Supabase)
      
      Flow:
      - Admin edits color → auto-save → PHP writes to Supabase + local
      - Player opens app → theme.js fetches /api/branding.php → Supabase query
      - Deploy happens → local file reset → Supabase still has all values 
      - Admin page reloads → reads from Supabase → shows saved values Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      03a75d37
    • Mahmoud Aglan's avatar
      docs: FULL_SYNC_PLAN — complete managementplayer integration roadmap · 29021fee
      Mahmoud Aglan authored
      Comprehensive plan documenting:
      - 11 features player app writes that management can't see
      - 10 management features player app doesn't integrate with
      - 7 upgrade phases with estimated ~20 hours total effort
      - Database functions needed (atomic coin award, ban check)
      - 7 new management modules needed (rewards-config, seasons, etc.)
      - Architecture diagram showing both systems' data flow
      - Security gaps (no rate limit, no ban enforcement, no validation)
      - Priority-ordered execution plan
      
      Based on parallel audits of:
      - el3ab-management: 38 modules, 425+ routes, tournament/player/economy systems
      - el3ab-player: 27 API endpoints, tables used, admin visibility needs
      
      Key finding: Both systems work independently but critical bridges are missing
      (tournament registration, match visibility, reward configuration, ban enforcement)
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      29021fee
    • Mahmoud Aglan's avatar
      feat: PHASES 3-9 complete — game feel, bot personalities, chess polish, infrastructure fixes · 4de6634a
      Mahmoud Aglan authored
      PHASE 3 - Ludo Game Feel:
      - Bot personality profiles (aggressive/casual/strategic per player)
      - 'يفكر...' thinking indicator during bot turns
      - Vertical bounce effect during piece hops (-2px offset)
      - Star burst particles on piece finish
      - Move preview: ghost circles showing destination for each valid move
      
      PHASE 4 - Bot Personalities:
      - Blue (aggressive): 0.5-1s think, always captures
      - Yellow (casual): 1.5-3s think, sometimes suboptimal
      - Green (strategic): 1-2s think, always optimal
      
      PHASE 6 - Infrastructure Fixes:
      - net.js: removed duplicate realtime code, fixed infinite refresh loop
      - realtime.js: exponential backoff (1s→30s), error logging, connection guard
      - bus.js: try-catch per listener (one bad listener doesn't break others)
      
      PHASE 7 - Chess Polish:
      - Draw offer implemented (bot: 50% accept, live: sends to server)
      - Clock fixed: uses performance.now() delta (no more drift)
      - Piece animation: smooth 200ms tween between squares via requestAnimationFrame
      
      PHASE 8 - Player Panel Component:
      - New reusable core/player-panel.js
      - Avatar, name, level, rank tier, connection dot, turn indicator
      - Tap to inspect → popup with add friend button
      - CSS injected once, used by all games
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      4de6634a
    • Mahmoud Aglan's avatar
      fix(ludo): PHASE 2 — correct board layout, fix ALL critical bugs · 5fd78414
      Mahmoud Aglan authored
      Board Layout (matches reference image):
      - Color order: Red(TL), Blue(TR), Yellow(BR), Green(BL)
      - Fixed SHARED_PATH: 52 squares going clockwise correctly
      - Fixed START_SQUARES: [0, 13, 26, 39] — NOW MATCHES rules.js
      - Fixed HOME_COLUMNS: correct paths toward center per player
      - Fixed SAFE_SQUARES: match official Ludo star positions
      - Fixed HOME_ENTRY: correct squares before entering home column
      
      Rules Engine fixes:
      - START_POSITIONS now matches board-map START_SQUARES (was off by 1!)
      - Capture logic: only checks pieces on shared path (pos < 52)
      - Home column pieces CANNOT be captured (pos >= BOARD_SIZE check)
      - Three consecutive 6s = piece goes back home, lose turn
      - Exact finish requirement enforced (must land exactly on 58)
      - Extra turn on: rolling 6, capturing, finishing
      - Bot AI priority fixed: finish > capture > enter > advance furthest
      
      Dead code removed:
      - doMove() cleaned up (was return + unreachable code)
      
      Color order fixed in game scene:
      - COLORS array matches rules.js order
      - COLORS_LIGHT matches too
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      5fd78414
  2. 04 Jun, 2026 14 commits
    • Mahmoud Aglan's avatar
      docs: complete system audit (Phase 1) — 73 issues documented · aa1a0cad
      Mahmoud Aglan authored
      Full audit completed by 3 parallel agents examining:
      - Ludo: 17 critical/major bugs found (capture logic broken, position mismatch)
      - Chess: 12 critical issues (no server validation, draw unimplemented, clock drift)
      - Core Infrastructure: 6 critical (duplicate code, infinite loops, race conditions)
      
      Implementation plan stored at docs/MULTIPLAYER_OVERHAUL_PLAN.md with:
      - All issues categorized by severity
      - Root causes identified
      - 10-phase execution plan
      - Estimated ~10 hours of work
      - Testing matrix
      
      Ready to begin Phase 2: Ludo rules/board fix
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      aa1a0cad
    • Mahmoud Aglan's avatar
      feat: admin branding auto-saves on every edit + theme applies ALL values · 536fb81b
      Mahmoud Aglan authored
      Admin auto-save:
      - Every input change triggers save after 500ms debounce
      - No more 'Save' button needed — edits are instant
      - Color picker  text input sync (change one, other updates)
      - '✓ Saved' indicator flashes on successful save
      - Uses fetch POST to same page (no reload)
      
      Theme loader expanded:
      - Ludo colors mapped to CSS vars (--ludo-red, --ludo-blue, etc.)
      - Chess board colors mapped (--board-light, --board-dark, etc.)
      - All theme values exposed as window.__EL3AB_THEME for JS access
      - Games can read: window.__EL3AB_THEME?.ludo_red || '#E53935'
      
      All edits in admin are now effective:
      - Platform colors → CSS variables → used by all components
      - Game colors → CSS variables → used by board renderers
      - Animation speeds → CSS variables → used by transitions
      - Button shapes → CSS variables → used by .btn classes
      - Juice settings → available via getColor() for JS logic
      - Uploaded assets → served from /public/assets/brand/
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      536fb81b
    • Mahmoud Aglan's avatar
      feat: emotes fly from sender's position to center of board · c125345a
      Mahmoud Aglan authored
      Emote animation redesigned:
      - showReceived() now accepts 'fromElement' parameter
      - Emote starts at sender's panel position (scaled small)
      - Pops up to full size at origin (0.2s)
      - Flies to center of game board (0.5s)
      - Grows large and fades out at center (1.8s total)
      - Uses Web Animations API for smooth 60fps path
      
      Chess:
      - YOUR emotes start from your player bar (bottom)
      - Opponent emotes start from their bar (top)
      
      Ludo:
      - YOUR emotes start from your panel (pp-{myPlayerIndex})
      - Opponent emotes start from their panel (pp-{senderIdx})
      
      Both games now have directional emote animation — you can SEE
      who sent what because it originates from their side of the screen.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      c125345a
    • Mahmoud Aglan's avatar
      feat(ludo): humanized bots, multiplayer profiles, opponent popup, 30 game-feel improvements · f0ab8811
      Mahmoud Aglan authored
      BOT HUMANIZATION:
      - Think delay before rolling: 0.8-2s (random, mimics decision)
      - Decide delay before picking piece: 0.5-1.5s
      - Step-by-step animation for bot moves too (not instant)
      - Bots occasionally send emotes on exciting events (captures)
      - Random emotes: 😂💪🎉😎
      
      MULTIPLAYER PROFILE HOOK:
      - In live mode, fetches real opponent profiles
      - Player panels show actual names (not 'Bot X')
      - Tap opponent panel → popup with avatar, name, level
      - Add friend button in popup (sends request via mp.addFriendFromGame)
      - Close button, outside-click-to-dismiss
      - Connection dot + emote sync already wired from previous commit
      
      GAME FEEL:
      - Bot turns feel human (total 2-4s per turn vs instant)
      - Piece hop animation plays for bot moves too
      - Capture shake effect on bot captures
      - Bot emote floating animation appears above board
      - Golden glow ring on selectable pieces (multiple valid moves)
      - Tap-to-select piece interaction always required
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      f0ab8811
    • Mahmoud Aglan's avatar
      feat(ludo): piece selection, step-by-step animation, 2-4 player matchmaking, branding admin · 875a302e
      Mahmoud Aglan authored
      PIECE SELECTION:
      - Player always taps which piece to move (golden glow highlight on valid pieces)
      - Canvas click detection: finds nearest highlighted piece within tap radius
      - Even with 1 valid move: brief highlight before auto-execute (confirms to player)
      
      STEP-BY-STEP ANIMATION:
      - Pieces hop one square at a time (120ms per hop) instead of teleporting
      - Audio cue on each step
      - Capture/finish effects play AFTER animation completes
      - Confetti on capture, star burst on finish
      
      MATCHMAKING (2-4 players):
      - Searches for up to 3 waiting opponents
      - 2 humans found → 2 humans + 2 bots
      - 3 humans found → 3 humans + 1 bot
      - 4 humans found → 4 humans, no bots
      - All matched opponents' queue entries updated
      - 30s timeout handled client-side (queue scene already has timer)
      
      BRANDING ADMIN:
      - New 'Ludo Board Colors' section with 9 color controls:
        Red/Blue/Green/Yellow zones, board bg, path, safe star, piece border, grid lines
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      875a302e
    • Mahmoud Aglan's avatar
      fix(ludo): responsive layout for small phones · 96ebe555
      Mahmoud Aglan authored
      - Board max 360px, constrained by container
      - Dice 50x50, roll button smaller padding
      - Panels 6px padding
      - Fits on 360x640 screens
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      96ebe555
    • Mahmoud Aglan's avatar
      fix: challenges now track REAL progress from today's completed matches · d33a8aea
      Mahmoud Aglan authored
      Challenges API now counts actual matches played today:
      - games_played: total completed matches today
      - wins: matches won today
      - chess_played: chess games today
      - ludo_played: ludo games today
      - domino_played: domino games today
      - bot_wins: bot games won today
      
      Progress is calculated server-side by querying matches table
      where player was white/black AND status=completed AND created today.
      Challenge marked completed=true when progress >= target.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      d33a8aea
    • Mahmoud Aglan's avatar
      fix: home buttons, daily reward, back navigation — full sweep · a9cd8b66
      Mahmoud Aglan authored
      1. Removed أحجيات (puzzles) from home quick buttons — chess-only feature
      2. Daily reward completely rewritten:
         - 7-day streak timeline showing claimed/today/future days
         - Each day shows reward amount (50→75→100→125→150→200→300)
         - Already-claimed state: shows  with 'عد غداً' message
         - Prevents double claim (checks last_daily_reward date)
         - Coin burst + fly-to-HUD animation on claim
         - Streak badge '🔥 X يوم متتالي'
         - Info text explaining escalating rewards
         - Has back button ←
      3. Challenges scene: added back button ←
      4. All pushed scenes now have proper back navigation
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      a9cd8b66
    • Mahmoud Aglan's avatar
      fix: bot games now create real match record (appear in match history) · 85d39aa0
      Mahmoud Aglan authored
      Previously bot games used matchId='local' which meant no DB record was
      created. Now on bot game start, calls game.php 'start' to insert a real
      match row. When game completes, the 'complete' action updates that row
      with result/fen/pgn/rating. Matches now appear in مبارياتي.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      85d39aa0
    • Mahmoud Aglan's avatar
      feat: match history — real data from DB with opponent names, result colors, rating changes · cb7dd082
      Mahmoud Aglan authored
      New API: /api/match-history.php
      - Fetches completed matches where player was white OR black
      - Enriches with opponent display names from profiles
      - Returns: result, time_control, bot_id, rating changes, move count, date
      - Supports game_key filter and limit parameter
      
      History scene rewritten:
      - Shows real matches with colored left border (green=win, red=loss, gold=draw)
      - Opponent name (or bot name if vs bot)
      - Rating change (+12 / -8) in matching color
      - Time control label (5+0, 10+0, etc.)
      - Relative time (5د, 2س, 3ي)
      - Proper result detection for all match_result enum values
      - Empty state with helpful message
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      cb7dd082
    • Mahmoud Aglan's avatar
      fix: game menu redesigned as proper game UI — bigger buttons, better layout · cc7da7a7
      Mahmoud Aglan authored
      Game menu popup overhauled:
      - Header: game icon (gradient square) + name + close button
      - Main buttons (.gm-btn): 52px icon, bold title, subtitle, arrow indicator
        - 'لاعب واحد' with gamepad icon on game gradient
        - 'أونلاين' with swords on red/orange gradient
      - Secondary grid (.gm-chip): vertical icon + label, full tap target
        - الترتيب, مبارياتي, أحجيات (chess only)
      - All buttons: dark card style with border, scale-on-press, no web-form feel
      - Removed old .menu-btn / .feature-chip CSS entirely
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      cc7da7a7
    • Mahmoud Aglan's avatar
      feat: wire multiplayer module into Chess and Ludo UI · adb62666
      Mahmoud Aglan authored
      Chess (live mode):
      - Fetches opponent profile, shows real name in opponent bar
      - Emotes sync to opponent via game_state (send + receive)
      - Connection status monitored (green/yellow/red dot)
      - Incoming emotes shown as floating animation
      - mp.cleanup() on game end
      
      Ludo (live mode):
      - Emotes sync to opponent via ludo-match.php
      - Connection status monitored
      - Incoming emotes received and displayed
      - Polling starts if not player's turn at game start
      
      Both games:
      - Fixed emoteWrap variable reference (was using wrong 'wrap')
      - Shared multiplayer.js handles all common features
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      adb62666
    • Mahmoud Aglan's avatar
      feat: shared multiplayer module — opponent bar, synced emotes, disconnect, rematch, friend add · a220f7d0
      Mahmoud Aglan authored
      New core module: multiplayer.js
      Used by Chess, Ludo, Domino for all common multiplayer features:
      
      1. OPPONENT BAR:
         - Avatar, name, rating, level
         - Green/yellow/red connection dot
         - Tap → popup menu (view profile, add friend, report)
      
      2. SYNCED EMOTES:
         - sendEmote(matchId, type, key) → writes to game_state
         - checkForEmote(gameState, myId) → detects opponent's emote
         - onEmoteReceived(callback) → fires for UI to show floating emote
      
      3. CONNECTION STATUS:
         - Green dot = connected (< 15s since last opponent action)
         - Yellow dot = weak (15-60s)
         - Red dot = disconnected (> 60s → can claim win)
         - startDisconnectWatch / stopDisconnectWatch
      
      4. REMATCH:
         - requestRematch(matchId, type) → writes to game_state
         - checkForRematch(gameState, myId) → detects request
      
      5. FRIEND ADD:
         - addFriendFromGame(opponentId) → sends friend request
         - Accessible from opponent bar tap menu
      
      6. REPORT:
         - reportOpponent(opponentId, reason)
      
      All games can import { renderOpponentBar, sendEmote, ... } from 'core/multiplayer.js'
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      a220f7d0
    • Mahmoud Aglan's avatar
      feat: Ludo multiplayer — 2 humans + 2 bots, matchmaking + realtime sync · d6b1ca39
      Mahmoud Aglan authored
      New API: /api/ludo-match.php
      - queue: searches ludo_queue for opponent, creates match with 2 humans + 2 bots
      - status: polls for match_id when opponent joins
      - move: syncs game state (positions, turn, dice)
      - get: fetches current match state
      
      Ludo game scene updated:
      - Stores mode, myPlayerIndex, matchId, isHost
      - isMyTurn() checks player_index vs current_turn
      - handleNonPlayerTurn(): routes to bot (if host) or polling (if waiting)
      - syncLudoState(): sends positions/turn/dice to server after every move
      - startLudoPolling(): polls every 2s for opponent moves, applies state
      - Bot turns run by host only (prevents duplicate bot moves)
      - Player names show 'أنت' for self, 'لاعب X' for other human, 'Bot X' for bots
      
      Queue scene updated:
      - Uses ludo-match.php endpoint for Ludo games
      - Passes playerIndex and players array to game scene
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      d6b1ca39
  3. 03 Jun, 2026 15 commits
    • Mahmoud Aglan's avatar
      fix: Ludo/Domino multiplayer skips time control (chess-only) · ae7f8586
      Mahmoud Aglan authored
      Only chess shows the time control picker (bullet/blitz/rapid).
      Ludo and Domino go straight to matchmaking queue with 'standard' control.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      ae7f8586
    • Mahmoud Aglan's avatar
      fix: matchmaking — add match_type, initial_time_ms, started_at to match creation · 57d5b88d
      Mahmoud Aglan authored
      ROOT CAUSE: matches table has NOT NULL constraint on 'match_type' column.
      Insert was failing silently, falling through to 'queued: true'.
      
      FIX: Added required fields:
      - match_type: 'rated'
      - initial_time_ms: calculated from time_control
      - white/black_time_remaining_ms: set to initial
      - is_rated: true
      - started_at: current timestamp
      
      Removed debug output.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      57d5b88d
    • Mahmoud Aglan's avatar
      debug: show match insert error · 9c2f1f1d
      Mahmoud Aglan authored
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      9c2f1f1d
    • Mahmoud Aglan's avatar
      9d9d328b
    • Mahmoud Aglan's avatar
    • Mahmoud Aglan's avatar
      fix: realtime chess multiplayer — RLS bypass + live polling + opponent move sync · c37f0571
      Mahmoud Aglan authored
      ROOT CAUSE: Supabase RLS on matchmaking_queue only allowed players to
      see their OWN rows. Player A couldn't find Player B in the queue.
      
      FIX: All matchmaking operations now use service_role key (bypasses RLS):
      - handleQueue: searches ALL waiting players, not just own
      - handleStatus: reads match details with service key
      - handleDequeue: cleans up with service key
      - Random color assignment (50/50 white/black)
      
      Chess game live mode:
      - NEW: sendLiveMove() — sends current FEN + move_count to server after player moves
      - NEW: startLivePolling() — polls match row every 2s for opponent's move
      - NEW: When opponent's move_count increases, loads new FEN and updates board
      - NEW: Detects opponent resign/completion via status field
      - If playing as black in live mode, waits for white's first move
      - stopLivePolling() on game end
      
      Flow:
      1. Player A queues → inserted as 'waiting'
      2. Player B queues → finds Player A, creates match, marks A as 'matched'
      3. Player B gets match_id immediately (they're white or black randomly)
      4. Player A polls status → finds 'matched' → gets match_id + color
      5. Both enter chess-game with mode:'live' + matchId
      6. Each player's moves update the match row
      7. Opponent detects new move_count via polling
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      c37f0571
    • Mahmoud Aglan's avatar
      fix(home): remove empty space, add greeting, better quick-action layout · c21445cb
      Mahmoud Aglan authored
      - Content starts from TOP (justify-content: flex-start) — no more void
      - Player greeting: 'أهلاً [name] 👋' with level display
      - Quick action buttons redesigned: icon circles with labels below
        (Challenges , Season 🎖️, Gift 🎁, Puzzles 🧩)
      - Gift button has breathe-glow animation (attention grabber)
      - Puzzles button added for direct access
      - Game tiles: aspect ratio 1.1 (slightly shorter, fits better)
      - Grid gap reduced to 12px for tighter layout
      - Page scrolls if content overflows
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      c21445cb
    • Mahmoud Aglan's avatar
      feat: wire all engagement features into UI · cc5ca0f9
      Mahmoud Aglan authored
      Home screen:
      - 3 widget buttons above game tiles:  التحديات | 🎖️ الموسم | 🎁 هدية
      - Challenges button → daily-challenges scene
      - Daily reward button → daily-reward scene
      
      Social tab:
      - Added '📰 أخبار' (Activity) as 4th tab
      - Activity tab loads friend timeline from activity API
      - Shows actions with Arabic labels and relative timestamps
      
      All features now accessible from UI:
      - Daily Challenges: Home →  button
      - Battle Pass: Home → 🎖️ button (placeholder)
      - Daily Reward: Home → 🎁 button
      - Activity Feed: Social tab → أخبار tab
      - Rank tiers: Profile → rating section (logic ready)
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      cc5ca0f9
    • Mahmoud Aglan's avatar
      feat: activity feed + battle pass system · e9838deb
      Mahmoud Aglan authored
      Activity Feed (api/activity.php + scenes/activity.js):
      - Fetches friend + self activity from activity_feed table
      - Enriches with actor profile (name, avatar)
      - Timeline UI with action labels in Arabic
      - Relative timestamps
      
      Battle Pass (api/battlepass.php):
      - Season config: 30 tiers, 100 XP per tier
      - Current tier from player total XP
      - Free + premium reward tracks
      - Claim tier endpoint
      - Days remaining counter
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      e9838deb
    • Mahmoud Aglan's avatar
      feat: daily challenges + streak + rank tiers system · 5ade83d4
      Mahmoud Aglan authored
      Daily Challenges (api/challenges.php):
      - GET: returns 3 randomized challenges per day (deterministic per user+date)
      - 10 challenge types: play X games, win X, play specific game, solve puzzles,
        beat bot, claim daily, win streak
      - Rewards scale with player level (+10% coins per level)
      - POST claim: grants coins + XP, records transaction
      - Streak tracking with bonus multiplier
      
      Challenges UI (rewards/scenes/challenges.js):
      - Progress bars per challenge
      - Claim button with coin burst + fly-to-HUD animation
      - Streak badge showing consecutive days
      - Staggered card entrance animation
      - Haptic success on claim
      
      Rank Tiers (rewards/scenes/ranks.js):
      - 7 tiers: Bronze → Silver → Gold → Platinum → Diamond → Master → Grandmaster
      - Rating ranges defined for each tier
      - getTier(), getTierProgress(), getNextTier() utilities
      - Arabic + English names, colors, icons
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      5ade83d4
    • Mahmoud Aglan's avatar
      feat: resweep + admin branding expanded to 60 emoji slots · 40ded3ba
      Mahmoud Aglan authored
      Full resweep results:
      - 78 emojis (was 67)
      - 84 colors (was 80)
      - 14 gradients
      - 26 animations (was 24)
      - 57 CSS variables (was 56)
      
      Admin branding panel now has 60 emoji replacement slots:
      - Original 27 (trophy, skull, gift, etc.)
      - NEW: HUD icons (coin dot, gem diamond, level hex)
      - NEW: Game-specific (lightning, best-move star, particle star)
      - NEW: Home screen game tiles (chess pawn, domino, backgammon, ludo)
      - NEW: Social (challenge swords, search, online dot)
      - NEW: All 6 dice faces (⚀⚁⚂⚃⚄⚅) at 56px
      - NEW: Puzzle themes (fork, pin, castle, crown, sacrifice)
      - NEW: Tournament (cup, money bag)
      - NEW: Misc (thinking dots, building/org)
      
      Labels switched to English per user request.
      All slots have exact pixel size hints.
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      40ded3ba
    • Mahmoud Aglan's avatar
      feat(social): full friends system — search, add, pending requests, online filter, remove · bf608999
      Mahmoud Aglan authored
      Friends scene rebuilt:
      - 3 tabs: الأصدقاء (all), الطلبات (pending), متصلين (online)
      - Search players by username (🔍 button → input + results)
      - Send friend request with + button (success feedback)
      - Accept/reject pending requests (✓/✕ buttons)
      - Remove friend (with confirm dialog)
      - Challenge online friend (️ → navigates to game select)
      - View profile button
      - Online dot indicator on avatars
      - Empty states with helpful CTAs
      
      API updated:
      - New action: search — finds players by username (ilike)
      - Returns id, username, display_name, avatar_url, level, is_online
      
      UI polish:
      - Tab system with active state
      - Card-based friend list with actions
      - Animations and haptic on interactions
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      bf608999
    • Mahmoud Aglan's avatar
      feat: realtime multiplayer system for Chess and Ludo · e1001508
      Mahmoud Aglan authored
      New core module: realtime.js
      - WebSocket connection to Supabase Realtime
      - Auto-reconnect on disconnect (3s retry)
      - Heartbeat every 30s
      - Subscribe to any table row by filter
      - subscribeMatch(), subscribeLudoMatch(), subscribeQueue() helpers
      - Unsubscribe cleanup on leave
      
      Chess live (logic/live.js) rewritten:
      - startMatchmaking() — joins queue + subscribes for match found
      - joinMatch() — subscribes to match row, fires onMove/onStateChange
      - sendMove() — updates match with fen, move, move_count
      - sendResign(), sendDrawOffer(), sendEmote()
      - Properly increments move_count for realtime detection
      
      Ludo live (logic/live.js) new:
      - joinMatch() — subscribes to ludo_matches row
      - sendRoll() — updates positions, current_turn, dice_value
      - sendEnd() — marks game complete
      
      API game.php updated:
      - handleGameMove now supports: move_count, game_state, time remaining
      - All fields optional (only updates what's sent)
      - updated_at timestamp on every move (triggers realtime broadcast)
      
      Architecture: Player A updates row → Supabase broadcasts → Player B receives
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      e1001508
    • Mahmoud Aglan's avatar
      feat(ludo): JUICY flat dice — CSS dot rendering, slam, shake, golden glow on 6 · e26cb40f
      Mahmoud Aglan authored
      Dice overhaul:
      - Flat white die with CSS-rendered dots (3x3 grid, proper pip layout)
      - Roll animation: rapid random faces + violent shake + blur (55ms per frame, 14 frames)
      - SLAM landing: scale 1.25 → 1.0 with spring easing
      - Heavy haptic on every roll
      - Dice area shakes on land
      - Rolling 6: golden box-shadow glow + 8 star particles + success haptic
      - Bot rolls: same dot renderer with subtle scale pulse
      - Button fades to 0.5 opacity when disabled (clear visual state)
      - Faster animation interval (55ms vs 70ms) for more frantic feel
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      e26cb40f
    • Mahmoud Aglan's avatar
      fix(ludo): center pawns in home, fix center triangles geometry · 8d556485
      Mahmoud Aglan authored
      - Home bases: positions at grid 1.5/3.5 (exact quadrant centers)
      - Center: 4 triangles now form a proper square (top=red, right=blue,
        bottom=green, left=yellow) with white border — like real Ludo boards
      - Removed weird angle-based triangle calculation
      Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
      8d556485