Opportunity Surface Pattern
AI-driven dashboard that shows contextually relevant opportunities instead of static widgets. Same user, different context = different dashboard.
The Problem with Traditional Dashboards
Traditional dashboards show the same widgets to everyone, all the time:
❌ Traditional Dashboard (Static)
Opportunity Surface: Context-Adaptive Dashboard
The Opportunity Surface shows only what's relevant right now. The LLM evaluates:
🕐 Time Context
- • Morning (7 AM): Today's schedule + commute traffic
- • Afternoon (2 PM): Pending tasks + emails
- • Evening (8 PM): Tomorrow's prep
📊 User Situation
- • Budget overspent: Financial guidance cards
- • Traveling tomorrow: Flight check-in, weather, packing
- • Normal day: Calendar + relevant tasks
Interactive Context Demo
Change the time and user situation to see how the Opportunity Surface adapts dynamically.
🕐 Time of Day
👤 User Situation
Your Day at a Glance
Heavy Traffic on Your Route
Real-World Example: Same User, 3 Different Times
Morning (7:00 AM) - Rushing to Work
Afternoon (2:00 PM) - Work Mode
Evening (8:00 PM) - Planning Mode
How It Works
Domains Emit Triggers
Finance domain detects: BUDGET_EXCEEDED
Calendar domain detects: MEETING_IN_30MIN
Travel domain detects: FLIGHT_CHECKIN_OPEN
LLM Scores Relevance
Context: 7:00 AM, user at home, normal day
• MEETING_IN_30MIN → Score: 95 (high urgency + time-sensitive)
• BUDGET_EXCEEDED → Score: 40 (important but not urgent now)
• WEEKLY_REPORT → Score: 10 (not time-sensitive)
Top Opportunities Rendered
Only opportunities with score > 70 are shown as OpportunityCards on the dashboard. User controls dismissal (no auto-hide).
Usage Guidelines
When to use
- •As the main dashboard/home screen in AI-driven applications
- •When user context significantly affects what's relevant (time, location, situation)
- •When you want to surface proactive insights, not just reactive responses
- •When different users (or same user at different times) need different content
Best practices
- •Let LLM decide relevance based on context - don't hardcode "if morning, show X"
- •User controls dismissal (X button, swipe) - NEVER auto-hide based on timers
- •Show 2-5 opportunities max - prioritize quality over quantity
- •Re-evaluate opportunities when context changes (time passes, location changes)
- •Include actionable CTAs in OpportunityCards (not just passive info)
Accessibility
- •Announce new opportunities with aria-live="polite"
- •Dismissal buttons must have clear aria-labels ("Dismiss budget alert")
- •Ensure keyboard navigation between opportunities and actions
- •High-priority opportunities should have higher contrast/visual weight
Do's and Don'ts
✓ Do
- •Let LLM evaluate relevance based on full context
- •Give user full control over dismissal (X button, swipe)
- •Re-evaluate opportunities as context changes
- •Include clear CTAs in opportunity cards
- •Show empty state when no relevant opportunities exist
- •Prioritize time-sensitive opportunities in the morning
✗ Don't
- •Hardcode "if morning, show calendar widget" logic
- •Auto-hide opportunities after timeout (user controls dismissal)
- •Show static widgets that never change
- •Overwhelm with 10+ opportunities at once
- •Ignore context changes (time, location, user state)
- •Mix Opportunity Surface with traditional fixed navigation
Related Components & Patterns
OpportunityCard
The card component used in Opportunity Surface
UI Decision Layer
How LLM decides which UI to render
AI-Driven UI Paradigm
Core principles of context-adaptive UI
Alert
For high-priority opportunities
Badge
Priority and category indicators
Empty States
When no opportunities exist