grubflip-design/sponsor-token-purchase.html
Ava 9fb5bd83a6 Add Payfrit design system, page templates, and component prototypes
Core brand design system, page layout templates, avatar styles,
sponsor token purchase flow, and status dashboard — all as living
HTML/CSS design references for the team.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 05:56:18 +00:00

805 lines
23 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sponsor Portal — Token Purchase UI | Payfrit Design</title>
<style>
/* ========================================
SPONSOR PORTAL: TOKEN PURCHASE UI
Designed by Ava — 2026-03-21
Design spec for @nora to implement
======================================== */
/* --- Design Tokens (from design-system.html) --- */
:root {
--color-primary: #0D6E6E;
--color-primary-light: #14A3A3;
--color-primary-dark: #094F4F;
--color-primary-bg: #E6F5F5;
--color-accent: #F5A623;
--color-accent-light: #FFCF70;
--color-accent-dark: #C4841A;
--color-success: #2ECC71;
--color-success-bg: #EAFAF1;
--color-warning: #F39C12;
--color-warning-bg: #FEF5E7;
--color-error: #E74C3C;
--color-error-bg: #FDEDEC;
--color-info: #3498DB;
--color-info-bg: #EBF5FB;
--color-gray-50: #F9FAFB;
--color-gray-100: #F3F4F6;
--color-gray-200: #E5E7EB;
--color-gray-300: #D1D5DB;
--color-gray-400: #9CA3AF;
--color-gray-500: #6B7280;
--color-gray-600: #4B5563;
--color-gray-700: #374151;
--color-gray-800: #1F2937;
--color-gray-900: #111827;
--color-bg: #FFFFFF;
--color-bg-subtle: #F9FAFB;
--color-bg-muted: #F3F4F6;
--font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
--font-mono: 'JetBrains Mono', 'Fira Code', monospace;
--text-xs: 0.75rem;
--text-sm: 0.875rem;
--text-base: 1rem;
--text-lg: 1.125rem;
--text-xl: 1.25rem;
--text-2xl: 1.5rem;
--text-3xl: 1.875rem;
--text-4xl: 2.25rem;
--font-normal: 400;
--font-medium: 500;
--font-semibold:600;
--font-bold: 700;
--leading-tight: 1.25;
--leading-normal: 1.5;
--leading-relaxed: 1.625;
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-3: 0.75rem;
--space-4: 1rem;
--space-5: 1.25rem;
--space-6: 1.5rem;
--space-8: 2rem;
--space-10: 2.5rem;
--space-12: 3rem;
--space-16: 4rem;
--radius-sm: 0.25rem;
--radius-md: 0.5rem;
--radius-lg: 0.75rem;
--radius-xl: 1rem;
--radius-full: 9999px;
--shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
--shadow-md: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -2px rgba(0,0,0,0.1);
--shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -4px rgba(0,0,0,0.1);
--shadow-xl: 0 20px 25px -5px rgba(0,0,0,0.1), 0 8px 10px -6px rgba(0,0,0,0.1);
--transition-fast: 150ms ease;
--transition-base: 200ms ease;
--transition-slow: 300ms ease;
}
/* --- Reset & Base --- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { font-size: 16px; -webkit-font-smoothing: antialiased; }
body {
font-family: var(--font-family);
color: var(--color-gray-800);
background: var(--color-bg-subtle);
line-height: var(--leading-normal);
}
/* --- Spec Banner --- */
.spec-banner {
background: linear-gradient(135deg, #1a1a2e, #16213e);
color: white;
padding: var(--space-6) var(--space-8);
text-align: center;
font-size: var(--text-sm);
letter-spacing: 0.05em;
}
.spec-banner strong { color: var(--color-accent-light); font-size: var(--text-base); display: block; margin-bottom: var(--space-1); }
.spec-banner span { opacity: 0.7; }
/* --- Page Shell (simulates sponsor portal layout) --- */
.portal-shell {
display: flex;
min-height: 100vh;
}
/* Sidebar */
.sidebar {
width: 260px;
background: var(--color-primary-dark);
color: white;
padding: var(--space-6) 0;
flex-shrink: 0;
}
.sidebar-logo {
padding: 0 var(--space-6) var(--space-6);
border-bottom: 1px solid rgba(255,255,255,0.1);
margin-bottom: var(--space-4);
}
.sidebar-logo h2 {
font-size: var(--text-xl);
font-weight: var(--font-bold);
letter-spacing: -0.02em;
}
.sidebar-logo span {
font-size: var(--text-xs);
opacity: 0.6;
text-transform: uppercase;
letter-spacing: 0.08em;
}
.nav-item {
display: flex;
align-items: center;
gap: var(--space-3);
padding: var(--space-3) var(--space-6);
font-size: var(--text-sm);
color: rgba(255,255,255,0.7);
cursor: pointer;
transition: all var(--transition-fast);
border-left: 3px solid transparent;
}
.nav-item:hover { background: rgba(255,255,255,0.05); color: white; }
.nav-item.active {
background: rgba(255,255,255,0.1);
color: white;
border-left-color: var(--color-accent);
font-weight: var(--font-medium);
}
.nav-icon { width: 18px; text-align: center; opacity: 0.8; }
/* Main Content */
.main-content {
flex: 1;
padding: var(--space-8);
max-width: 960px;
}
/* --- Page Header --- */
.page-header {
margin-bottom: var(--space-8);
}
.page-header h1 {
font-size: var(--text-3xl);
font-weight: var(--font-bold);
color: var(--color-gray-900);
margin-bottom: var(--space-1);
}
.page-header p {
font-size: var(--text-base);
color: var(--color-gray-500);
}
/* --- Balance Card --- */
.balance-card {
background: linear-gradient(135deg, var(--color-primary), var(--color-primary-light));
color: white;
border-radius: var(--radius-xl);
padding: var(--space-8);
margin-bottom: var(--space-8);
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: var(--shadow-lg);
}
.balance-label {
font-size: var(--text-sm);
opacity: 0.8;
text-transform: uppercase;
letter-spacing: 0.06em;
margin-bottom: var(--space-1);
}
.balance-amount {
font-size: var(--text-4xl);
font-weight: var(--font-bold);
letter-spacing: -0.02em;
}
.balance-amount span {
font-size: var(--text-xl);
font-weight: var(--font-normal);
opacity: 0.8;
}
.balance-meta {
text-align: right;
}
.balance-meta-item {
font-size: var(--text-sm);
opacity: 0.75;
margin-bottom: var(--space-1);
}
/* --- Token Packages Grid --- */
.section-label {
font-size: var(--text-lg);
font-weight: var(--font-semibold);
color: var(--color-gray-900);
margin-bottom: var(--space-4);
}
.section-sublabel {
font-size: var(--text-sm);
color: var(--color-gray-500);
margin-top: calc(-1 * var(--space-3));
margin-bottom: var(--space-6);
}
.packages-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--space-4);
margin-bottom: var(--space-8);
}
.package-card {
border: 2px solid var(--color-gray-200);
border-radius: var(--radius-lg);
padding: var(--space-6);
text-align: center;
cursor: pointer;
transition: all var(--transition-base);
background: white;
position: relative;
}
.package-card:hover {
border-color: var(--color-primary-light);
box-shadow: var(--shadow-md);
transform: translateY(-2px);
}
.package-card.selected {
border-color: var(--color-primary);
background: var(--color-primary-bg);
box-shadow: 0 0 0 3px rgba(13, 110, 110, 0.15);
}
.package-card.popular {
border-color: var(--color-accent);
}
.popular-badge {
position: absolute;
top: -12px;
left: 50%;
transform: translateX(-50%);
background: var(--color-accent);
color: white;
font-size: var(--text-xs);
font-weight: var(--font-semibold);
padding: var(--space-1) var(--space-3);
border-radius: var(--radius-full);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.package-tokens {
font-size: var(--text-3xl);
font-weight: var(--font-bold);
color: var(--color-primary-dark);
margin-bottom: var(--space-1);
}
.package-tokens-label {
font-size: var(--text-sm);
color: var(--color-gray-500);
margin-bottom: var(--space-4);
}
.package-price {
font-size: var(--text-2xl);
font-weight: var(--font-semibold);
color: var(--color-gray-900);
margin-bottom: var(--space-1);
}
.package-unit {
font-size: var(--text-xs);
color: var(--color-gray-400);
}
.package-savings {
display: inline-block;
margin-top: var(--space-3);
font-size: var(--text-xs);
font-weight: var(--font-medium);
color: var(--color-success);
background: var(--color-success-bg);
padding: var(--space-1) var(--space-2);
border-radius: var(--radius-full);
}
/* --- Custom Amount --- */
.custom-amount-section {
background: white;
border: 1px solid var(--color-gray-200);
border-radius: var(--radius-lg);
padding: var(--space-6);
margin-bottom: var(--space-8);
}
.custom-amount-row {
display: flex;
align-items: center;
gap: var(--space-4);
}
.custom-label {
font-size: var(--text-sm);
font-weight: var(--font-medium);
color: var(--color-gray-700);
white-space: nowrap;
}
.custom-input-wrap {
position: relative;
flex: 1;
max-width: 240px;
}
.custom-input-wrap .prefix {
position: absolute;
left: var(--space-4);
top: 50%;
transform: translateY(-50%);
color: var(--color-gray-400);
font-size: var(--text-base);
font-weight: var(--font-medium);
}
.custom-input {
width: 100%;
padding: var(--space-3) var(--space-4) var(--space-3) var(--space-8);
border: 2px solid var(--color-gray-200);
border-radius: var(--radius-md);
font-size: var(--text-base);
font-family: var(--font-family);
color: var(--color-gray-800);
transition: border-color var(--transition-fast);
}
.custom-input:focus {
outline: none;
border-color: var(--color-primary);
box-shadow: 0 0 0 3px rgba(13, 110, 110, 0.1);
}
.custom-conversion {
font-size: var(--text-sm);
color: var(--color-gray-500);
}
.custom-conversion strong {
color: var(--color-primary);
}
/* --- Order Summary --- */
.order-summary {
background: white;
border: 1px solid var(--color-gray-200);
border-radius: var(--radius-lg);
padding: var(--space-6);
margin-bottom: var(--space-8);
}
.summary-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: var(--space-3) 0;
font-size: var(--text-sm);
color: var(--color-gray-600);
}
.summary-row + .summary-row {
border-top: 1px solid var(--color-gray-100);
}
.summary-row.total {
border-top: 2px solid var(--color-gray-200);
padding-top: var(--space-4);
margin-top: var(--space-2);
font-size: var(--text-base);
font-weight: var(--font-semibold);
color: var(--color-gray-900);
}
.summary-value {
font-weight: var(--font-medium);
color: var(--color-gray-800);
}
.summary-row.total .summary-value {
font-size: var(--text-xl);
color: var(--color-primary-dark);
}
/* --- Payment Method Selector --- */
.payment-methods {
margin-bottom: var(--space-8);
}
.payment-options {
display: flex;
gap: var(--space-3);
}
.payment-option {
flex: 1;
display: flex;
align-items: center;
gap: var(--space-3);
padding: var(--space-4);
border: 2px solid var(--color-gray-200);
border-radius: var(--radius-md);
cursor: pointer;
transition: all var(--transition-fast);
background: white;
}
.payment-option:hover {
border-color: var(--color-gray-300);
}
.payment-option.selected {
border-color: var(--color-primary);
background: var(--color-primary-bg);
}
.payment-radio {
width: 20px;
height: 20px;
border: 2px solid var(--color-gray-300);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.payment-option.selected .payment-radio {
border-color: var(--color-primary);
}
.payment-radio-inner {
width: 10px;
height: 10px;
border-radius: 50%;
background: transparent;
}
.payment-option.selected .payment-radio-inner {
background: var(--color-primary);
}
.payment-details {
flex: 1;
}
.payment-name {
font-size: var(--text-sm);
font-weight: var(--font-medium);
color: var(--color-gray-800);
}
.payment-desc {
font-size: var(--text-xs);
color: var(--color-gray-400);
}
.payment-icon {
font-size: var(--text-xl);
opacity: 0.6;
}
/* --- CTA Button --- */
.cta-section {
display: flex;
align-items: center;
gap: var(--space-4);
}
.btn-purchase {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--space-2);
padding: var(--space-4) var(--space-8);
background: var(--color-primary);
color: white;
border: none;
border-radius: var(--radius-md);
font-size: var(--text-base);
font-weight: var(--font-semibold);
font-family: var(--font-family);
cursor: pointer;
transition: all var(--transition-base);
box-shadow: var(--shadow-md);
min-width: 220px;
}
.btn-purchase:hover {
background: var(--color-primary-dark);
box-shadow: var(--shadow-lg);
transform: translateY(-1px);
}
.btn-purchase:active {
transform: translateY(0);
box-shadow: var(--shadow-sm);
}
.cta-note {
font-size: var(--text-xs);
color: var(--color-gray-400);
max-width: 300px;
line-height: var(--leading-relaxed);
}
/* --- Recent Purchases Table --- */
.recent-purchases {
margin-top: var(--space-12);
}
.purchases-table {
width: 100%;
border-collapse: collapse;
background: white;
border-radius: var(--radius-lg);
overflow: hidden;
box-shadow: var(--shadow-sm);
border: 1px solid var(--color-gray-200);
}
.purchases-table th {
text-align: left;
padding: var(--space-3) var(--space-4);
font-size: var(--text-xs);
font-weight: var(--font-semibold);
color: var(--color-gray-500);
text-transform: uppercase;
letter-spacing: 0.05em;
background: var(--color-gray-50);
border-bottom: 1px solid var(--color-gray-200);
}
.purchases-table td {
padding: var(--space-3) var(--space-4);
font-size: var(--text-sm);
color: var(--color-gray-700);
border-bottom: 1px solid var(--color-gray-100);
}
.purchases-table tr:last-child td { border-bottom: none; }
.status-badge {
display: inline-block;
padding: var(--space-1) var(--space-2);
border-radius: var(--radius-full);
font-size: var(--text-xs);
font-weight: var(--font-medium);
}
.status-badge.completed {
background: var(--color-success-bg);
color: #1a9a54;
}
.status-badge.pending {
background: var(--color-warning-bg);
color: #b87d0a;
}
/* --- Annotations (design notes for devs) --- */
.annotation {
position: relative;
}
.annotation::after {
content: attr(data-note);
position: absolute;
right: -16px;
top: 0;
transform: translateX(100%);
background: #FFF3CD;
color: #856404;
font-size: 11px;
padding: 4px 8px;
border-radius: 4px;
white-space: nowrap;
pointer-events: none;
opacity: 0;
transition: opacity 0.2s;
z-index: 10;
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
}
.annotation:hover::after { opacity: 1; }
/* --- Responsive --- */
@media (max-width: 768px) {
.portal-shell { flex-direction: column; }
.sidebar { width: 100%; padding: var(--space-4) 0; }
.main-content { padding: var(--space-4); }
.packages-grid { grid-template-columns: 1fr; }
.balance-card { flex-direction: column; gap: var(--space-4); text-align: center; }
.balance-meta { text-align: center; }
.payment-options { flex-direction: column; }
.custom-amount-row { flex-direction: column; align-items: flex-start; }
.cta-section { flex-direction: column; }
}
</style>
</head>
<body>
<!-- Design Spec Banner -->
<div class="spec-banner">
<strong>📐 DESIGN SPEC — Sponsor Portal: Token Purchase</strong>
<span>Designed by Ava · 2026-03-21 · For @nora to implement</span>
</div>
<div class="portal-shell">
<!-- Sidebar -->
<nav class="sidebar">
<div class="sidebar-logo">
<h2>Payfrit</h2>
<span>Sponsor Portal</span>
</div>
<div class="nav-item">
<span class="nav-icon">📊</span> Dashboard
</div>
<div class="nav-item active">
<span class="nav-icon">🪙</span> Buy Tokens
</div>
<div class="nav-item">
<span class="nav-icon">👥</span> Members
</div>
<div class="nav-item">
<span class="nav-icon">📋</span> Transactions
</div>
<div class="nav-item">
<span class="nav-icon">📈</span> Reports
</div>
<div class="nav-item">
<span class="nav-icon">⚙️</span> Settings
</div>
</nav>
<!-- Main Content -->
<main class="main-content">
<!-- Page Header -->
<div class="page-header">
<h1>Purchase Tokens</h1>
<p>Buy tokens to distribute to your sponsored members for health services.</p>
</div>
<!-- Current Balance Card -->
<div class="balance-card">
<div>
<div class="balance-label">Current Token Balance</div>
<div class="balance-amount">12,450 <span>tokens</span></div>
</div>
<div class="balance-meta">
<div class="balance-meta-item">Last purchase: Mar 14, 2026</div>
<div class="balance-meta-item">Avg. monthly usage: ~3,200 tokens</div>
</div>
</div>
<!-- Token Packages -->
<div class="section-label">Choose a Package</div>
<div class="section-sublabel">Select a pre-set bundle or enter a custom amount below.</div>
<div class="packages-grid">
<!-- Package 1 -->
<div class="package-card">
<div class="package-tokens">1,000</div>
<div class="package-tokens-label">tokens</div>
<div class="package-price">$100</div>
<div class="package-unit">$0.10 / token</div>
</div>
<!-- Package 2 (Popular) -->
<div class="package-card popular selected">
<div class="popular-badge">Most Popular</div>
<div class="package-tokens">5,000</div>
<div class="package-tokens-label">tokens</div>
<div class="package-price">$450</div>
<div class="package-unit">$0.09 / token</div>
<div class="package-savings">Save 10%</div>
</div>
<!-- Package 3 -->
<div class="package-card">
<div class="package-tokens">15,000</div>
<div class="package-tokens-label">tokens</div>
<div class="package-price">$1,200</div>
<div class="package-unit">$0.08 / token</div>
<div class="package-savings">Save 20%</div>
</div>
</div>
<!-- Custom Amount -->
<div class="custom-amount-section">
<div class="custom-amount-row">
<span class="custom-label">Or enter custom amount:</span>
<div class="custom-input-wrap">
<span class="prefix">$</span>
<input type="text" class="custom-input" placeholder="0.00" value="">
</div>
<span class="custom-conversion"><strong>0 tokens</strong> at current rate</span>
</div>
</div>
<!-- Order Summary -->
<div class="order-summary">
<div class="section-label" style="margin-bottom: var(--space-4);">Order Summary</div>
<div class="summary-row">
<span>Token Package</span>
<span class="summary-value">5,000 tokens</span>
</div>
<div class="summary-row">
<span>Unit Price</span>
<span class="summary-value">$0.09 / token</span>
</div>
<div class="summary-row">
<span>Subtotal</span>
<span class="summary-value">$450.00</span>
</div>
<div class="summary-row">
<span>Processing Fee (2.5%)</span>
<span class="summary-value">$11.25</span>
</div>
<div class="summary-row total">
<span>Total</span>
<span class="summary-value">$461.25</span>
</div>
</div>
<!-- Payment Method -->
<div class="payment-methods">
<div class="section-label" style="margin-bottom: var(--space-4);">Payment Method</div>
<div class="payment-options">
<div class="payment-option selected">
<div class="payment-radio"><div class="payment-radio-inner"></div></div>
<div class="payment-details">
<div class="payment-name">Credit Card</div>
<div class="payment-desc">Visa ending in 4242</div>
</div>
<span class="payment-icon">💳</span>
</div>
<div class="payment-option">
<div class="payment-radio"><div class="payment-radio-inner"></div></div>
<div class="payment-details">
<div class="payment-name">Bank Transfer (ACH)</div>
<div class="payment-desc">13 business days</div>
</div>
<span class="payment-icon">🏦</span>
</div>
<div class="payment-option">
<div class="payment-radio"><div class="payment-radio-inner"></div></div>
<div class="payment-details">
<div class="payment-name">Add New Method</div>
<div class="payment-desc">Card, bank, or wire</div>
</div>
<span class="payment-icon"></span>
</div>
</div>
</div>
<!-- CTA -->
<div class="cta-section">
<button class="btn-purchase">
🔒 Purchase 5,000 Tokens — $461.25
</button>
<span class="cta-note">Tokens are non-refundable and will be credited to your account immediately. Secure payment powered by Stripe.</span>
</div>
<!-- Recent Purchases -->
<div class="recent-purchases">
<div class="section-label" style="margin-bottom: var(--space-4);">Recent Purchases</div>
<table class="purchases-table">
<thead>
<tr>
<th>Date</th>
<th>Tokens</th>
<th>Amount</th>
<th>Method</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mar 14, 2026</td>
<td>5,000</td>
<td>$461.25</td>
<td>Visa ••4242</td>
<td><span class="status-badge completed">Completed</span></td>
</tr>
<tr>
<td>Feb 28, 2026</td>
<td>1,000</td>
<td>$102.50</td>
<td>ACH Transfer</td>
<td><span class="status-badge completed">Completed</span></td>
</tr>
<tr>
<td>Feb 10, 2026</td>
<td>15,000</td>
<td>$1,230.00</td>
<td>Visa ••4242</td>
<td><span class="status-badge completed">Completed</span></td>
</tr>
<tr>
<td>Jan 22, 2026</td>
<td>5,000</td>
<td>$461.25</td>
<td>Wire Transfer</td>
<td><span class="status-badge completed">Completed</span></td>
</tr>
</tbody>
</table>
</div>
</main>
</div>
</body>
</html>