| name | frontend-design |
| description | Create distinctive, production-grade frontend interfaces for the Clue Symptom Tracker. Use Podia-inspired warm, approachable aesthetics with energy-conscious design for chronic illness users. Generates pixel-perfect React Native code using NativeWind. |
| license | Complete terms in LICENSE.txt |
This skill guides creation of distinctive, production-grade frontend interfaces for Clue. The design language is Podia-inspired: warm, approachable, and energy-conscious for users with chronic illness and brain fog.
Architecture note (agent-driven UI)
- Why this matters: In
web-landing-next, some “conversion UI” components (e.g. ValuePropScreen) are tightly coupled to onboarding agent output types and are rendered from the “summary” step after Q3.
- Rule of thumb: If a React component is user-facing UI, prefer placing it under a UI-oriented folder (
src/components/...) or a clearly named neutral folder like src/agent-ui/... rather than src/backend/... to avoid misleading boundaries.
Design System Reference
Color Palette
primary: "#20132E"
"primary-light": "#f3f0fa"
"background-light": "#FDFBF9"
"card-light": "#FFFFFF"
"surface-light": "#FFFFFF"
"accent-peach": "#E8974F"
"accent-blue": "#A4C8D8"
"accent-purple": "#D0BDF4"
"accent-mint": "#B8E3D6"
"pill-hover": "#F3EFFF"
"pill-selected": "#E0D4FC"
"text-main": "#20132E"
"text-muted": "#554b66"
Typography
| Role | Font | Weights | Usage |
|---|
| Display | Fraunces (serif) | 300, 600 | Headings, onboarding titles |
| Body | Inter / DM Sans | 400, 500, 600, 700 | UI text, buttons, body copy |
Headlines: Large (34-40px), semibold Fraunces, tight leading
Body: 16-18px Inter/DM Sans, relaxed leading
Labels: 12-14px Inter, uppercase tracking for section labels
Spacing & Radius
DEFAULT: "12px"
xl: "16px"
"2xl": "24px"
"3xl": "32px"
pill: "9999px"
soft: "0 4px 20px -2px rgba(0, 0, 0, 0.05)"
card: "0 2px 12px -2px rgba(32, 20, 69, 0.05)"
Visual Elements
Decorative Blobs (positioned absolutely, pointer-events-none):
<View className="absolute -top-10 -right-10 w-40 h-40 bg-accent-peach/80 rounded-[3rem] rotate-12 blur-sm" />
<View className="absolute top-1/4 -left-12 w-32 h-32 bg-accent-blue/60 rounded-full blur-xl" />
<View className="absolute bottom-20 -right-6 w-48 h-48 bg-accent-purple/50 rounded-[4rem] -rotate-12" />
Bottom Gradient Overlay (for sticky CTAs):
<View className="bg-gradient-to-t from-background-light via-background-light to-transparent pt-12" />
Component Patterns
Pill Chips (Selection)
<Pressable className="px-5 py-3 bg-white border border-gray-200 rounded-full shadow-sm">
<Text className="text-gray-700 font-medium">Option</Text>
</Pressable>
<Pressable className="px-5 py-3 bg-pill-selected border border-primary rounded-full">
<Text className="text-primary font-semibold">Option</Text>
<Icon name="check" size={16} />
</Pressable>
Cards with Icons
<Pressable className="flex-row items-center p-4 bg-white border-2 border-transparent rounded-2xl shadow-soft">
{}
<View className="w-12 h-12 rounded-xl bg-yellow-100 items-center justify-center mr-4">
<Icon name="bolt" color="#CA8A04" size={24} />
</View>
<View className="flex-1">
<Text className="font-semibold text-lg text-primary">Title</Text>
<Text className="text-sm text-gray-500">Subtitle description</Text>
</View>
{}
<View className="w-6 h-6 rounded-full border-2 border-gray-300" />
</Pressable>
Chat Bubbles
<View className="p-6 rounded-[2rem] rounded-bl-none bg-white border border-black/5 shadow-card">
<Text className="text-[17px] leading-relaxed font-medium text-primary">
Message content
</Text>
</View>
<View className="p-6 rounded-[2rem] rounded-br-none bg-primary">
<Text className="text-[17px] leading-relaxed font-medium text-white/95">
Message content
</Text>
</View>
Focus Card (Hypothesis Tracking)
<View className="rounded-[2.5rem] border border-primary/5 bg-white p-7 shadow-soft">
{}
<View className="flex-row items-center px-4 py-1.5 rounded-full bg-accent-mint/40">
<Icon name="push-pin" size={18} className="text-teal-800" />
<Text className="text-xs font-bold uppercase tracking-wider text-teal-900">
Focus
</Text>
</View>
{}
<Text className="text-xl font-bold text-primary">
How does{' '}
<Text className="bg-accent-purple/30 px-2 rounded-lg">Poor Sleep</Text>{' '}
impact{' '}
<Text className="bg-accent-peach/40 px-2 rounded-lg text-orange-900">
Joint Pain
</Text>
?
</Text>
{}
<View className="h-3 w-full rounded-full bg-primary-light overflow-hidden">
<View className="h-full w-[65%] rounded-full bg-accent-purple" />
</View>
</View>
Primary Button (Sticky CTA)
<Pressable className="w-full py-4 bg-primary rounded-full shadow-lg flex-row items-center justify-center">
<Text className="text-white text-lg font-bold">Continue</Text>
<Icon name="arrow-forward" color="white" className="ml-2" />
</Pressable>
Energy-Conscious UX Principles
- Large touch targets: Minimum 48px, preferably 56px for primary actions
- One-tap actions: Prefer toggles and chips over text input
- Progressive disclosure: Show minimal UI upfront, expand on demand
- Gentle transitions: Soft animations, no jarring movements
- Clear hierarchy: One primary CTA per screen, secondary actions subtle
- Forgiving interactions: Easy to undo, skip, or "do later"
Screen Structure
<SafeAreaView className="flex-1 bg-background-light">
{}
<DecorativeBlobs />
{}
<View className="flex-1 px-6 pt-12">
{}
<ProgressBar step={1} total={3} />
{}
<Text className="font-display text-4xl font-semibold text-primary mb-3">
Screen Title
</Text>
{}
<Text className="text-gray-600 text-lg leading-relaxed mb-8">
Helpful description
</Text>
{}
<ScrollView className="flex-1" showsVerticalScrollIndicator={false}>
{}
</ScrollView>
</View>
{}
<View className="p-6 bg-gradient-to-t from-background-light via-background-light to-transparent">
<PrimaryButton title="Continue" />
</View>
</SafeAreaView>
UI Source References
Hero Pattern: Visible-Style Persona Layout (Landing Pages)
Inspiration: makevisible.com — Clean, trustworthy, human-centered design.
Use for: Marketing landing pages, not in-app screens.
Desktop Layout (min-width: 768px)
┌─────────────────────────────────────────────────────────────────────┐
│ SOLID BACKGROUND COLOR (accent-blue: #A4C8D8) │
│ ┌──────────────────────────┐ ┌─────────────────────────────────┐│
│ │ LEFT 45-50% │ │ RIGHT 50-55% ││
│ │ ───────────── │ │ ───────────── ││
│ │ H1: Fraunces, white │ │ ││
│ │ "Your flares have │ │ [PERSONA IMAGE] ││
│ │ a forecast." │ │ PNG cutout on solid bg ││
│ │ │ │ Position: right edge, ││
│ │ H2: DM Sans, white/80% │ │ bleeds off container ││
│ │ "Get a 48-hour..." │ │ ││
│ │ │ │ object-position: top right ││
│ │ [Condition Pills] │ │ max-height: 90vh ││
│ │ white borders, semi- │ │ ││
│ │ transparent bg │ │ ││
│ │ │ │ ││
│ │ [CTA Button →] │ │ ││
│ │ White bg, dark text │ │ ││
│ └──────────────────────────┘ └─────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────────┘
Mobile Layout (max-width: 767px)
Option A: Card Style (Visible's iPhone screenshot)
┌─────────────────────────────────┐
│ CARD with rounded corners │
│ (inside a cream background) │
│ ───────────────────────── │
│ H1 (centered) │
│ H2 (centered) │
│ │
│ [Condition Pills] │
│ (wrapped, centered) │
│ │
│ [CTA Button →] │
│ │
│ [PERSONA IMAGE] │
│ (below text, centered, │
│ smaller, full visible) │
└─────────────────────────────────┘
Option B: Full-Width Background (alternate variant)
┌─────────────────────────────────┐
│ FULL BLEED BACKGROUND │
│ Persona as subtle bg image │
│ (opacity 20%, positioned │
│ bottom-right, fixed) │
│ ───────────────────────── │
│ H1 (centered) │
│ H2 (centered) │
│ [Pills] [CTA] │
└─────────────────────────────────┘
CSS Implementation
.hero-visible {
background-color: #a4c8d8;
min-height: 100vh;
position: relative;
overflow: hidden;
}
@media (min-width: 768px) {
.hero-persona {
position: absolute;
right: 0;
bottom: 0;
height: 90vh;
max-height: 800px;
width: auto;
object-fit: contain;
object-position: bottom right;
transform: translateX(5%);
}
}
@media (max-width: 767px) {
.hero-visible {
background-color: #fdfbf9;
padding: 1rem;
}
.hero-card {
background-color: #a4c8d8;
border-radius: 2rem;
padding: 2rem 1.5rem;
overflow: hidden;
}
.hero-persona {
position: relative;
width: 80%;
max-width: 300px;
margin: 2rem auto 0;
display: block;
}
}
.condition-pill {
padding: 0.625rem 1.25rem;
border-radius: 9999px;
border: 1px solid rgba(255, 255, 255, 0.6);
background: rgba(255, 255, 255, 0.15);
color: white;
font-weight: 500;
font-size: 0.875rem;
backdrop-filter: blur(4px);
}
.hero-cta {
background: white;
color: #20132e;
padding: 1rem 2rem;
border-radius: 9999px;
font-weight: 700;
font-size: 1.125rem;
box-shadow: 0 4px 20px -2px rgba(0, 0, 0, 0.15);
transition:
transform 0.2s,
box-shadow 0.2s;
}
.hero-cta:hover {
transform: translateY(-2px);
box-shadow: 0 8px 30px -4px rgba(0, 0, 0, 0.2);
}
Key Visual Properties
| Element | Desktop | Mobile (Card) |
|---|
| Background | Solid #A4C8D8 full-bleed | Cream outer, card has color |
| Container | max-w-7xl mx-auto | rounded-[2rem] card |
| Text align | Left | Center |
| Image size | 90vh height, auto width | 80% width, centered |
| Image position | Absolute, right edge bleed | Relative, below text |
| CTA | Inline with text | Full width or centered |
A/B Testing Support
<h1 data-variant="default">Your flares have a forecast.</h1>
<h1 data-variant="alt-1" class="hidden">See flares coming 48 hours early.</h1>
<h1 data-variant="alt-2" class="hidden">Stop being blindsided by flares.</h1>
<script>
const variant =
new URLSearchParams(location.search).get('headline') || 'default';
document.querySelectorAll('h1[data-variant]').forEach((el) => {
el.classList.toggle('hidden', el.dataset.variant !== variant);
});
</script>
UTM-Based Condition Pills
const utmContent = new URLSearchParams(location.search).get('utm_content');
const conditionMap = {
fibromyalgia: ['Fibromyalgia', 'Chronic Pain', 'ME/CFS'],
long_covid: ['Long COVID', 'Post-Viral', 'ME/CFS'],
endo: ['Endometriosis', 'PCOS', 'Chronic Pain'],
default: ['Long COVID', 'ME/CFS', 'Fibromyalgia', 'POTS', 'EDS'],
};
const conditions = conditionMap[utmContent] || conditionMap.default;
Spoon Saver Landing Page Patterns
Product Direction: "Low-effort, non-judgmental, flexible symptom tracking that works on bad days and doesn't create guilt."
Testimonial Cards (Social Proof)
<div className="hover-lift group rounded-[2rem] border border-primary/5 bg-white p-6 shadow-soft">
{}
<div className="mb-4 inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium bg-accent-purple/30 text-purple-800">
<span className="size-1.5 rounded-full bg-current" />
Feeling judged
</div>
{}
<blockquote className="font-display text-primary mb-4 text-lg leading-relaxed">
"Quote from user"
</blockquote>
{}
<div className="flex items-center gap-3">
<div className="flex size-10 items-center justify-center rounded-full bg-accent-purple/20">
<Icon name="person" className="text-primary/60" size="sm" />
</div>
<div>
<p className="text-sm font-medium text-primary">r/ChronicIllness</p>
<p className="text-xs text-text-muted">Fibromyalgia</p>
</div>
</div>
</div>
Pain Point Color Mapping:
| Pain Point | Color Class |
|---|
| burden | bg-accent-rose/20 text-red-700 |
| judgment | bg-accent-purple/30 text-purple-800 |
| brain_fog | bg-accent-blue/30 text-blue-800 |
| relief | bg-accent-mint/40 text-teal-800 |
| aspiration | bg-accent-peach/40 text-orange-800 |
| validation | bg-accent-mint/30 text-teal-700 |
"No Guilt" Comparison Cards
<div className="rounded-2xl border-2 border-red-200 bg-red-50/50 p-6">
<p className="mb-3 text-sm font-semibold uppercase tracking-wide text-red-600">
Other Apps
</p>
<div className="flex items-center gap-3">
<Icon name="sentiment_dissatisfied" size="lg" className="text-red-500" />
<span className="text-sm text-red-700">Pain Level: 8/10 - AWFUL</span>
</div>
<div className="mt-2 flex items-center gap-2 rounded-lg bg-red-100 p-2 text-sm text-red-700">
<Icon name="warning" size="sm" className="text-red-500" />
You broke your 14-day streak!
</div>
</div>
<div className="rounded-2xl border-2 border-accent-mint bg-accent-mint/10 p-6 shadow-soft">
<p className="mb-3 text-sm font-semibold uppercase tracking-wide text-teal-700">
Chronic Life
</p>
<div className="flex items-center gap-3">
<div className="flex size-8 items-center justify-center rounded-full bg-accent-purple/20">
<Icon name="circle" size="sm" className="text-primary/60" />
</div>
<span className="text-sm text-primary">Intensity: 8/10 - High intensity</span>
</div>
<div className="mt-2 flex items-center gap-2 rounded-lg bg-accent-mint/30 p-2 text-sm text-teal-800">
<Icon name="check_circle" size="sm" className="text-teal-600" />
Logged. Tough day — hope you can rest.
</div>
</div>
Section Badge Pattern
<div className="mb-6 inline-flex items-center gap-2 rounded-full bg-accent-peach/30 px-4 py-2 text-sm font-semibold text-primary">
<Icon name="groups" size="sm" />
From the Spoonie Community
</div>
Onboarding Q3 Widget Patterns
Based on onboarding-flow.json, use these widget types:
<div className="flex items-center gap-4">
<div className="h-16 w-8 rounded-full border-2 border-primary/20 overflow-hidden">
<div
className="w-full bg-accent-purple transition-all"
style={{ height: `${value}%` }}
/>
</div>
<span className="text-lg font-medium text-primary">{value}%</span>
</div>
<div className="flex gap-3">
{['green', 'yellow', 'red'].map(color => (
<button className={`
size-16 rounded-xl transition-all
${selected === color ? 'ring-2 ring-primary scale-110' : ''}
${color === 'green' && 'bg-green-400'}
${color === 'yellow' && 'bg-yellow-400'}
${color === 'red' && 'bg-red-400'}
`}>
{color === 'green' && 'Go'}
{color === 'yellow' && 'Caution'}
{color === 'red' && 'Cancel'}
</button>
))}
</div>
<div className="flex flex-wrap gap-2">
{options.map(opt => (
<button className={`
px-4 py-2 rounded-full border transition-all
${selected.includes(opt.value)
? 'bg-pill-selected border-primary text-primary font-semibold'
: 'bg-white border-gray-200 text-gray-700'}
`}>
{opt.label}
</button>
))}
</div>
Memory Stream Visualization (Brain Fog)
<div className="rounded-2xl rounded-bl-none border border-primary/5 bg-accent-blue/5 p-4">
<p className="text-primary leading-relaxed">
You logged{' '}
<span className="rounded bg-accent-purple/20 px-1.5 py-0.5 font-medium">
Poor Sleep
</span>{' '}
on Tuesday. Is today's{' '}
<span className="rounded bg-accent-rose/20 px-1.5 py-0.5 font-medium">
migraine
</span>{' '}
related?
</p>
</div>;
{
}
<div className="mt-4 flex items-center gap-2 rounded-lg bg-accent-mint/20 p-3">
<Icon name="insights" size="sm" className="text-teal-600" />
<span className="text-sm font-medium text-teal-800">
Pattern Detected: 70% of your migraines follow poor sleep by 48 hours
</span>
</div>;
Anti-Patterns (AVOID)
CRITICAL: No Emojis
- ❌ NEVER use emojis in UI, code, or content — Emojis feel juvenile, inconsistent across platforms, and clash with our sophisticated Podia-inspired aesthetic. Use icons from our icon system instead.
General Design Anti-Patterns
- ❌ Generic fonts (Inter alone is fine, but pair with Fraunces for display)
- ❌ Pure white backgrounds (use warm cream #FDFBF9)
- ❌ Sharp corners on cards (always round 16px+)
- ❌ Heavy drop shadows (use soft, low-opacity shadows)
- ❌ Dense forms or multiple text inputs per screen
- ❌ Purple gradients on white (use warm pastels instead)
- ❌ Aggressive animations or transitions
- ❌ Small touch targets (minimum 48px)
- ❌ Stock photos of smiling people (use authentic, hopeful imagery)
- ❌ Abstract illustrations instead of product UI mockups
- ❌ Rainbow gradients (stick to single accent color per section)
Chronic Illness UX Anti-Patterns (CRITICAL)
- ❌ Judgmental iconography: Sad faces 😢, red angry faces, "awful" labels
- ❌ Streak gamification: "You broke your streak!" messages
- ❌ Color-coded judgment: Red = bad day (use neutral intensity scales instead)
- ❌ Guilt-inducing language: "You missed 3 days" without empathy
- ❌ Complex navigation: Nested menus requiring multiple taps
- ❌ Required daily logging: Must allow gaps without penalty
- ❌ Text-heavy inputs: Typing is hard with brain fog, use taps
- ❌ Bright flashy UI: Painful during migraines or sensory sensitivity
- ❌ Social feeds in tracking: Users want focus, not distraction
- ❌ One-size-fits-all scales: "6/10 is bad" — but for chronic pain, 6 might be a GOOD day
Language Anti-Patterns (Per Language of Care guidelines)
- ❌ "Bad day" → Use "High intensity day" (neutral)
- ❌ "You should..." → Use "You might try..." (permission)
- ❌ "Track everything" → Use "Track what matters to YOUR question"
- ❌ Generic messages → Personalize with user's context
- ❌ Clinical jargon without context → Use accessible language