Agent-Customizable UI System
Design Document v1.0
Author: Hannibal Development Team
Date: January 2026
Status: Design Phase
Executive Summary
This feature enables agents (white-label operators) to set a default viewing experience for their punters, while allowing punters to override the setting. The goal is to differentiate agent brands and cater to different user preferences (traditional bettors vs prediction market enthusiasts).
Key Benefits
- Agent Differentiation - Each agent can have a unique default experience
- User Choice - Punters can override agent defaults in settings
- Modern UX - Prediction market view appeals to Kalshi/Polymarket users
- Accessibility - WCAG compliant with reduced motion support
- Mobile-First - Optimized for 70%+ mobile traffic
- Balanced Gamification - Subtle feedback, no controversial confetti
Table of Contents
- View Types
- Theme Modes
- Color Themes
- Accessibility Options
- UI Customization Options
- Hierarchy & Inheritance
- Database Schema
- API Endpoints
- Frontend Architecture
- Settings Pages
- Implementation Phases
- Research & References
1. View Types
Agents can select from four market display modes:
| View Type | Description | Target Audience | Key Characteristics |
|---|---|---|---|
| Exchange | Traditional back/lay interface | Pro bettors, traders | Information-dense, market depth visible, decimal/fractional odds |
| Prediction | Binary YES/NO interface (Kalshi/Polymarket style) | Casual users, prediction market enthusiasts | Probability percentages, single-click betting, clean layout |
| Simple Sportsbook | Basic odds display (FanDuel/DraftKings style) | Recreational bettors | American odds (+150), minimal UI, quick bet placement |
| Glass UI | iOS 26 Liquid Glass aesthetic | Premium/modern users | Translucent panels, blur effects, specular highlights, morphing controls |
1.1 Exchange View (Default)
Traditional back/lay interface for sophisticated bettors.
┌─────────────────────────────────────────────────────────┐
│ Manchester United vs Liverpool │
│ Premier League • Today 15:00 │
├─────────────────────────────────────────────────────────┤
│ Selection │ BACK │ LAY │
│─────────────────────────────────────────────────────────│
│ Man United │ 2.50 (£1.2k) │ 2.52 (£800) │
│ Draw │ 3.40 (£500) │ 3.45 (£300) │
│ Liverpool │ 2.80 (£900) │ 2.85 (£600) │
└─────────────────────────────────────────────────────────┘
1.2 Prediction View (Kalshi/Polymarket Style)
Binary YES/NO for casual users and prediction market enthusiasts.
┌─────────────────────────────────────────────────────────┐
│ Will Manchester United win? │
│ Premier League • Today 15:00 │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ YES │ │ NO │ │
│ │ 40% │ │ 60% │ │
│ │ ₹0.40 │ │ ₹0.60 │ │
│ └──────────────┘ └──────────────┘ │
│ │
│ [Buy YES] [Buy NO] │
└─────────────────────────────────────────────────────────┘
1.3 Simple Sportsbook View (FanDuel Style)
Simplified odds display for recreational bettors.
┌─────────────────────────────────────────────────────────┐
│ Manchester United vs Liverpool │
│ Premier League • Today 15:00 │
├─────────────────────────────────────────────────────────┤
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Man United │ │ Draw │ │ Liverpool │ │
│ │ +150 │ │ +240 │ │ +180 │ │
│ └────────────┘ └────────────┘ └────────────┘ │
└─────────────────────────────────────────────────────────┘
1.4 Glass UI View (iOS 26 Liquid Glass)
Premium view inspired by Apple's Liquid Glass design language (WWDC 2025).
Key Characteristics:
- Translucent panels with backdrop blur
- Multi-layer depth rendering (parallax-like 3D)
- Specular highlights that react to movement
- Dynamic adaptation between light/dark environments
- Controls that morph and "give way" to content
/* Glass UI CSS Implementation */
.glass-panel {
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(20px) saturate(180%);
-webkit-backdrop-filter: blur(20px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 16px;
box-shadow:
0 8px 32px rgba(0, 0, 0, 0.1),
inset 0 1px 0 rgba(255, 255, 255, 0.3);
}
1.5 Odds Conversion Logic
For Prediction View, back/lay odds are converted to probabilities:
| Back Odds | Probability | YES Price | NO Price |
|---|---|---|---|
| 2.00 | 50% | ₹0.50 | ₹0.50 |
| 2.50 | 40% | ₹0.40 | ₹0.60 |
| 4.00 | 25% | ₹0.25 | ₹0.75 |
Formula:
const probability = 1 / backOdds;
const yesPrice = probability; // e.g., 0.40
const noPrice = 1 - probability; // e.g., 0.60
2. Theme Modes
| Mode | Description |
|---|---|
| System | Follows device preference (iOS/Android/OS setting) |
| Light | Always light background |
| Dark | Always dark background (recommended for Glass UI) |
3. Color Themes
3.1 Predefined Color Themes
| Theme Name | Primary | Secondary | Accent | Best For |
|---|---|---|---|---|
| Ocean Blue | #0EA5E9 | #0284C7 | #38BDF8 | Trust, professionalism |
| Emerald Green | #10B981 | #059669 | #34D399 | Wealth, success |
| Royal Purple | #8B5CF6 | #7C3AED | #A78BFA | Premium, luxury |
| Sunset Orange | #F97316 | #EA580C | #FB923C | Energy, excitement |
| Ruby Red | #EF4444 | #DC2626 | #F87171 | Bold, action |
| Golden | #F59E0B | #D97706 | #FBBF24 | Premium, VIP |
| Slate | #64748B | #475569 | #94A3B8 | Neutral, professional |
| Midnight | #1E293B | #0F172A | #334155 | Dark, sophisticated |
| Neon Cyber | #06B6D4 | #0891B2 | #22D3EE | Modern, tech-forward |
| Forest | #22C55E | #16A34A | #4ADE80 | Natural, calm |
3.2 Custom Brand Colors
Agents can define custom colors when colorTheme = "custom":
| Setting | Description |
|---|---|
| Primary Color | Main brand color (buttons, headers) |
| Secondary Color | Supporting color (hover states, borders) |
| Accent Color | Highlights, CTAs, notifications |
| Success Color | Winning bets, positive actions (default: green) |
| Danger Color | Losing bets, errors, warnings (default: red) |
4. Accessibility Options
| Feature | Description | Default |
|---|---|---|
| Reduce Motion | Disables animations, respects prefers-reduced-motion | System |
| Reduce Transparency | Solid backgrounds instead of glass/blur effects | Off |
| High Contrast Mode | Increased contrast ratios for better readability | Off |
| Large Text | Increased font sizes | Off |
| Color Blind Mode | Alternative color schemes for color blindness | Off |
Color Blind Mode Options
protanopia- Red-blinddeuteranopia- Green-blindtritanopia- Blue-blind
5. UI Customization Options
5.1 Tab Bar Behavior
| Option | Description |
|---|---|
| Dynamic | Shrinks on scroll, expands on scroll up (Glass UI default) |
| Fixed | Always visible at full size |
| Hidden on Scroll | Completely hides when scrolling down |
5.2 Bet Slip Style
| Option | Description |
|---|---|
| Slide-up Panel | Modern slide-up from bottom (mobile-friendly) |
| Side Panel | Desktop-style right sidebar |
| Modal | Traditional popup modal |
5.3 Odds Display Format
| Format | Example | Region |
|---|---|---|
| Decimal | 2.50 | Europe, Australia |
| Fractional | 3/2 | UK, Ireland |
| American | +150 | USA |
| Probability | 40% | Prediction markets |
5.4 Branding Options
| Setting | Description |
|---|---|
| Logo URL | Custom logo for the agent's white-label |
| Favicon URL | Custom favicon |
6. Hierarchy & Inheritance
Settings follow a cascading inheritance model:
Platform Defaults
↓
Agent Settings (overrides platform)
↓
Punter Preferences (overrides agent)
Resolution Logic
function getEffectiveSettings(user: User, agent: Agent): UISettings {
return {
viewType: user.preferredView ?? agent.defaultPunterView ?? 'exchange',
themeMode: user.preferredTheme ?? agent.defaultTheme ?? 'system',
colorTheme: user.preferredColorTheme ?? agent.colorTheme ?? 'ocean-blue',
reduceMotion: user.reduceMotion ?? agent.defaultReduceMotion ?? 'system',
reduceTransparency: user.reduceTransparency ?? agent.defaultReduceTransparency ?? false,
oddsFormat: user.preferredOddsFormat ?? agent.defaultOddsFormat ?? 'decimal',
tabBarBehavior: agent.tabBarBehavior ?? 'dynamic',
betSlipStyle: agent.betSlipStyle ?? 'slide-up',
};
}
7. Database Schema
7.1 Agent Model Additions
model Agent {
// ... existing fields
// View Settings
defaultPunterView String @default("exchange") @map("default_punter_view")
// Values: "exchange" | "prediction" | "simple" | "glass"
// Theme Settings
defaultTheme String @default("system") @map("default_theme")
// Values: "light" | "dark" | "system"
// Color Theme
colorTheme String @default("ocean-blue") @map("color_theme")
// Values: predefined theme names or "custom"
// Custom Brand Colors (when colorTheme = "custom")
primaryColor String? @map("primary_color")
secondaryColor String? @map("secondary_color")
accentColor String? @map("accent_color")
// Accessibility Defaults
defaultReduceMotion String @default("system") @map("default_reduce_motion")
defaultReduceTransparency Boolean @default(false) @map("default_reduce_transparency")
// Display Preferences
defaultOddsFormat String @default("decimal") @map("default_odds_format")
// UI Behavior
tabBarBehavior String @default("dynamic") @map("tab_bar_behavior")
betSlipStyle String @default("slide-up") @map("bet_slip_style")
// Branding
logoUrl String? @map("logo_url")
faviconUrl String? @map("favicon_url")
}
7.2 User Model Additions
model User {
// ... existing fields
// View Preferences (null = inherit from agent)
preferredView String? @map("preferred_view")
preferredTheme String? @map("preferred_theme")
preferredColorTheme String? @map("preferred_color_theme")
preferredOddsFormat String? @map("preferred_odds_format")
// Accessibility Preferences
reduceMotion String? @map("reduce_motion")
reduceTransparency Boolean? @map("reduce_transparency")
highContrastMode Boolean? @map("high_contrast_mode")
largeText Boolean? @map("large_text")
colorBlindMode String? @map("color_blind_mode")
}
8. API Endpoints
8.1 Agent Settings
| Method | Endpoint | Description |
|---|---|---|
GET | /api/agent/ui-settings | Get agent's UI configuration |
PATCH | /api/agent/ui-settings | Update agent's UI configuration |
POST | /api/agent/ui-settings/preview | Preview settings without saving |
POST | /api/agent/ui-settings/reset | Reset to platform defaults |
8.2 User Preferences
| Method | Endpoint | Description |
|---|---|---|
GET | /api/user/preferences | Get user's effective settings (resolved) |
GET | /api/user/preferences/raw | Get user's explicit preferences only |
PATCH | /api/user/preferences | Update user's preferences |
DELETE | /api/user/preferences | Reset to agent defaults |
8.3 Theme Assets
| Method | Endpoint | Description |
|---|---|---|
GET | /api/themes | List all predefined themes |
GET | /api/themes/:name | Get specific theme details |
GET | /api/themes/css-variables | Get CSS variables for current theme |
9. Frontend Architecture
9.1 Component Hierarchy
<ThemeProvider> // Provides theme context
<UISettingsProvider> // Provides UI settings context
<AccessibilityProvider> // Handles a11y preferences
<App>
<MarketView> // Switches between view types
├── <ExchangeView />
├── <PredictionView />
├── <SimpleSportsbookView />
└── <GlassView />
</MarketView>
<BetSlip variant={settings.betSlipStyle} />
<TabBar behavior={settings.tabBarBehavior} />
</App>
</AccessibilityProvider>
</UISettingsProvider>
</ThemeProvider>
9.2 CSS Variables System
:root {
/* Color Theme Variables */
--color-primary: var(--theme-primary, #0EA5E9);
--color-secondary: var(--theme-secondary, #0284C7);
--color-accent: var(--theme-accent, #38BDF8);
--color-success: var(--theme-success, #10B981);
--color-danger: var(--theme-danger, #EF4444);
/* Glass UI Variables */
--glass-blur: 20px;
--glass-saturation: 180%;
--glass-opacity: 0.15;
--glass-border-opacity: 0.2;
/* Spacing & Sizing */
--border-radius: 12px;
--border-radius-lg: 16px;
/* Transitions */
--transition-fast: 150ms ease;
--transition-normal: 300ms ease;
}
/* Accessibility Overrides */
[data-reduce-motion="true"] {
--transition-fast: 0ms;
--transition-normal: 0ms;
}
[data-reduce-transparency="true"] {
--glass-blur: 0px;
--glass-opacity: 0.95;
}
[data-high-contrast="true"] {
--color-primary: #0066CC;
--glass-opacity: 0.98;
}
9.3 View Switching Hook
// hooks/useViewType.ts
export function useViewType() {
const { settings } = useUISettings();
const ViewComponent = useMemo(() => {
switch (settings.viewType) {
case 'prediction':
return PredictionView;
case 'simple':
return SimpleSportsbookView;
case 'glass':
return GlassView;
case 'exchange':
default:
return ExchangeView;
}
}, [settings.viewType]);
return { ViewComponent, viewType: settings.viewType };
}
10. Settings Pages
10.1 Punter Settings Page
┌─────────────────────────────────────────────────────────┐
│ ⚙️ Display Settings │
├─────────────────────────────────────────────────────────┤
│ │
│ MARKET VIEW │
│ ┌─────────────────────────────────────────────────┐ │
│ │ ○ Use default (Exchange) │ │
│ │ ○ Exchange View (Back/Lay) │ │
│ │ ○ Prediction View (Yes/No) │ │
│ │ ○ Simple Sportsbook │ │
│ │ ○ Glass UI ✨ │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ APPEARANCE │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Theme: ○ System ○ Light ● Dark │ │
│ │ Color: [Ocean Blue ▼] │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ ODDS FORMAT │
│ ┌─────────────────────────────────────────────────┐ │
│ │ ○ Decimal (2.50) │ │
│ │ ○ Fractional (3/2) │ │
│ │ ○ American (+150) │ │
│ │ ○ Probability (40%) │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ ACCESSIBILITY │
│ ┌─────────────────────────────────────────────────┐ │
│ │ ☐ Reduce motion │ │
│ │ ☐ Reduce transparency │ │
│ │ ☐ High contrast mode │ │
│ │ ☐ Large text │ │
│ │ Color blind mode: [None ▼] │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ [Reset to Defaults] [Save Preferences] │
└─────────────────────────────────────────────────────────┘
10.2 Agent Admin Panel
┌─────────────────────────────────────────────────────────┐
│ 🎨 Punter Experience Configuration │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────┐ ┌─────────────────────────┐ │
│ │ 📱 PREVIEW │ │ DEFAULT VIEW │ │
│ │ ┌───────────────┐ │ │ ● Exchange │ │
│ │ │ [Live │ │ │ ○ Prediction │ │
│ │ │ Preview] │ │ │ ○ Simple │ │
│ │ └───────────────┘ │ │ ○ Glass UI │ │
│ └─────────────────────┘ └─────────────────────────┘ │
│ │
│ COLOR THEME │
│ ┌─────────────────────────────────────────────────┐ │
│ │ [🔵] [🟢] [🟣] [🟠] [🔴] [🟡] [⚫] [🔷] [Custom] │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ BRANDING │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Logo: [Upload] or [URL: ________________] │ │
│ │ Favicon: [Upload] or [URL: ________________] │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ [Preview Changes] [Reset] [Save Settings] │
└─────────────────────────────────────────────────────────┘
11. Implementation Phases
| Phase | Features | Effort |
|---|---|---|
| Phase 1 | Database schema, basic API | 2-3 days |
| Phase 2 | View types (Exchange, Prediction, Simple) | 4-5 days |
| Phase 3 | Glass UI View | 3-4 days |
| Phase 4 | Theme modes (light/dark/system) | 1-2 days |
| Phase 5 | Color themes (predefined) | 2-3 days |
| Phase 6 | Custom brand colors | 1-2 days |
| Phase 7 | Accessibility features | 2-3 days |
| Phase 8 | Punter settings page | 2-3 days |
| Phase 9 | Agent admin panel | 3-4 days |
| Phase 10 | Testing & polish | 3-4 days |
Total Estimate: ~4-5 weeks
Phase Details
Phase 1: Foundation (2-3 days)
- Add new fields to Agent and User Prisma models
- Create and run database migrations
- Implement basic API endpoints for settings CRUD
Phase 2: Core View Types (4-5 days)
- Implement ExchangeView component (existing, refactor)
- Implement PredictionView with YES/NO binary interface
- Implement SimpleSportsbookView with American odds
- Create view switching mechanism and context
Phase 3: Glass UI (3-4 days)
- Implement GlassView with Liquid Glass aesthetics
- Add backdrop blur, translucency, specular highlights
- Implement dynamic morphing controls
- Test on iOS Safari for compatibility
Phase 4-6: Theming (4-7 days)
- Implement CSS variables system
- Add light/dark/system mode toggle
- Implement predefined color themes
- Add custom brand color picker for agents
Phase 7: Accessibility (2-3 days)
- Implement reduce motion preference
- Add reduce transparency option
- Implement high contrast mode
- Add large text support
- Implement color blind modes
Phase 8-9: Settings UI (5-7 days)
- Build punter settings page with live preview
- Build agent admin panel with live preview
- Implement preview before save functionality
Phase 10: Polish (3-4 days)
- End-to-end testing
- Performance optimization
- Cross-browser testing
- Documentation
12. Research & References
12.1 Apple Liquid Glass Design
- Source: WWDC 2025 (June 2025)
- Documentation: Apple Human Interface Guidelines for iOS 26
- Key Features: Translucent materials, multi-layer depth, specular highlights, dynamic adaptation
12.2 Prediction Markets UI Research
- Kalshi: Binary YES/NO tokens, probability-based pricing, clean single-click interface
- Polymarket: Event-based markets, probability display, minimal UI design
- Key Insight: Prices sum to $1.00, representing probability (e.g., YES $0.65 = 65% probability)
12.3 Sports Betting UI Trends (2025-2026)
- FanDuel/DraftKings: Simple odds display, quick bet placement, gamification elements
- Betfair Exchange: Information-dense, market depth, professional trader focus
- Key Insight: Mobile-first design, 70%+ of bets placed on mobile devices
12.4 Gamification Lessons
- Robinhood Case Study: Removed confetti animations in 2021 after criticism for encouraging risky trading
- Key Insight: Balanced gamification - subtle haptic feedback and sounds preferred over flashy animations
12.5 Accessibility Guidelines
- WCAG 2.1 AA Compliance: Target standard for accessibility
- Color Contrast: 4.5:1 minimum for normal text, 3:1 for large text
- Motion: Respect
prefers-reduced-motionsystem setting
12.6 Technical References
- CSS backdrop-filter: Browser support at 95%+ globally
- CSS Custom Properties: Used for real-time theme switching without re-render
- ResizeObserver API: For dynamic tab bar behavior
Complete Feature Checklist
View Types (4)
- Exchange View (back/lay)
- Prediction View (yes/no)
- Simple Sportsbook View
- Glass UI View (Liquid Glass)
Theme Modes (3)
- System (auto)
- Light Mode
- Dark Mode
Color Themes (10+ predefined + custom)
- Ocean Blue
- Emerald Green
- Royal Purple
- Sunset Orange
- Ruby Red
- Golden
- Slate
- Midnight
- Neon Cyber
- Forest
- Custom (agent-defined colors)
Accessibility Features (5)
- Reduce Motion
- Reduce Transparency
- High Contrast Mode
- Large Text
- Color Blind Modes
UI Behaviors
- Tab Bar: Dynamic / Fixed / Hidden
- Bet Slip: Slide-up / Side Panel / Modal
- Odds Format: Decimal / Fractional / American / Probability
Settings Pages
- Punter settings page
- Agent admin panel
- Live preview functionality
Document Version: 1.0 Last Updated: January 2026