Initial commit: Kalei app — docs, mockups, logo, pitch deck

Complete project files including:
- 73 polished HTML mockup screens (onboarding, turn, mirror, lens, gallery, you, ritual, spectrum, modals, guide)
- Design system CSS with Inter font, jewel-tone palette, device frame scaling
- Canonical 6-blade kaleidoscope logo (soft-elegance-final)
- SVG asset library (fragments, icons, patterns, evidence wall, spectrum viz)
- Product docs, brand guidelines, technical architecture, build phases
- Pitch deck and cost projections
- Logo mockup iterations and finalists

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-22 14:55:22 +01:00
commit 38021c4633
168 changed files with 46724 additions and 0 deletions

View File

@@ -0,0 +1,334 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=390, initial-scale=1">
<title>Kalei — Upgrade to Prism</title>
<link rel="stylesheet" href="../../assets/design-system.css">
<style>
.bg-screen {
position: absolute;
inset: 0;
background: var(--void);
}
/* Blurred background context (Turn Home) */
.bg-content {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
padding: 54px 16px 16px;
filter: blur(3px);
opacity: 0.4;
}
.bg-greeting {
font-size: 22px;
font-weight: 600;
color: var(--pure-light);
margin-top: 16px;
}
.bg-card {
height: 80px;
background: var(--deep-glass);
border: 1px solid var(--twilight);
border-radius: var(--radius-xl);
margin-top: 20px;
}
.modal-overlay {
position: absolute;
inset: 0;
background: rgba(5,5,8,0.75);
backdrop-filter: blur(10px);
display: flex;
align-items: center;
justify-content: center;
z-index: 50;
}
.modal-card {
width: 340px;
background: var(--kalei-navy);
border-radius: var(--radius-2xl);
padding: var(--space-6);
position: relative;
overflow: hidden;
animation: modalSlideIn 0.35s ease-out forwards;
}
@keyframes modalSlideIn {
from { opacity: 0; transform: translateY(12px) scale(0.97); }
to { opacity: 1; transform: translateY(0) scale(1); }
}
/* Prismatic border */
.modal-card::before {
content: '';
position: absolute;
inset: 0;
border-radius: var(--radius-2xl);
padding: 1.5px;
background: linear-gradient(135deg, #8B5CF6, #3B82F6, #10B981, #F59E0B, #EC4899);
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
}
.modal-header {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 20px;
}
.modal-logo {
margin-bottom: 14px;
}
.modal-title {
font-size: 22px;
font-weight: 700;
font-family: var(--font-display);
text-align: center;
background: linear-gradient(135deg, #C4B5FD, #93C5FD, #6EE7B7);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.modal-subtitle {
font-size: 14px;
color: var(--dim-light);
text-align: center;
margin-top: 6px;
}
.benefits-list {
margin-bottom: 20px;
}
.benefit-item {
display: flex;
align-items: flex-start;
gap: 10px;
padding: 8px 0;
}
.benefit-icon {
width: 24px;
height: 24px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
margin-top: 1px;
}
.benefit-text {
flex: 1;
}
.benefit-title {
font-size: 14px;
font-weight: 600;
color: var(--pure-light);
}
.benefit-desc {
font-size: 12px;
color: var(--dim-light);
margin-top: 1px;
}
.price-row {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
margin-bottom: 18px;
padding: 12px;
background: rgba(139,92,246,0.06);
border-radius: var(--radius-lg);
border: 1px solid rgba(139,92,246,0.15);
}
.price-val {
font-size: 28px;
font-weight: 700;
font-family: var(--font-display);
background: linear-gradient(135deg, #C4B5FD, #93C5FD, #6EE7B7, #FDE68A, #F9A8D4);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.price-period {
font-size: 13px;
color: var(--dim-light);
}
.btn-prismatic {
width: 100%;
height: 52px;
border: none;
border-radius: var(--radius-lg);
background: linear-gradient(135deg, #8B5CF6, #3B82F6, #10B981);
color: white;
font-size: 16px;
font-weight: 600;
font-family: var(--font-primary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
text-decoration: none;
margin-bottom: 10px;
box-shadow: 0 0 24px rgba(139,92,246,0.3);
transition: opacity 0.2s;
}
.btn-prismatic:hover { opacity: 0.9; }
.maybe-later {
width: 100%;
height: 40px;
background: transparent;
border: none;
color: var(--dim-light);
font-size: 14px;
font-family: var(--font-primary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
text-decoration: none;
transition: color 0.2s;
}
.maybe-later:hover { color: var(--soft-light); }
.trial-note {
font-size: 11px;
color: var(--faint-light);
text-align: center;
margin-top: 6px;
}
</style>
</head>
<body>
<div class="device-frame">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<rect x="1" y="7" width="2.5" height="5" rx="0.5" fill="#E2E8F0" opacity="0.4"/>
<rect x="4.5" y="5" width="2.5" height="7" rx="0.5" fill="#E2E8F0" opacity="0.6"/>
<rect x="8" y="3" width="2.5" height="9" rx="0.5" fill="#E2E8F0" opacity="0.8"/>
<rect x="11.5" y="1" width="2.5" height="11" rx="0.5" fill="#E2E8F0"/>
</svg>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M 2,8 C 4,4 12,4 14,8" stroke="#E2E8F0" stroke-width="1.2" fill="none" stroke-linecap="round"/>
<path d="M 4,10 C 6,7 10,7 12,10" stroke="#E2E8F0" stroke-width="1" fill="none" opacity="0.8" stroke-linecap="round"/>
<circle cx="8" cy="12" r="1.2" fill="#E2E8F0"/>
</svg>
<svg width="24" height="12" viewBox="0 0 24 12" fill="none">
<rect x="0.5" y="0.5" width="21" height="11" rx="2.5" stroke="#E2E8F0" stroke-width="1" opacity="0.5"/>
<rect x="22" y="3" width="2" height="6" rx="1" fill="#E2E8F0" opacity="0.3"/>
<rect x="2" y="2" width="16" height="8" rx="1.5" fill="#10B981" opacity="0.9"/>
</svg>
</div>
</div>
<!-- Blurred background -->
<div class="bg-content" aria-hidden="true">
<div class="bg-greeting">Good morning, Alex</div>
<div class="bg-card" style="margin-top:16px;"></div>
<div class="bg-card" style="margin-top:10px; height:60px;"></div>
</div>
<!-- Modal overlay -->
<div class="modal-overlay">
<div class="modal-card">
<!-- Kaleidoscope logo -->
<div class="modal-header">
<div class="modal-logo">
<svg width="56" height="56" viewBox="0 0 56 56" style="mix-blend-mode: normal;">
<defs>
<linearGradient id="upBlade1" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#C4B5FD" stop-opacity="0.9"/>
<stop offset="100%" stop-color="#7C3AED" stop-opacity="0.4"/>
</linearGradient>
<linearGradient id="upBlade2" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#93C5FD" stop-opacity="0.8"/>
<stop offset="100%" stop-color="#2563EB" stop-opacity="0.3"/>
</linearGradient>
<linearGradient id="upBlade3" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#6EE7B7" stop-opacity="0.8"/>
<stop offset="100%" stop-color="#059669" stop-opacity="0.3"/>
</linearGradient>
</defs>
<g transform="translate(28,28)" style="animation: breathing 6s ease-in-out infinite;">
<g><path d="M0,0 L4,-20 L0,-24 L-4,-20Z" fill="url(#upBlade1)"/></g>
<g transform="rotate(60)"><path d="M0,0 L4,-20 L0,-24 L-4,-20Z" fill="url(#upBlade2)"/></g>
<g transform="rotate(120)"><path d="M0,0 L4,-20 L0,-24 L-4,-20Z" fill="url(#upBlade3)"/></g>
<g transform="rotate(180)"><path d="M0,0 L4,-20 L0,-24 L-4,-20Z" fill="url(#upBlade1)"/></g>
<g transform="rotate(240)"><path d="M0,0 L4,-20 L0,-24 L-4,-20Z" fill="url(#upBlade2)"/></g>
<g transform="rotate(300)"><path d="M0,0 L4,-20 L0,-24 L-4,-20Z" fill="url(#upBlade3)"/></g>
<circle r="5" fill="white" opacity="0.15"/>
</g>
</svg>
</div>
<div class="modal-title">Unlock Kalei Plus</div>
<div class="modal-subtitle">More turns. More insight. Same intention.</div>
</div>
<!-- Benefits — grounded, not pushy -->
<div class="benefits-list">
<div class="benefit-item">
<div class="benefit-icon" style="background: rgba(139,92,246,0.15);">
<svg width="14" height="14" viewBox="0 0 14 14">
<path d="M7 1L13 7L7 13L1 7Z" fill="#C4B5FD" opacity="0.9"/>
</svg>
</div>
<div class="benefit-text">
<div class="benefit-title">10 Turns per day</div>
<div class="benefit-desc">From 3 free → 10 per day. Enough for real-time reframing</div>
</div>
</div>
<div class="benefit-item">
<div class="benefit-icon" style="background: rgba(59,130,246,0.12);">
<svg width="14" height="14" viewBox="0 0 14 14">
<path d="M7 1L13 7L7 13L1 7Z" fill="#93C5FD" opacity="0.9"/>
</svg>
</div>
<div class="benefit-text">
<div class="benefit-title">Full Spectrum Access</div>
<div class="benefit-desc">The River, Your Glass, Rhythm, Growth — all views unlocked</div>
</div>
</div>
<div class="benefit-item">
<div class="benefit-icon" style="background: rgba(16,185,129,0.12);">
<svg width="14" height="14" viewBox="0 0 14 14">
<path d="M7 1L13 7L7 13L1 7Z" fill="#6EE7B7" opacity="0.9"/>
</svg>
</div>
<div class="benefit-text">
<div class="benefit-title">Weekly &amp; Monthly Reports</div>
<div class="benefit-desc">AI-written summaries with specific pattern trends and dates</div>
</div>
</div>
</div>
<!-- Tier price row -->
<div class="price-row">
<div class="price-val">$9.99</div>
<div class="price-period">/ month</div>
</div>
<!-- Tier note -->
<div style="display:flex; justify-content:center; gap:18px; margin-bottom:14px;">
<div style="text-align:center;">
<div style="font-size:10px; color:var(--faint-light); text-transform:uppercase; letter-spacing:0.06em; margin-bottom:3px;">Free</div>
<div style="font-size:12px; color:var(--dim-light);">3 turns/day</div>
</div>
<div style="text-align:center; position:relative;">
<div style="font-size:10px; color:var(--amethyst-light); text-transform:uppercase; letter-spacing:0.06em; margin-bottom:3px; font-weight:600;">Plus</div>
<div style="font-size:12px; color:var(--soft-light); font-weight:600;">10 turns/day</div>
</div>
<div style="text-align:center;">
<div style="font-size:10px; color:var(--faint-light); text-transform:uppercase; letter-spacing:0.06em; margin-bottom:3px;">Pro</div>
<div style="font-size:12px; color:var(--dim-light);">Unlimited</div>
</div>
</div>
<!-- CTA -->
<a class="btn-prismatic" href="../you/38-you-subscription.html">Try Plus free for 7 days</a>
<div class="trial-note">7 days free, then $9.99/month. Cancel anytime. Pro available at $19.99/month.</div>
<a class="maybe-later" href="../turn/10-turn-home.html">Maybe later</a>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,312 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=390, initial-scale=1">
<title>Kalei — Rate Limit</title>
<link rel="stylesheet" href="../../assets/design-system.css">
<style>
.bg-content {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
filter: blur(2px);
opacity: 0.35;
}
.bg-status {
height: 54px;
padding: 14px 28px 0;
display: flex;
justify-content: space-between;
align-items: center;
}
.bg-time { font-size: 15px; font-weight: 600; color: var(--pure-light); }
.bg-header {
padding: 16px;
font-size: 22px;
font-weight: 600;
color: var(--pure-light);
}
.bg-input {
margin: 0 16px;
height: 120px;
background: var(--deep-glass);
border: 1px solid var(--twilight);
border-radius: var(--radius-xl);
}
.bg-cards {
margin: 16px;
display: flex;
flex-direction: column;
gap: 10px;
}
.bg-mini-card {
height: 60px;
background: var(--kalei-navy);
border: 1px solid var(--twilight);
border-radius: var(--radius-lg);
}
.limit-overlay {
position: absolute;
inset: 0;
background: rgba(5,5,8,0.65);
backdrop-filter: blur(8px);
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
z-index: 50;
}
.limit-card {
width: 100%;
background: var(--kalei-navy);
border: 1px solid rgba(139,92,246,0.2);
border-radius: var(--radius-2xl);
padding: 24px;
box-shadow: 0 0 40px rgba(0,0,0,0.5), 0 0 60px rgba(139,92,246,0.08);
animation: modalSlideIn 0.3s ease-out forwards;
}
@keyframes modalSlideIn {
from { opacity: 0; transform: translateY(8px); }
to { opacity: 1; transform: translateY(0); }
}
.limit-icon {
width: 52px;
height: 52px;
border-radius: 50%;
background: rgba(139,92,246,0.12);
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 14px;
}
.limit-title {
font-size: 18px;
font-weight: 700;
color: var(--pure-light);
text-align: center;
margin-bottom: 6px;
}
.limit-subtitle {
font-size: 13px;
color: var(--dim-light);
text-align: center;
margin-bottom: 18px;
}
.progress-section {
margin-bottom: 18px;
}
.progress-label {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
}
.progress-label-text {
font-size: 12px;
color: var(--dim-light);
}
.progress-label-count {
font-size: 12px;
font-weight: 600;
color: var(--pure-light);
}
.progress-bar-bg {
height: 8px;
background: var(--twilight);
border-radius: var(--radius-full);
overflow: hidden;
}
.progress-bar-fill {
height: 100%;
border-radius: var(--radius-full);
background: linear-gradient(90deg, var(--amethyst), var(--ruby));
width: 100%;
}
.turn-dots {
display: flex;
gap: 8px;
justify-content: center;
margin-top: 10px;
}
.turn-dot {
width: 32px;
height: 32px;
border-radius: 50%;
background: rgba(139,92,246,0.3);
border: 2px solid var(--amethyst);
display: flex;
align-items: center;
justify-content: center;
}
.turn-dot.used {
background: var(--amethyst);
opacity: 0.7;
}
.upgrade-prompt {
background: rgba(139,92,246,0.06);
border: 1px solid rgba(139,92,246,0.2);
border-radius: var(--radius-lg);
padding: 12px;
margin-bottom: 16px;
text-align: center;
}
.upgrade-prompt-text {
font-size: 13px;
color: var(--soft-light);
}
.upgrade-prompt-link {
font-size: 13px;
font-weight: 600;
color: var(--amethyst-light);
}
.timer-row {
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
margin-bottom: 16px;
font-size: 13px;
color: var(--dim-light);
}
.timer-val {
font-size: 14px;
font-weight: 600;
color: var(--soft-light);
font-variant-numeric: tabular-nums;
}
.btn-prismatic {
width: 100%;
height: 48px;
border: none;
border-radius: var(--radius-lg);
background: linear-gradient(135deg, #8B5CF6, #3B82F6);
color: white;
font-size: 15px;
font-weight: 600;
font-family: var(--font-primary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
text-decoration: none;
margin-bottom: 10px;
box-shadow: 0 0 20px rgba(139,92,246,0.25);
}
.dismiss-btn {
width: 100%;
height: 40px;
background: transparent;
border: none;
color: var(--dim-light);
font-size: 14px;
font-family: var(--font-primary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
text-decoration: none;
}
</style>
</head>
<body>
<div class="device-frame">
<!-- Blurred Turn Home context -->
<div class="bg-content" aria-hidden="true">
<div class="bg-status">
<span class="bg-time">9:41</span>
</div>
<div class="bg-header">Good morning, Alex</div>
<div class="bg-input"></div>
<div class="bg-cards">
<div class="bg-mini-card"></div>
<div class="bg-mini-card"></div>
</div>
</div>
<!-- Rate limit overlay -->
<div class="limit-overlay">
<div class="limit-card">
<div class="limit-icon">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
<path d="M12 2L22 12L12 22L2 12Z" fill="#8B5CF6" opacity="0.6"/>
<path d="M12 8V12M12 16H12.01" stroke="#C4B5FD" stroke-width="1.5" stroke-linecap="round"/>
</svg>
</div>
<div class="limit-title">That's your 3 for today</div>
<div class="limit-subtitle">Good work showing up. Your next turns reset at midnight.</div>
<!-- Progress -->
<div class="progress-section">
<div class="progress-label">
<span class="progress-label-text">Daily usage</span>
<span class="progress-label-count">3 / 3</span>
</div>
<div class="progress-bar-bg">
<div class="progress-bar-fill"></div>
</div>
<div class="turn-dots">
<div class="turn-dot used">
<svg width="12" height="12" viewBox="0 0 12 12">
<path d="M6 1L11 6L6 11L1 6Z" fill="#fff" opacity="0.8"/>
</svg>
</div>
<div class="turn-dot used">
<svg width="12" height="12" viewBox="0 0 12 12">
<path d="M6 1L11 6L6 11L1 6Z" fill="#fff" opacity="0.8"/>
</svg>
</div>
<div class="turn-dot used">
<svg width="12" height="12" viewBox="0 0 12 12">
<path d="M6 1L11 6L6 11L1 6Z" fill="#fff" opacity="0.8"/>
</svg>
</div>
</div>
</div>
<!-- Upgrade prompt — calm, not pushy -->
<div class="upgrade-prompt">
<span class="upgrade-prompt-text">Plus gives you </span>
<span class="upgrade-prompt-text" style="font-weight:600; color: var(--pure-light);">10 turns per day</span>
<span class="upgrade-prompt-text"> — enough for real-time reframing</span>
</div>
<!-- Timer -->
<div class="timer-row">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none">
<circle cx="7" cy="8" r="5" stroke="#94A3B8" stroke-width="1.2"/>
<path d="M7 5V8L9 9" stroke="#94A3B8" stroke-width="1.2" stroke-linecap="round"/>
<path d="M5 1H9" stroke="#94A3B8" stroke-width="1.2" stroke-linecap="round"/>
</svg>
Resets in <span class="timer-val" id="timer">18:23:47</span>
</div>
<!-- Upgrade CTA -->
<a class="btn-prismatic" href="58-upgrade-modal.html">
See Plus — from $9.99/mo
</a>
<a class="dismiss-btn" href="../turn/10-turn-home.html">Got it, see you tomorrow</a>
</div>
</div>
</div>
<script>
// Countdown timer simulation
let seconds = 18 * 3600 + 23 * 60 + 47;
const timerEl = document.getElementById('timer');
function updateTimer() {
if (seconds <= 0) return;
seconds--;
const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds % 3600) / 60);
const s = seconds % 60;
timerEl.textContent = `${String(h).padStart(2,'0')}:${String(m).padStart(2,'0')}:${String(s).padStart(2,'0')}`;
}
setInterval(updateTimer, 1000);
</script>
</body>
</html>

View File

@@ -0,0 +1,274 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=390, initial-scale=1">
<title>Kalei — Crisis Response</title>
<link rel="stylesheet" href="../../assets/design-system.css">
<style>
.device-frame {
background: var(--void);
}
.screen-content {
display: flex;
flex-direction: column;
padding: 0 20px 24px;
}
.hero-section {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 24px;
padding-bottom: 20px;
}
.ruby-aura {
position: absolute;
top: 80px;
left: 50%;
transform: translateX(-50%);
width: 240px;
height: 240px;
border-radius: 50%;
background: radial-gradient(circle, rgba(239,68,68,0.12) 0%, transparent 70%);
filter: blur(40px);
animation: breathing 6s ease-in-out infinite;
pointer-events: none;
z-index: 0;
}
.hero-icon {
width: 72px;
height: 72px;
border-radius: 50%;
background: rgba(239,68,68,0.12);
border: 2px solid rgba(239,68,68,0.3);
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 16px;
position: relative;
z-index: 1;
animation: breathing 6s ease-in-out infinite;
}
.hero-title {
font-size: 26px;
font-weight: 700;
font-family: var(--font-display);
color: var(--ruby);
text-align: center;
margin-bottom: 8px;
position: relative;
z-index: 1;
}
.hero-subtitle {
font-size: 15px;
color: var(--dim-light);
text-align: center;
line-height: 1.5;
position: relative;
z-index: 1;
}
.resources-section {
margin-bottom: 16px;
}
.resource-card {
background: var(--kalei-navy);
border: 1px solid rgba(239,68,68,0.2);
border-radius: var(--radius-xl);
padding: 16px;
margin-bottom: 10px;
}
.resource-header {
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 4px;
}
.resource-icon {
width: 36px;
height: 36px;
border-radius: 50%;
background: rgba(239,68,68,0.12);
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.resource-name {
font-size: 15px;
font-weight: 600;
color: var(--pure-light);
}
.resource-detail {
font-size: 13px;
color: var(--dim-light);
margin-top: 2px;
margin-left: 48px;
}
.divider { height: 1px; background: rgba(239,68,68,0.1); margin: 8px 0; }
.btn-ruby {
width: 100%;
height: 52px;
border: none;
border-radius: var(--radius-lg);
background: var(--ruby);
color: white;
font-size: 16px;
font-weight: 600;
font-family: var(--font-primary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
text-decoration: none;
margin-bottom: 10px;
box-shadow: 0 0 20px rgba(239,68,68,0.3);
transition: background 0.2s;
}
.btn-ruby:hover { background: var(--ruby); filter: brightness(0.85); }
.btn-okay {
width: 100%;
height: 44px;
background: var(--deep-glass);
border: 1px solid var(--twilight);
border-radius: var(--radius-lg);
color: var(--soft-light);
font-size: 15px;
font-weight: 500;
font-family: var(--font-primary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
text-decoration: none;
margin-bottom: 10px;
transition: background 0.2s;
}
.btn-okay:hover { background: var(--twilight); }
.breathing-link {
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
font-size: 13px;
color: var(--dim-light);
text-decoration: none;
padding: 8px;
transition: color 0.2s;
}
.breathing-link:hover { color: var(--soft-light); }
.safe-note {
font-size: 11px;
color: var(--faint-light);
text-align: center;
line-height: 1.5;
margin-top: 4px;
}
</style>
</head>
<body>
<div class="device-frame">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<rect x="1" y="7" width="2.5" height="5" rx="0.5" fill="#E2E8F0" opacity="0.4"/>
<rect x="4.5" y="5" width="2.5" height="7" rx="0.5" fill="#E2E8F0" opacity="0.6"/>
<rect x="8" y="3" width="2.5" height="9" rx="0.5" fill="#E2E8F0" opacity="0.8"/>
<rect x="11.5" y="1" width="2.5" height="11" rx="0.5" fill="#E2E8F0"/>
</svg>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
<path d="M 2,8 C 4,4 12,4 14,8" stroke="#E2E8F0" stroke-width="1.2" fill="none" stroke-linecap="round"/>
<path d="M 4,10 C 6,7 10,7 12,10" stroke="#E2E8F0" stroke-width="1" fill="none" opacity="0.8" stroke-linecap="round"/>
<circle cx="8" cy="12" r="1.2" fill="#E2E8F0"/>
</svg>
<svg width="24" height="12" viewBox="0 0 24 12" fill="none">
<rect x="0.5" y="0.5" width="21" height="11" rx="2.5" stroke="#E2E8F0" stroke-width="1" opacity="0.5"/>
<rect x="22" y="3" width="2" height="6" rx="1" fill="#E2E8F0" opacity="0.3"/>
<rect x="2" y="2" width="16" height="8" rx="1.5" fill="#10B981" opacity="0.9"/>
</svg>
</div>
</div>
<div class="ruby-aura"></div>
<div class="screen-content">
<!-- Hero -->
<div class="hero-section">
<div class="hero-icon">
<svg width="32" height="32" viewBox="0 0 32 32" fill="none">
<path d="M16 4L28 16L16 28L4 16Z" fill="#EF4444" opacity="0.3"/>
<path d="M16 8L24 16L16 24L8 16Z" fill="#EF4444" opacity="0.5"/>
<!-- Heart shape -->
<path d="M11 13.5C11 12.1 12.1 11 13.5 11C14.3 11 15 11.4 15.5 12C16 11.4 16.7 11 17.5 11C18.9 11 20 12.1 20 13.5C20 16 15.5 20 15.5 20C15.5 20 11 16 11 13.5Z" fill="#FCA5A5" opacity="0.9"/>
</svg>
</div>
<div class="hero-title">You're not alone in this</div>
<div class="hero-subtitle">Whatever you're carrying right now — it's real, and it matters. You don't have to face it alone. Trained people are ready to listen, right now, any hour.</div>
</div>
<!-- Crisis resources -->
<div class="resources-section">
<!-- 988 Lifeline -->
<div class="resource-card">
<div class="resource-header">
<div class="resource-icon">
<svg width="18" height="18" viewBox="0 0 18 18" fill="none">
<rect x="3" y="3" width="12" height="12" rx="2" stroke="#EF4444" stroke-width="1.2"/>
<path d="M6 7C6 7 7.5 6 9 7C10.5 8 12 7 12 7" stroke="#EF4444" stroke-width="1" stroke-linecap="round"/>
<path d="M6 10.5C7.5 12 10.5 12 12 10.5" stroke="#EF4444" stroke-width="1" stroke-linecap="round"/>
<circle cx="7" cy="9" r="0.8" fill="#EF4444"/>
<circle cx="11" cy="9" r="0.8" fill="#EF4444"/>
</svg>
</div>
<div class="resource-name">988 Suicide &amp; Crisis Lifeline</div>
</div>
<div class="resource-detail">Call or text 988 — free, confidential, 24/7</div>
</div>
<!-- Crisis Text Line -->
<div class="resource-card">
<div class="resource-header">
<div class="resource-icon">
<svg width="18" height="18" viewBox="0 0 18 18" fill="none">
<rect x="2" y="4" width="14" height="10" rx="2" stroke="#EF4444" stroke-width="1.2"/>
<path d="M6 14L4 16" stroke="#EF4444" stroke-width="1.2" stroke-linecap="round"/>
<path d="M5 8H13M5 11H10" stroke="#EF4444" stroke-width="1" stroke-linecap="round"/>
</svg>
</div>
<div class="resource-name">Crisis Text Line</div>
</div>
<div class="resource-detail">Text HOME to 741741 — text-based support, 24/7</div>
</div>
</div>
<!-- Primary CTA: Call or text 988 -->
<a class="btn-ruby" href="tel:988">
<svg width="18" height="18" viewBox="0 0 18 18" fill="none">
<path d="M6.5 3.5C6.5 3.5 5 3 3.5 5S3 9 5.5 11.5S10 15 12.5 14.5S15.5 13.5 15.5 12L13 10.5C13 10.5 12 10 11 11C10 12 9.5 11.5 7.5 9.5S7 7 8 6L6.5 3.5Z" fill="white" opacity="0.9"/>
</svg>
Call or text 988 — free, 24/7
</a>
<!-- Secondary: I'm okay -->
<a class="btn-okay" href="../turn/10-turn-home.html">
I'm okay right now
</a>
<!-- Breathing exercise link -->
<a class="breathing-link" href="../ritual/47-ritual-quick.html">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none">
<circle cx="7" cy="7" r="5" stroke="#94A3B8" stroke-width="1.2" stroke-dasharray="2 2"/>
<circle cx="7" cy="7" r="2" fill="#94A3B8" opacity="0.5"/>
</svg>
Try a grounding exercise instead
</a>
<div class="safe-note">
If you or someone else is in immediate danger, call 911.<br>
Kalei is a support tool, not a substitute for emergency care.
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,339 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=390, initial-scale=1">
<title>Kalei — Share Pattern</title>
<link rel="stylesheet" href="../../assets/design-system.css">
<style>
/* Blurred gallery background */
.bg-content {
position: absolute;
inset: 0;
display: flex;
flex-direction: column;
filter: blur(3px);
opacity: 0.35;
}
.bg-status {
height: 54px;
padding: 14px 28px 0;
display: flex;
justify-content: space-between;
}
.bg-header {
height: 56px;
background: rgba(28,34,64,0.3);
}
.bg-pattern-card {
margin: 16px;
height: 260px;
background: var(--kalei-navy);
border: 1px solid var(--twilight);
border-radius: var(--radius-2xl);
}
.modal-overlay {
position: absolute;
inset: 0;
background: rgba(5,5,8,0.7);
backdrop-filter: blur(8px);
display: flex;
align-items: flex-end;
z-index: 50;
}
.share-sheet {
width: 100%;
background: var(--kalei-navy);
border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
padding: 0 0 32px;
border-top: 1px solid var(--twilight);
}
.sheet-handle {
width: 36px;
height: 4px;
background: var(--twilight);
border-radius: var(--radius-full);
margin: 14px auto 18px;
}
.sheet-title {
font-size: 16px;
font-weight: 600;
color: var(--pure-light);
text-align: center;
margin-bottom: 18px;
}
/* Pattern card preview */
.pattern-preview {
margin: 0 16px 20px;
background: var(--void);
border-radius: var(--radius-xl);
border: 1px solid var(--twilight);
overflow: hidden;
}
.pattern-visual-area {
height: 120px;
display: flex;
align-items: center;
justify-content: center;
background: var(--void);
position: relative;
}
.pattern-aura {
position: absolute;
width: 120px;
height: 120px;
border-radius: 50%;
background: radial-gradient(circle, rgba(139,92,246,0.15) 0%, transparent 70%);
filter: blur(30px);
animation: breathing 6s ease-in-out infinite;
}
.pattern-content-area {
padding: 12px 14px;
border-top: 1px solid var(--twilight);
}
.pattern-thought {
font-size: 13px;
color: var(--soft-light);
line-height: 1.4;
margin-bottom: 6px;
font-style: italic;
}
.pattern-reframe {
font-size: 12px;
color: var(--amethyst-light);
margin-bottom: 8px;
}
.pattern-branding {
display: flex;
align-items: center;
gap: 6px;
}
.branding-logo {
width: 16px;
height: 16px;
}
.branding-text {
font-size: 10px;
font-weight: 600;
color: var(--faint-light);
letter-spacing: 0.04em;
}
/* Share targets */
.share-targets {
display: flex;
justify-content: space-around;
padding: 0 20px;
margin-bottom: 16px;
}
.share-target {
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
cursor: pointer;
background: transparent;
border: none;
padding: 8px;
border-radius: var(--radius-lg);
transition: background 0.15s;
text-decoration: none;
}
.share-target:hover { background: rgba(28,34,64,0.5); }
.share-target-icon {
width: 52px;
height: 52px;
border-radius: 14px;
background: var(--deep-glass);
border: 1px solid var(--twilight);
display: flex;
align-items: center;
justify-content: center;
}
.share-target-label {
font-size: 11px;
color: var(--dim-light);
font-family: var(--font-primary);
}
.close-row {
padding: 0 16px;
}
.close-btn {
width: 100%;
height: 48px;
background: var(--deep-glass);
border: 1px solid var(--twilight);
border-radius: var(--radius-lg);
color: var(--soft-light);
font-size: 15px;
font-weight: 500;
font-family: var(--font-primary);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
text-decoration: none;
transition: background 0.15s;
}
.close-btn:hover { background: var(--twilight); }
.copied-toast {
position: absolute;
bottom: 320px;
left: 50%;
transform: translateX(-50%);
background: var(--deep-glass);
border: 1px solid var(--emerald);
border-radius: var(--radius-full);
padding: 8px 20px;
display: flex;
align-items: center;
gap: 8px;
box-shadow: 0 0 16px rgba(16,185,129,0.2);
opacity: 0;
transition: opacity 0.3s;
pointer-events: none;
white-space: nowrap;
z-index: 60;
}
.copied-toast.visible { opacity: 1; }
</style>
</head>
<body>
<div class="device-frame">
<!-- Blurred gallery background -->
<div class="bg-content" aria-hidden="true">
<div class="bg-status">
<span style="font-size:15px; font-weight:600; color:var(--pure-light);">9:41</span>
</div>
<div class="bg-header"></div>
<div class="bg-pattern-card"></div>
</div>
<!-- Copied toast -->
<div class="copied-toast" id="copiedToast">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none">
<path d="M2 7L5.5 10.5L12 3" stroke="#10B981" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<span style="font-size:13px; color:var(--soft-light); font-weight:500;">Link copied</span>
</div>
<!-- Share sheet modal -->
<div class="modal-overlay">
<div class="share-sheet">
<div class="sheet-handle"></div>
<div class="sheet-title">Share Pattern</div>
<!-- Pattern card preview -->
<div class="pattern-preview">
<div class="pattern-visual-area">
<div class="pattern-aura"></div>
<svg width="100" height="100" viewBox="0 0 100 100" style="mix-blend-mode: screen; position:relative; z-index:1;">
<defs>
<linearGradient id="sb1" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#C4B5FD" stop-opacity="0.8"/>
<stop offset="100%" stop-color="#7C3AED" stop-opacity="0.3"/>
</linearGradient>
<linearGradient id="sb2" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#6EE7B7" stop-opacity="0.7"/>
<stop offset="100%" stop-color="#059669" stop-opacity="0.2"/>
</linearGradient>
<linearGradient id="sb3" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#FDE68A" stop-opacity="0.6"/>
<stop offset="100%" stop-color="#D97706" stop-opacity="0.2"/>
</linearGradient>
</defs>
<g transform="translate(50,50)">
<g><path d="M0,0 L6,-32 L0,-38 L-6,-32Z" fill="url(#sb1)"/></g>
<g transform="rotate(60)"><path d="M0,0 L6,-32 L0,-38 L-6,-32Z" fill="url(#sb2)"/></g>
<g transform="rotate(120)"><path d="M0,0 L6,-32 L0,-38 L-6,-32Z" fill="url(#sb3)"/></g>
<g transform="rotate(180)"><path d="M0,0 L6,-32 L0,-38 L-6,-32Z" fill="url(#sb1)"/></g>
<g transform="rotate(240)"><path d="M0,0 L6,-32 L0,-38 L-6,-32Z" fill="url(#sb2)"/></g>
<g transform="rotate(300)"><path d="M0,0 L6,-32 L0,-38 L-6,-32Z" fill="url(#sb3)"/></g>
<circle r="8" fill="white" opacity="0.12"/>
</g>
</svg>
</div>
<div class="pattern-content-area">
<div class="pattern-thought">"I completely bombed my presentation today..."</div>
<div class="pattern-reframe">One hard moment doesn't define the arc. What's one thing you learned that you couldn't have without this?</div>
<div style="display:flex; align-items:center; justify-content:space-between; margin-bottom:6px;">
<span style="font-size:10px; color:var(--faint-light);">Feb 22, 2026 · Catastrophizing</span>
<span style="font-size:10px; color:var(--emerald-light); font-weight:600;">+52% lift</span>
</div>
<div class="pattern-branding">
<svg class="branding-logo" width="16" height="16" viewBox="0 0 16 16">
<g transform="translate(8,8)">
<path d="M0,0 L2,-6 L0,-8 L-2,-6Z" fill="#8B5CF6" opacity="0.7"/>
<path d="M0,0 L2,-6 L0,-8 L-2,-6Z" fill="#3B82F6" opacity="0.5" transform="rotate(120)"/>
<path d="M0,0 L2,-6 L0,-8 L-2,-6Z" fill="#10B981" opacity="0.5" transform="rotate(240)"/>
</g>
</svg>
<span class="branding-text">Made with Kalei</span>
</div>
</div>
</div>
<!-- Share targets -->
<div class="share-targets">
<button class="share-target" onclick="copyLink()">
<div class="share-target-icon">
<svg width="22" height="22" viewBox="0 0 22 22" fill="none">
<path d="M9 13L13 9M8 10L6 12C5 13 5 15 6 16C7 17 9 17 10 16L12 14" stroke="#E2E8F0" stroke-width="1.4" stroke-linecap="round"/>
<path d="M14 12L16 10C17 9 17 7 16 6C15 5 13 5 12 6L10 8" stroke="#E2E8F0" stroke-width="1.4" stroke-linecap="round"/>
</svg>
</div>
<span class="share-target-label">Copy Link</span>
</button>
<button class="share-target" onclick="shareMessages()">
<div class="share-target-icon">
<svg width="22" height="22" viewBox="0 0 22 22" fill="none">
<rect x="3" y="5" width="16" height="12" rx="3" stroke="#E2E8F0" stroke-width="1.4"/>
<path d="M3 17L7 14" stroke="#E2E8F0" stroke-width="1.4" stroke-linecap="round"/>
<path d="M7 10H15M7 13H12" stroke="#E2E8F0" stroke-width="1" stroke-linecap="round"/>
</svg>
</div>
<span class="share-target-label">Messages</span>
</button>
<button class="share-target" onclick="shareMore()">
<div class="share-target-icon">
<svg width="22" height="22" viewBox="0 0 22 22" fill="none">
<circle cx="7" cy="11" r="1.5" fill="#E2E8F0"/>
<circle cx="11" cy="11" r="1.5" fill="#E2E8F0"/>
<circle cx="15" cy="11" r="1.5" fill="#E2E8F0"/>
</svg>
</div>
<span class="share-target-label">More...</span>
</button>
</div>
<!-- Close -->
<div class="close-row">
<a class="close-btn" href="../gallery/33-gallery-detail.html">Close</a>
</div>
</div>
</div>
</div>
<script>
function copyLink() {
const toast = document.getElementById('copiedToast');
toast.classList.add('visible');
setTimeout(() => toast.classList.remove('visible'), 2000);
}
function shareMessages() {
// Simulated share action
alert('Opening Messages...');
}
function shareMore() {
// Simulated share sheet
alert('Opening share sheet...');
}
</script>
</body>
</html>