Skip to main content

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

  1. View Types
  2. Theme Modes
  3. Color Themes
  4. Accessibility Options
  5. UI Customization Options
  6. Hierarchy & Inheritance
  7. Database Schema
  8. API Endpoints
  9. Frontend Architecture
  10. Settings Pages
  11. Implementation Phases
  12. Research & References

1. View Types

Agents can select from four market display modes:

View TypeDescriptionTarget AudienceKey Characteristics
ExchangeTraditional back/lay interfacePro bettors, tradersInformation-dense, market depth visible, decimal/fractional odds
PredictionBinary YES/NO interface (Kalshi/Polymarket style)Casual users, prediction market enthusiastsProbability percentages, single-click betting, clean layout
Simple SportsbookBasic odds display (FanDuel/DraftKings style)Recreational bettorsAmerican odds (+150), minimal UI, quick bet placement
Glass UIiOS 26 Liquid Glass aestheticPremium/modern usersTranslucent 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 OddsProbabilityYES PriceNO Price
2.0050%₹0.50₹0.50
2.5040%₹0.40₹0.60
4.0025%₹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

ModeDescription
SystemFollows device preference (iOS/Android/OS setting)
LightAlways light background
DarkAlways dark background (recommended for Glass UI)

3. Color Themes

3.1 Predefined Color Themes

Theme NamePrimarySecondaryAccentBest For
Ocean Blue#0EA5E9#0284C7#38BDF8Trust, professionalism
Emerald Green#10B981#059669#34D399Wealth, success
Royal Purple#8B5CF6#7C3AED#A78BFAPremium, luxury
Sunset Orange#F97316#EA580C#FB923CEnergy, excitement
Ruby Red#EF4444#DC2626#F87171Bold, action
Golden#F59E0B#D97706#FBBF24Premium, VIP
Slate#64748B#475569#94A3B8Neutral, professional
Midnight#1E293B#0F172A#334155Dark, sophisticated
Neon Cyber#06B6D4#0891B2#22D3EEModern, tech-forward
Forest#22C55E#16A34A#4ADE80Natural, calm

3.2 Custom Brand Colors

Agents can define custom colors when colorTheme = "custom":

SettingDescription
Primary ColorMain brand color (buttons, headers)
Secondary ColorSupporting color (hover states, borders)
Accent ColorHighlights, CTAs, notifications
Success ColorWinning bets, positive actions (default: green)
Danger ColorLosing bets, errors, warnings (default: red)

4. Accessibility Options

FeatureDescriptionDefault
Reduce MotionDisables animations, respects prefers-reduced-motionSystem
Reduce TransparencySolid backgrounds instead of glass/blur effectsOff
High Contrast ModeIncreased contrast ratios for better readabilityOff
Large TextIncreased font sizesOff
Color Blind ModeAlternative color schemes for color blindnessOff

Color Blind Mode Options

  • protanopia - Red-blind
  • deuteranopia - Green-blind
  • tritanopia - Blue-blind

5. UI Customization Options

5.1 Tab Bar Behavior

OptionDescription
DynamicShrinks on scroll, expands on scroll up (Glass UI default)
FixedAlways visible at full size
Hidden on ScrollCompletely hides when scrolling down

5.2 Bet Slip Style

OptionDescription
Slide-up PanelModern slide-up from bottom (mobile-friendly)
Side PanelDesktop-style right sidebar
ModalTraditional popup modal

5.3 Odds Display Format

FormatExampleRegion
Decimal2.50Europe, Australia
Fractional3/2UK, Ireland
American+150USA
Probability40%Prediction markets

5.4 Branding Options

SettingDescription
Logo URLCustom logo for the agent's white-label
Favicon URLCustom 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

MethodEndpointDescription
GET/api/agent/ui-settingsGet agent's UI configuration
PATCH/api/agent/ui-settingsUpdate agent's UI configuration
POST/api/agent/ui-settings/previewPreview settings without saving
POST/api/agent/ui-settings/resetReset to platform defaults

8.2 User Preferences

MethodEndpointDescription
GET/api/user/preferencesGet user's effective settings (resolved)
GET/api/user/preferences/rawGet user's explicit preferences only
PATCH/api/user/preferencesUpdate user's preferences
DELETE/api/user/preferencesReset to agent defaults

8.3 Theme Assets

MethodEndpointDescription
GET/api/themesList all predefined themes
GET/api/themes/:nameGet specific theme details
GET/api/themes/css-variablesGet 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

PhaseFeaturesEffort
Phase 1Database schema, basic API2-3 days
Phase 2View types (Exchange, Prediction, Simple)4-5 days
Phase 3Glass UI View3-4 days
Phase 4Theme modes (light/dark/system)1-2 days
Phase 5Color themes (predefined)2-3 days
Phase 6Custom brand colors1-2 days
Phase 7Accessibility features2-3 days
Phase 8Punter settings page2-3 days
Phase 9Agent admin panel3-4 days
Phase 10Testing & polish3-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)
  • 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-motion system 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