Skip to main content

Player & Agent Menu Page — Design Spec

Date: 2026-06-16 Status: Approved approach + gradient token confirmed Figma: node 3542-2674 (forsyt.io master file)

Goal

Replace the popover "More" menus (player and agent views) with a dedicated full menu page matching the Figma design: a gradient banner header (avatar + display name) over a flat list of icon+label rows, with the bottom nav showing "More" active. Each view keeps its current menu options. Email is intentionally omitted for now. Must work in dark and light mode via the existing design system.

Routes

ViewRouteFile
Player/menusrc/app/menu/page.tsx
Agent/agent-v2/menusrc/app/agent-v2/menu/page.tsx

Player /menu renders under the root layout (global BottomNav). Agent /agent-v2/menu renders under the agent-v2 layout (its own bottom nav).

Components

src/components/menu/MenuScreen.tsx (new, shared, presentational)

Dumb component — no business logic, no data fetching.

Props:

interface MenuItem {
icon: React.ComponentType<{ className?: string }>;
label: string;
href?: string; // navigation target
onClick?: () => void; // action (e.g. logout) — mutually exclusive with href
external?: boolean; // shows the ↗ "leaves this section" arrow (e.g. Agent Panel)
danger?: boolean; // red label (logout) — uses text-loss
}

interface MenuScreenProps {
displayName: string;
avatarUrl?: string | null; // falls back to initial when absent
role?: string; // optional small badge under name (no email)
items: MenuItem[];
}

Renders:

  1. Gradient banner header — full-width, ~180px. Centered circular avatar (dashed ring), then displayName (white, centered). No email row.
  2. List — each MenuItem is a full-width row: left icon (currentColor/text-fg), label (text-fg), optional right ↗ for external, text-loss when danger. h-px bg-fg/[0.06] divider between rows. href rows use the router; onClick rows fire the handler.

src/app/menu/page.tsx (player)

Reads useAuthStore, builds the player item list, renders <MenuScreen>:

  • Home (/)
  • Settings (/settings)
  • PnL Report (/reports/pnl) — flattened from the old expandable Reports section
  • Bet History (/reports/bet-history) — flattened
  • Agent Panel (/agent) — external, only if user has agent access
  • Admin Panel (/admin) — external, only if user has admin access
  • Install App — only when installable (keeps current PWA-install behavior)
  • Logout / Exit Demo — danger, onClick

src/app/agent-v2/menu/page.tsx (agent)

Reads useAuthStore, builds the agent item list, renders <MenuScreen>:

  • Player View (/sports) — external
  • Ledger (/agent-v2/ledger)
  • Admin Panel (/admin) — external, only if platform_admin / adminUser
  • Logout — danger, onClick

Bottom-nav changes

  • Player BottomNav.tsx: "More" navigates to /menu (was: toggle popover). "More" shows active when pathname === '/menu'. The popover JSX/state becomes dead code.
  • Agent agent-v2/layout.tsx: "More" navigates to /agent-v2/menu (was: toggle popover). Active on that route. Popover JSX/state becomes dead code.
  • The menu page suppresses the existing top header (player global Header; agent-v2 layout header) so the gradient banner sits at the very top.

Design tokens

One new token — the banner gradient. Everything else reuses existing tokens (bg-bg, text-fg, dividers bg-fg/[0.06], text-loss, icon currentColor).

Confirmed: --menu-header-gradient: linear-gradient(135deg, #e171d3 0%, #d9614f 45%, #5f8fc4 100%) (magenta → coral → blue, sampled from Figma). Defined identically in both :root,.dark and .light — the banner is decorative with white text and reads fine on the vibrant gradient in either theme.

Dark / light mode

  • List, dividers, icons, labels all flip via existing tokens (same pattern as the recent contrast fixes — currentColor icons, text-fg, faint dividers).
  • Banner gradient + white header text are constant (readable on the vibrant gradient in both modes).

Dead code (list, do not delete without confirmation)

  • Player popover block + isMoreMenuOpen state in BottomNav.tsx.
  • Agent popover block + moreOpen state in agent-v2/layout.tsx.

These will be itemized after wiring; removal confirmed with the user (Dead Code Hygiene).

Out of scope

  • Email display.
  • Bet-slip green-tint / keypad contrast (separate task).
  • Any backend/API change — frontend only.

Cross-system impact

  • frontend: new shared component, 2 routes, 2 bottom-nav edits, 1 new token.
  • backend / services / infra: none.

Testing / verification

  • Render /menu and /agent-v2/menu in both dark and light mode; verify every current menu option is present and routes correctly, conditionals (Agent/Admin/Install) behave, logout works, "More" shows active, and the banner + rows are legible in both themes.