40 KiB
🎨 UX Implementation Plan v2.0 - Teal Primary System
Project: AI Speedrun - Mini-EPD Prototype Versie: v2.0 (Teal-First Design System) Datum: 17-11-2024 Auteur: Colin Lit Context: Showcase voor AI consultancy, niet productie EPD
1. Strategic Context & Design Rationale
1.1 Project Identity (Revised Understanding)
Wat AI Speedrun ECHT is:
- AI consultancy portfolio piece (NIET een EPD vendor)
- Technical demonstration van "Software on Demand" (NIET production healthcare tool)
- Build-in-public LinkedIn content machine (NIET end-user product)
- Proof-of-concept voor GGZ innovatiemanagers (NIET voor therapeuten)
Target Audience:
- ✅ GGZ innovatiemanagers & bestuurders (decision makers)
- ✅ Tech-savvy stakeholders (CTO's, IT managers)
- ✅ LinkedIn followers (build-in-public audience)
- ✅ Consultancy prospects (potential clients)
- ❌ NIET: Dagelijkse EPD gebruikers (therapeuten, psychologen)
Business Goal:
Demonstrate AI expertise through rapid EPD development (€100k → €200, 12 months → 4 weeks) to attract GGZ consultancy clients.
1.2 Why Teal (#0D9488) as Primary Color
Strategic Reasoning:
| Criterion | Blue (#3B82F6) | Teal (#0D9488) | Violet (#5B47ED) | Winner |
|---|---|---|---|---|
| Differentiation | Blends with traditional EPDs | Distinct but professional | Very bold, might alienate | Teal |
| Innovation Signal | Conservative, "old guard" | Modern, tech-forward | Cutting-edge, risky | Teal |
| GGZ Appropriateness | Expected, safe | Healthcare-adjacent, fresh | Too unconventional | Teal |
| LinkedIn Visual Recall | Generic screenshots | Recognizable brand color | Memorable but polarizing | Teal |
| Demo Context | Works but boring | Perfect for 10-min showcase | Strong but might distract | Teal |
| Tailwind Integration | Native (blue-600) | Native (teal-600) | Native (purple-600) | Tie |
Decision: Teal (#0D9488 / Tailwind teal-600) as primary brand color.
Rationale:
- Differentiates from traditional EPD blue-sea (Chipsoft, Epic, Nexus)
- Signals innovation without alienating conservative GGZ sector
- Modern aesthetic (2020s design language, not dated #008080)
- LinkedIn-friendly (visual brand consistency in screenshots)
- Tailwind-native (free design system with teal-50 through teal-900)
- Demo-optimized (visual impact for 10-minute showcases)
Psychology: Teal = Innovation + Clarity + Forward-thinking (without purple's "luxury" or blue's "corporate" baggage)
2. Color System Design
2.1 Primary Brand Colors
/* Teal - Primary Brand (Innovation Signal) */
--color-brand-50: #F0FDFA; /* Subtle backgrounds, hover states */
--color-brand-100: #CCFBF1; /* Light backgrounds, disabled states */
--color-brand-200: #99F6E4; /* Borders, dividers */
--color-brand-300: #5EEAD4; /* Hover borders */
--color-brand-400: #2DD4BF; /* Active states */
--color-brand-500: #14B8A6; /* Base teal (lighter variant) */
--color-brand-600: #0D9488; /* PRIMARY - Main brand color */
--color-brand-700: #0F766E; /* Hover state for buttons */
--color-brand-800: #115E59; /* Active state for buttons */
--color-brand-900: #134E4A; /* Deep variant for text on light bg */
Usage:
- Primary CTAs (buttons, links)
- Focus states (input fields, interactive elements)
- Navigation highlights (active menu items)
- Brand elements (logo accents, hero sections)
- Timeline dots, progress indicators
2.2 AI Features - Amber Highlights
/* Amber - AI Augmentation (Enhancement Signal) */
--color-ai-50: #FFFBEB; /* Subtle AI suggestion backgrounds */
--color-ai-100: #FEF3C7; /* AI suggestion panels */
--color-ai-200: #FDE68A; /* AI highlight borders */
--color-ai-300: #FCD34D; /* Hover states */
--color-ai-400: #FBBF24; /* AI inline highlights */
--color-ai-500: #F59E0B; /* PRIMARY - AI actions */
--color-ai-600: #D97706; /* Hover state */
--color-ai-700: #B45309; /* Active state */
--color-ai-800: #92400E; /* Dark text on light bg */
--color-ai-900: #78350F; /* Deep variant */
Usage:
- AI action buttons (gradient from-amber-500 to-amber-400)
- AI processing states (shimmer animations)
- AI suggestion badges ("AI" icon + amber glow)
- Inline AI highlights (selected text suggestions)
2.3 Neutral Base - Slate
/* Slate - Professional Foundation */
--color-bg-app: #F8FAFC; /* slate-50 - Main app background */
--color-surface: #FFFFFF; /* White - Cards, panels */
--color-surface-secondary: #F1F5F9; /* slate-100 - Secondary surfaces */
--color-border-subtle: #F1F5F9; /* slate-100 - Very subtle borders */
--color-border: #E2E8F0; /* slate-200 - Default borders */
--color-border-strong: #CBD5E1; /* slate-300 - Emphasized borders */
--color-text-primary: #0F172A; /* slate-900 - Headings, emphasis */
--color-text-secondary: #475569;/* slate-600 - Body text, labels */
--color-text-tertiary: #64748B; /* slate-500 - Metadata, captions */
--color-text-placeholder: #94A3B8; /* slate-400 - Input placeholders */
Usage:
- Background hierarchy (app → surface → cards)
- Text hierarchy (primary → secondary → tertiary)
- Border weights (subtle → default → strong)
2.4 Semantic Colors (Universal)
/* Success - Green */
--color-success: #16A34A; /* green-600 - Success states */
--color-success-subtle: #ECFDF5;/* green-50 - Success backgrounds */
--color-success-border: #86EFAC;/* green-300 - Success borders */
/* Warning - Yellow */
--color-warning: #EAB308; /* yellow-500 - Warning states */
--color-warning-subtle: #FEFCE8;/* yellow-50 - Warning backgrounds */
--color-warning-border: #FDE047;/* yellow-300 - Warning borders */
/* Error - Red */
--color-error: #DC2626; /* red-600 - Error states */
--color-error-subtle: #FEF2F2; /* red-50 - Error backgrounds */
--color-error-border: #FCA5A5; /* red-300 - Error borders */
/* Info - Teal (uses brand) */
--color-info: #0D9488; /* teal-600 - Info states (brand color) */
--color-info-subtle: #CCFBF1; /* teal-100 - Info backgrounds */
--color-info-border: #5EEAD4; /* teal-300 - Info borders */
Usage:
- Toast notifications
- Form validation states
- Alert banners
- Status badges
2.5 Functional Module Colors (Behouden)
/* Appointments Module - Green */
--color-module-appointments-bg: #E8F8EF; /* green-100 variant */
--color-module-appointments-accent: #16A34A; /* green-600 */
--color-module-appointments-border: #CDECDC; /* green-200 variant */
/* Medications Module - Amber */
--color-module-meds-bg: #FEF6DC; /* amber-100 variant */
--color-module-meds-accent: #F59E0B; /* amber-500 */
--color-module-meds-border: #F6E7B6; /* amber-200 variant */
/* Lab Results Module - Orange */
--color-module-labs-bg: #FFEBDC; /* orange-100 variant */
--color-module-labs-accent: #F97316; /* orange-500 */
--color-module-labs-border: #FFD2B8; /* orange-200 variant */
Usage:
- EPD module cards (left-border accent pattern)
- Dashboard widgets
- Category badges
3. Typography System
3.1 Font Families (Behouden - Perfect)
// Current font stack is excellent, no changes needed
--font-serif: 'Crimson Text', Georgia, serif; // Storytelling, manifesto
--font-sans: 'Inter', system-ui, sans-serif; // UI, body text
--font-mono: 'JetBrains Mono', 'Courier New', monospace; // Data, timestamps
Rationale:
- Crimson Text = elegant long-form reading (manifesto)
- Inter = clean UI workhorse (buttons, labels, forms)
- JetBrains Mono = technical credibility (IDs, timestamps, code)
3.2 Type Scale
/* Display & Headings */
--text-display: clamp(2.5rem, 6vw, 4rem); /* 40-64px - Hero headings */
line-height: 1.1;
letter-spacing: -0.02em;
--text-h1: clamp(2rem, 5vw, 3rem); /* 32-48px - Page titles */
line-height: 1.1;
letter-spacing: -0.01em;
--text-h2: clamp(1.75rem, 4vw, 2.5rem); /* 28-40px - Section headers */
line-height: 1.2;
font-weight: 600;
--text-h3: 1.5rem; /* 24px - Subsection headers */
line-height: 1.3;
font-weight: 600;
--text-h4: 1.125rem; /* 18px - Card headers */
line-height: 1.4;
font-weight: 600;
/* Body Text */
--text-body: 1rem; /* 16px - Default body */
line-height: 1.5;
--text-body-lg: 1.125rem; /* 18px - Emphasized body */
line-height: 1.6;
--text-body-sm: 0.875rem; /* 14px - Dense content */
line-height: 1.5;
/* Utility Text */
--text-caption: 0.875rem; /* 14px - Metadata, timestamps */
line-height: 1.4;
--text-overline: 0.75rem; /* 12px - Labels, badges */
line-height: 1.4;
letter-spacing: 0.08em;
text-transform: uppercase;
3.3 Font Weight Strategy
/* Inter weights for UI hierarchy */
--font-weight-normal: 400; /* Body text, form inputs */
--font-weight-medium: 500; /* Subtle emphasis, labels */
--font-weight-semibold: 600; /* Buttons, card titles, h3-h4 */
--font-weight-bold: 700; /* Important CTAs, h1-h2 */
/* Crimson Text for storytelling */
--font-weight-regular: 400; /* Manifesto body */
--font-weight-semibold: 600; /* Manifesto headings */
/* JetBrains Mono for data */
--font-weight-regular: 400; /* Timestamps, IDs */
--font-weight-medium: 500; /* Emphasized data points */
4. Component Patterns
4.1 Button System
Primary Button (Teal)
<button className="
px-6 py-3
bg-teal-600 hover:bg-teal-700 active:bg-teal-800
text-white font-sans font-semibold
rounded-lg
focus:outline-none focus:ring-2 focus:ring-teal-500 focus:ring-offset-2
transition-colors duration-200
disabled:opacity-50 disabled:cursor-not-allowed
">
Primary Action
</button>
Usage: Main CTAs, form submissions, primary navigation actions
AI Action Button (Amber Gradient)
<button className="
px-6 py-3
bg-gradient-to-r from-amber-500 to-amber-400
hover:from-amber-600 hover:to-amber-500
text-amber-900 font-sans font-semibold
rounded-lg
shadow-sm hover:shadow-md
flex items-center gap-2
transition-all duration-200
">
<SparklesIcon className="w-5 h-5" />
Generate with AI
</button>
Usage: AI-powered actions (summarize, categorize, generate plan)
Secondary Button (Neutral)
<button className="
px-6 py-3
bg-slate-700 hover:bg-slate-800
text-white font-sans font-semibold
rounded-lg
transition-colors duration-200
">
Secondary Action
</button>
Usage: Alternative actions, cancel, back navigation
Ghost Button (Teal Outline)
<button className="
px-6 py-3
bg-transparent hover:bg-teal-50
text-teal-600 hover:text-teal-700
border border-teal-600 hover:border-teal-700
font-sans font-semibold
rounded-lg
transition-all duration-200
">
Tertiary Action
</button>
Usage: Tertiary actions, filters, toggles
4.2 Input Fields
Standard Input
<input className="
w-full px-4 py-3
bg-white border border-slate-200
text-slate-900 placeholder:text-slate-400
font-sans text-body-sm
rounded-lg
focus:outline-none
focus:border-teal-600
focus:ring-2 focus:ring-teal-500 focus:ring-opacity-20
disabled:bg-slate-100 disabled:text-slate-500
transition-all duration-200
" />
AI-Enhanced Input (with suggestion indicator)
<div className="relative">
<input className="
w-full px-4 py-3 pr-16
bg-white border border-slate-200
text-slate-900
rounded-lg
focus:border-teal-600
focus:ring-2 focus:ring-teal-500 focus:ring-opacity-20
data-[ai-active]:border-amber-500
data-[ai-active]:ring-amber-500
" />
<div className="absolute right-3 top-3">
<span className="
text-caption font-medium text-amber-600
flex items-center gap-1
px-2 py-0.5
bg-amber-50 rounded
">
<SparklesIcon className="w-4 h-4" />
AI
</span>
</div>
</div>
4.3 Card System
Module Card (Semantic Left Border)
<div className="
bg-white
border-l-[3px] border-l-teal-600
border border-slate-200
rounded-lg
p-6
hover:bg-teal-50 hover:shadow-md
transition-all duration-200
">
<div className="flex items-start gap-3">
{/* Icon */}
<div className="
w-10 h-10
bg-teal-100
rounded-lg
flex items-center justify-center
">
<IconComponent className="w-5 h-5 text-teal-700" />
</div>
{/* Content */}
<div className="flex-1">
<h3 className="font-sans font-semibold text-h4 text-slate-900">
Card Title
</h3>
<p className="font-mono text-caption text-slate-500 mt-1">
Metadata or timestamp
</p>
<p className="font-sans text-body-sm text-slate-600 mt-2">
Card description content
</p>
</div>
</div>
</div>
Variants:
border-l-green-600for appointments moduleborder-l-amber-500for medications moduleborder-l-orange-500for lab results module
Standard Card (No Accent)
<div className="
bg-white
border border-slate-200
rounded-lg
p-6
hover:shadow-md
transition-shadow duration-200
">
{/* Content */}
</div>
4.4 Badge System
// Status Badge
<span className="
inline-flex items-center gap-1
px-2.5 py-0.5
text-overline font-medium
bg-teal-100 text-teal-700
rounded-full
">
Active
</span>
// AI Badge
<span className="
inline-flex items-center gap-1
px-2.5 py-0.5
text-overline font-medium
bg-amber-100 text-amber-700
rounded-full
">
<SparklesIcon className="w-3 h-3" />
AI Generated
</span>
// Severity Badge (DSM)
<span className="
inline-flex items-center
px-2.5 py-0.5
text-caption font-medium
bg-red-100 text-red-700
rounded
">
Hoog
</span>
5. Motion & Animation Principles
5.1 Duration Scale
export const motionDurations = {
instant: '100ms', // Micro-feedback (button press, checkbox toggle)
fast: '200ms', // Hover states, tooltips
normal: '300ms', // Panel opens, dropdown menus
slow: '500ms', // Modals, drawers
glacial: '800ms', // Marketing animations only (hero sections)
}
Rules:
- EPD Interface: Use
instanttonormalonly (users want speed) - Marketing Site: Can use up to
glacial(storytelling allows slower pace)
5.2 Easing Functions
/* Standard easing (default) */
--ease-standard: cubic-bezier(0.4, 0.0, 0.2, 1);
/* Decelerate (elements entering screen) */
--ease-decelerate: cubic-bezier(0.0, 0.0, 0.2, 1);
/* Accelerate (elements exiting screen) */
--ease-accelerate: cubic-bezier(0.4, 0.0, 1, 1);
/* Gentle (calm, therapeutic feel) */
--ease-gentle: cubic-bezier(0.25, 0.46, 0.45, 0.94);
Usage:
- Standard: Most transitions
- Decelerate: Modals opening, panels sliding in
- Accelerate: Modals closing, panels sliding out
- Gentle: Marketing site, long-form content
5.3 AI-Specific Animations
"Thinking" Shimmer
@keyframes ai-thinking {
0% { background-position: -200% center; }
100% { background-position: 200% center; }
}
.ai-processing {
background: linear-gradient(
90deg,
transparent,
rgba(245, 158, 11, 0.1),
transparent
);
background-size: 200% 100%;
animation: ai-thinking 1.5s ease-in-out infinite;
}
Usage: Loading states for AI API calls
Fade-Slide-Up (AI Suggestions)
@keyframes fadeSlideUp {
from {
opacity: 0;
transform: translateY(8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.ai-suggestion-enter {
animation: fadeSlideUp 400ms var(--ease-gentle);
}
Usage: AI suggestions appearing in right panel (AI-rail)
Pulse (AI Badge)
@keyframes pulse-amber {
0%, 100% { opacity: 1; }
50% { opacity: 0.6; }
}
.ai-badge-pulse {
animation: pulse-amber 2s ease-in-out infinite;
}
Usage: AI badge on active processing
5.4 Performance Guidelines
// Prefer transforms over top/left
// GOOD:
transform: translateY(8px);
// BAD:
top: 8px;
// Prefer opacity over visibility
// GOOD:
opacity: 0; pointer-events: none;
// BAD:
display: none;
// Use will-change sparingly
.modal-enter {
will-change: transform, opacity;
}
.modal-enter-done {
will-change: auto; /* Remove after animation */
}
6. Implementation Roadmap
Phase 1: Foundation (Week 1 - Day 1-2)
Priority: CRITICAL - Breaking changes, full color swap
Task 1.1: Update Tailwind Config
File: tailwind.config.ts
Time: 30 min
// Replace blue-based brand with teal
colors: {
brand: {
50: '#F0FDFA',
100: '#CCFBF1',
200: '#99F6E4',
300: '#5EEAD4',
400: '#2DD4BF',
500: '#14B8A6',
600: '#0D9488', // PRIMARY
700: '#0F766E',
800: '#115E59',
900: '#134E4A',
},
ai: colors.amber, // Keep amber for AI features
// Semantic colors (keep existing)
success: colors.green,
warning: colors.yellow,
error: colors.red,
// Info now uses brand teal
info: {
DEFAULT: '#0D9488',
light: '#CCFBF1',
dark: '#0F766E',
},
}
Task 1.2: Update Global CSS Variables
File: app/globals.css
Time: 20 min
@layer base {
:root {
/* Primary Brand - UPDATE from blue to teal */
--primary: #0D9488; /* was #3B82F6 */
--primary-foreground: #FFFFFF;
/* Info color - UPDATE to match brand */
--info: #0D9488; /* was #3B82F6 */
/* Keep existing */
--background: #F8FAFC;
--foreground: #0F172A;
--border: #E2E8F0;
/* AI colors - KEEP */
--ai-highlight: #F59E0B;
--ai-subtle: #FEF3C7;
/* Module colors - KEEP */
--module-appointments: #16A34A;
--module-meds: #F59E0B;
--module-labs: #F97316;
}
.dark {
/* Dark mode variants (if needed later) */
--primary: #14B8A6; /* Lighter teal for dark bg */
}
}
Task 1.3: Test Contrast Ratios
Tool: WebAIM Contrast Checker Time: 15 min
Verify WCAG AA compliance:
- Teal-600 (#0D9488) on white: 4.58:1 ✅ (AA Large Text)
- Teal-700 (#0F766E) on white: 5.77:1 ✅ (AA Normal Text)
- Teal-900 (#134E4A) on white: 11.32:1 ✅ (AAA)
- White on teal-600: 4.58:1 ✅ (AA Large Text)
Action if needed: Use teal-700 for small text on white, teal-600 for buttons with white text.
Phase 2: Component Updates (Week 1 - Day 2-3)
Priority: HIGH - Visible user-facing changes
Task 2.1: Sign-In Component Refactor
File: components/ui/sign-in.tsx
Time: 1 hour
Changes:
// Background
- className="bg-[#e8f4ef]"
+ className="bg-slate-50"
// Primary buttons
- className="bg-blue-600 hover:bg-blue-500"
+ className="bg-teal-600 hover:bg-teal-700"
// Links
- className="text-blue-400 hover:text-blue-300"
+ className="text-teal-400 hover:text-teal-300"
// Stat card 1 (Orange - Cost reduction)
- Content: "41% of recruiters..."
+ Content: "€100k → €200: 99.8% cost reduction"
+ Keep: bg-gradient-to-br from-orange-500 to-orange-400
// Stat card 2 (Green - Speed)
- Content: "76% of hiring managers..."
+ Content: "4 weeks: traditional takes 6 months"
- bg-green-500
+ bg-gradient-to-br from-teal-500 to-teal-400
Before/After:
- Before: Generic job-seeking stats with blue/green
- After: AI Speedrun specific metrics with teal/amber theme
Task 2.2: Timeline Component Update
File: components/ui/timeline.tsx (to be created from docs/design/timeline-comp.tsx)
Time: 1.5 hours
Implementation:
- Copy timeline component from
docs/design/timeline-comp.tsx - Update gradient:
// Line gradient
- className="bg-gradient-to-t from-purple-500 via-blue-500"
+ className="bg-gradient-to-t from-teal-600 via-teal-500 to-transparent"
// Dots
- className="bg-white border-purple-200"
+ className="bg-white border-teal-200"
// Active dot
- className="bg-purple-600"
+ className="bg-teal-600"
// Timestamps (add mono font)
+ className="text-teal-600 font-mono text-caption"
- Create content structure:
File:
content/nl/timeline.json
[
{
"weekNumber": 1,
"title": "Week 1 • Nov 11-17",
"status": "completed",
"description": "Marketing site foundation opgezet. Hero section, manifesto content, database schema aangemaakt.",
"metrics": {
"developmentHours": 30,
"infrastructureCost": 50
},
"achievements": [
"Landing page met hero + statement",
"EPD demo pagina met credentials",
"Contact form + lead capture API",
"Database schema (5 core tables)",
"Supabase Auth + RLS policies"
]
},
{
"weekNumber": 2,
"title": "Week 2 • Nov 18-24",
"status": "in_progress",
"description": "EPD app foundation. Client management, auth flow, protected routes.",
"metrics": {
"developmentHours": 0,
"infrastructureCost": 0
},
"achievements": []
}
]
Task 2.3: Navigation Component Update
File: app/(marketing)/components/minimal-nav.tsx
Time: 30 min
Changes:
// Active link styling
- className="text-blue-600"
+ className="text-teal-600"
// Hover states
- className="hover:text-blue-700"
+ className="hover:text-teal-700"
// Mobile menu button
- className="text-blue-600"
+ className="text-teal-600"
Task 2.4: Create AI Button Component
File: components/ui/ai-button.tsx (NEW)
Time: 20 min
import { SparklesIcon } from 'lucide-react'
interface AIButtonProps {
children: React.ReactNode
onClick?: () => void
loading?: boolean
disabled?: boolean
}
export function AIButton({ children, onClick, loading, disabled }: AIButtonProps) {
return (
<button
onClick={onClick}
disabled={disabled || loading}
className="
px-6 py-3
bg-gradient-to-r from-amber-500 to-amber-400
hover:from-amber-600 hover:to-amber-500
text-amber-900 font-sans font-semibold text-body-sm
rounded-lg
shadow-sm hover:shadow-md
flex items-center justify-center gap-2
disabled:opacity-50 disabled:cursor-not-allowed
transition-all duration-200
"
>
{loading ? (
<>
<div className="w-5 h-5 border-2 border-amber-900/20 border-t-amber-900 rounded-full animate-spin" />
Processing...
</>
) : (
<>
<SparklesIcon className="w-5 h-5" />
{children}
</>
)}
</button>
)
}
Usage:
<AIButton onClick={handleAISummarize}>
Generate Summary
</AIButton>
Task 2.5: Update Module Cards (EPD)
Files: Future EPD components Time: 30 min
Pattern:
// Appointments card
<div className="
bg-white
border-l-[3px] border-l-green-600
border border-slate-200
rounded-lg p-6
hover:bg-green-50
">
// Medications card
<div className="
bg-white
border-l-[3px] border-l-amber-500
border border-slate-200
rounded-lg p-6
hover:bg-amber-50
">
// Labs card
<div className="
bg-white
border-l-[3px] border-l-orange-500
border border-slate-200
rounded-lg p-6
hover:bg-orange-50
">
Phase 3: Marketing Site Integration (Week 1 - Day 3-4)
Priority: MEDIUM - Content updates, new sections
Task 3.1: Homepage Restructure
File: app/(marketing)/page.tsx
Time: 2 hours
New Structure:
export default function HomePage() {
return (
<main>
{/* 1. Hero Section - KEEP */}
<HeroQuote />
{/* 2. Statement Section - NEW */}
<StatementSection />
{/* 3. Timeline Section - NEW */}
<TimelineSection />
{/* 4. CTA Section - SIMPLIFIED */}
<CTASection />
</main>
)
}
Remove:
- ManifestoContent (long-form moved to separate /about page if needed)
- ComparisonTable (moved to /epd page)
- Multiple InsightBox components
Task 3.2: Create Statement Section
File: app/(marketing)/components/statement-section.tsx (NEW)
Time: 1 hour
export function StatementSection() {
return (
<section className="
max-w-4xl mx-auto px-6 py-24
">
<h2 className="
font-serif font-semibold text-h1 text-slate-900
mb-8
">
Software on Demand: Van €100k naar €200
</h2>
<div className="
font-serif text-body-lg text-slate-700
space-y-6
leading-loose
">
<p>
Enterprise software kost gemiddeld <strong>€100.000+</strong> en duurt
<strong> 12-24 maanden</strong> om te bouwen. Voor een GGZ-praktijk met
5 therapeuten is dit onbereikbaar.
</p>
<p>
AI-powered development verandert dit. Met Claude als co-pilot, moderne
frameworks, en cloud infrastructure bouwen we hetzelfde EPD in
<strong> 4 weken</strong> voor <strong>€200</strong> totale kosten.
</p>
<p className="text-teal-700 font-semibold">
Dit project is het bewijs. Volg hieronder de voortgang week voor week.
</p>
</div>
</section>
)
}
Task 3.3: Integrate Timeline Component
File: app/(marketing)/components/timeline-section.tsx (NEW)
Time: 1 hour
import { Timeline } from '@/components/ui/timeline'
import { getContent } from '@/lib/content/loader'
export async function TimelineSection() {
const timelineData = await getContent('nl', 'timeline')
// Transform to Timeline component format
const data = timelineData.map(week => ({
title: week.title,
content: (
<div>
<p className="text-slate-700 text-body-sm mb-4">
{week.description}
</p>
{/* Metrics */}
{week.metrics && (
<div className="grid grid-cols-2 gap-4 mb-6">
<div className="bg-teal-50 border border-teal-200 rounded-lg p-4">
<div className="text-overline text-teal-700 mb-1">Dev Hours</div>
<div className="font-mono text-h3 text-teal-900">
{week.metrics.developmentHours}
</div>
</div>
<div className="bg-amber-50 border border-amber-200 rounded-lg p-4">
<div className="text-overline text-amber-700 mb-1">Cost</div>
<div className="font-mono text-h3 text-amber-900">
€{week.metrics.infrastructureCost}
</div>
</div>
</div>
)}
{/* Achievements */}
{week.achievements && week.achievements.length > 0 && (
<div className="space-y-2">
{week.achievements.map((achievement, i) => (
<div key={i} className="flex items-center gap-2 text-body-sm text-slate-600">
<div className="w-1.5 h-1.5 rounded-full bg-teal-600" />
{achievement}
</div>
))}
</div>
)}
</div>
),
}))
return (
<section id="timeline" className="py-24 bg-slate-50">
<div className="max-w-6xl mx-auto px-6">
<h2 className="font-serif font-semibold text-h2 text-slate-900 mb-4 text-center">
Build in Public: 4 Weken Progress
</h2>
<p className="font-sans text-body text-slate-600 mb-12 text-center max-w-2xl mx-auto">
Transparantie vanaf dag 1. Volg elke week de voortgang,
kosten, en geleerde lessen.
</p>
<Timeline data={data} />
</div>
</section>
)
}
Task 3.4: Update CTA Section
File: Update existing CTA in homepage Time: 20 min
Simplified CTA:
<section className="py-24 bg-white">
<div className="max-w-4xl mx-auto px-6 text-center">
<h2 className="font-serif font-semibold text-h2 text-slate-900 mb-6">
Klaar om te experimenteren?
</h2>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
{/* Primary CTA */}
<a
href="/epd"
className="
px-8 py-4
bg-teal-600 hover:bg-teal-700
text-white font-sans font-semibold text-body
rounded-lg
transition-colors duration-200
"
>
Bekijk het EPD Prototype
</a>
{/* Secondary CTA */}
<a
href="/contact"
className="
px-8 py-4
bg-slate-700 hover:bg-slate-800
text-white font-sans font-semibold text-body
rounded-lg
transition-colors duration-200
"
>
Start een Project
</a>
</div>
</div>
</section>
Phase 4: Content Updates (Week 1 - Day 4)
Priority: MEDIUM - Supporting content
Task 4.1: Fix EPD Page Links
File: app/(marketing)/epd/credentials-box.tsx
Time: 5 min
// Line 80 or wherever login link is
- href="/app/login"
+ href="/login"
Task 4.2: Update Navigation Content
File: content/nl/navigation.json
Time: 5 min
{
"logo": {
"text": "AI Speedrun",
"href": "/"
},
"links": [
{
"label": "Home",
"href": "/"
},
{
"label": "EPD Prototype",
"href": "/epd"
},
{
"label": "Contact",
"href": "/contact"
},
{
"label": "Login",
"href": "/login"
}
]
}
Task 4.3: Create Timeline Content
File: content/nl/timeline.json (NEW)
Time: 30 min
See Task 2.2 for structure. Populate with real Week 1 data.
Phase 5: EPD App Foundation (Week 2 - Later)
Priority: LOW - Can be done in Week 2
Task 5.1: Coming Soon Dashboard
File: app/epd/clients/page.tsx (NEW)
Time: 45 min
import { redirect } from 'next/navigation'
import { createClient } from '@/lib/supabase/server'
export default async function ClientsPage() {
const supabase = createClient()
const { data: { user } } = await supabase.auth.getUser()
if (!user) {
redirect('/login')
}
return (
<div className="min-h-screen bg-slate-50 flex items-center justify-center p-6">
<div className="max-w-2xl w-full bg-white border border-slate-200 rounded-lg p-12 text-center">
{/* Icon */}
<div className="w-16 h-16 bg-teal-100 rounded-full flex items-center justify-center mx-auto mb-6">
<svg className="w-8 h-8 text-teal-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
</svg>
</div>
{/* Heading */}
<h1 className="font-sans font-bold text-h1 text-slate-900 mb-4">
EPD Dashboard - Coming Week 2
</h1>
{/* Description */}
<p className="font-sans text-body text-slate-600 mb-8">
De EPD applicatie wordt momenteel gebouwd.
Volg de voortgang op de <a href="/#timeline" className="text-teal-600 hover:underline">homepage timeline</a>.
</p>
{/* Timeline Preview */}
<div className="bg-slate-50 rounded-lg p-6 mb-8 text-left">
<h2 className="font-sans font-semibold text-h4 text-slate-900 mb-4">
Development Roadmap
</h2>
<div className="space-y-3">
<div className="flex items-start gap-3">
<div className="w-6 h-6 bg-teal-600 rounded-full flex items-center justify-center flex-shrink-0 mt-0.5">
<svg className="w-3 h-3 text-white" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
</svg>
</div>
<div>
<div className="font-sans font-medium text-body-sm text-slate-900">Week 1: Foundation ✓</div>
<div className="font-sans text-caption text-slate-500">Marketing site, auth, database schema</div>
</div>
</div>
<div className="flex items-start gap-3">
<div className="w-6 h-6 border-2 border-teal-600 rounded-full flex-shrink-0 mt-0.5">
<div className="w-2 h-2 bg-teal-600 rounded-full m-0.5 animate-pulse" />
</div>
<div>
<div className="font-sans font-medium text-body-sm text-slate-900">Week 2: Client Management</div>
<div className="font-sans text-caption text-slate-500">CRUD operations, client list, detail views</div>
</div>
</div>
<div className="flex items-start gap-3">
<div className="w-6 h-6 border-2 border-slate-300 rounded-full flex-shrink-0 mt-0.5" />
<div>
<div className="font-sans font-medium text-body-sm text-slate-500">Week 3: AI Integration</div>
<div className="font-sans text-caption text-slate-400">Intake editor, summarization, categorization</div>
</div>
</div>
<div className="flex items-start gap-3">
<div className="w-6 h-6 border-2 border-slate-300 rounded-full flex-shrink-0 mt-0.5" />
<div>
<div className="font-sans font-medium text-body-sm text-slate-500">Week 4: Polish & Launch</div>
<div className="font-sans text-caption text-slate-400">Onboarding, optimization, demo prep</div>
</div>
</div>
</div>
</div>
{/* Actions */}
<div className="flex gap-4 justify-center">
<a
href="/epd"
className="
px-6 py-3
bg-teal-600 hover:bg-teal-700
text-white font-sans font-semibold
rounded-lg
transition-colors duration-200
"
>
Terug naar Prototype Info
</a>
<a
href="/auth/logout"
className="
px-6 py-3
bg-slate-200 hover:bg-slate-300
text-slate-700 font-sans font-semibold
rounded-lg
transition-colors duration-200
"
>
Logout
</a>
</div>
</div>
</div>
)
}
Task 5.2: Update Middleware Redirects
File: middleware.ts
Time: 10 min
// Line 78-81: Update redirect target
if (user && pathname === '/login') {
return NextResponse.redirect(new URL('/epd/clients', request.url))
}
// Ensure /epd/clients is protected
const publicRoutes = [
'/', '/epd', '/contact', '/login',
'/auth/callback', '/auth/logout'
]
// /epd/clients is NOT in publicRoutes, so it's protected ✓
Phase 6: Documentation (Week 1 - Day 5)
Priority: LOW - Can be done async
Task 6.1: Update UX Stylesheet
File: docs/specs/ux-stylesheet.md
Time: 30 min
Document the new teal-first system with:
- Color palette updates
- Component examples
- Usage guidelines
Task 6.2: Create Component Library Doc
File: docs/specs/component-library.md (NEW)
Time: 1 hour
Document all reusable components:
- AIButton
- ModuleCard
- Timeline
- Badge variants
- Button variants
Task 6.3: Update Bouwplan
File: docs/specs/bouwplan-ai-speedrun-marketing-first-v1.1.md
Time: 15 min
Update status:
- E1 (Marketing Website): 100% complete → Mark timeline integration
- E2 (Database & Auth): Update progress
7. Testing & Quality Assurance
7.1 Visual Regression Checklist
Manual Testing:
- Homepage: Hero, statement, timeline, CTA flow correctly
- EPD page: Features, credentials, comparison table visible
- Contact page: Form submits, validation works
- Login page: Both flows work (magic link + demo)
- Coming Soon page: Roadmap displays, logout works
Cross-Browser:
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
Responsive:
- Mobile (375px)
- Tablet (768px)
- Desktop (1440px)
7.2 Accessibility Audit
WCAG AA Compliance:
- Color contrast ≥ 4.5:1 for normal text
- Color contrast ≥ 3:1 for large text (18px+)
- Focus states visible (teal ring)
- Keyboard navigation works
- Screen reader labels present
- No color-only information (icons + text)
Tools:
- axe DevTools (Chrome extension)
- Lighthouse (built into Chrome DevTools)
- Color contrast analyzer
7.3 Performance Benchmarks
Lighthouse Targets:
- Performance: > 90
- Accessibility: 100
- Best Practices: > 95
- SEO: 100
Core Web Vitals:
- LCP (Largest Contentful Paint): < 2.5s
- FID (First Input Delay): < 100ms
- CLS (Cumulative Layout Shift): < 0.1
Optimization:
- Use next/image for all images
- Lazy load timeline component
- Code-split marketing vs EPD routes
- Minimize CSS (Tailwind purge)
8. Migration Checklist (Quick Reference)
Global Changes
- tailwind.config.ts: blue → teal brand colors
- globals.css: --primary and --info variables
- Test contrast ratios (WCAG AA)
Component Updates
- Sign-in: bg, buttons, stats content
- Timeline: gradient, dots, timestamps
- MinimalNav: links, active states
- AIButton: create new component
- Module cards: left-border pattern
Content Updates
- navigation.json: add Login link
- timeline.json: create Week 1 data
- epd/credentials-box: fix login href
New Components
- StatementSection: homepage pitch
- TimelineSection: build-in-public
- Coming Soon page: /epd/clients
Cleanup
- Remove long-form manifesto from homepage
- Move comparison table to /epd only
- Archive unused InsightBox components
9. Success Metrics
Qualitative Goals
- Visual Impact: Screenshots are instantly recognizable as AI Speedrun brand
- LinkedIn Shareability: Timeline posts generate engagement
- Demo Effectiveness: 10-min demo flows smoothly without confusion
- Brand Coherence: Teal = innovation signal is clear to stakeholders
Quantitative Targets
- Lighthouse Performance: > 90
- Accessibility Score: 100 (WCAG AA)
- Load Time: Homepage < 2s on 3G
- Conversion: > 5% contact form completion from landing
Week 1 Review Questions
- Does teal feel "innovative but trustworthy"?
- Do GGZ stakeholders understand the AI Speedrun value prop?
- Is the timeline section compelling for LinkedIn?
- Does the Coming Soon page manage expectations well?
10. Rollback Plan (If Needed)
If Teal Doesn't Work
Scenario: Stakeholder feedback is negative, teal feels wrong
Quick Rollback (< 1 hour):
- Revert tailwind.config.ts: teal → blue
- Revert globals.css: --primary back to #3B82F6
- Git revert component changes
- Deploy previous version
Keep: Timeline component, statement section, improved content Revert: Only color changes
Partial Rollback
Scenario: Teal works for marketing, not for EPD
Hybrid Approach:
- Marketing site: Keep teal (#0D9488)
- EPD app: Revert to blue (#3B82F6)
- Justification: "Bold vision (marketing) + Familiar execution (product)"
11. Next Steps (Week 2+)
After Teal Implementation
Week 2 Focus:
- Build actual EPD client list (replace Coming Soon)
- Client detail page with tabs (intake, profile, plan)
- Forms for client creation/editing
Week 3 Focus:
- TipTap editor for intake notes
- AI integration (Claude API endpoints)
- AI-rail component for suggestions
Week 4 Focus:
- Onboarding flow
- Polish & optimization
- Demo dry-run preparation
12. Resources & References
Design System Documentation
- Tailwind Docs: https://tailwindcss.com/docs/customizing-colors
- WCAG Contrast: https://webaim.org/resources/contrastchecker/
- Color Palette Tool: https://coolors.co
Inspiration
- Linear: https://linear.app (violet/purple primary)
- Vercel: https://vercel.com/design (systematic grays)
- Notion: https://notion.so (clean, minimal)
Internal Docs
- FO v2.0:
docs/specs/fo-marketing-app-flow-v2.md - UX Stylesheet (current):
docs/specs/ux-stylesheet.md - Bouwplan:
docs/specs/bouwplan-ai-speedrun-marketing-first-v1.1.md
Changelog
| Version | Date | Author | Changes |
|---|---|---|---|
| v2.0 | 17-11-2024 | Colin | Initial UX Implementation Plan with teal-first design system. Strategic pivot from blue to teal based on AI Speedrun positioning as consultancy showcase. |
Status: Ready for Implementation Next Action: Begin Phase 1 (tailwind.config.ts update) Owner: Colin Lit Timeline: Week 1, Days 1-5