first commit

This commit is contained in:
ytc1012
2025-11-22 18:17:35 +08:00
commit d427916c6a
169 changed files with 15241 additions and 0 deletions

472
icon-preview.html Normal file
View File

@@ -0,0 +1,472 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FocusBuddy App Icon Preview</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 40px 20px;
}
.container {
max-width: 1200px;
width: 100%;
}
h1 {
color: white;
text-align: center;
margin-bottom: 10px;
font-size: 2.5rem;
}
.subtitle {
color: rgba(255, 255, 255, 0.9);
text-align: center;
margin-bottom: 40px;
font-size: 1.1rem;
}
.designs {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
gap: 30px;
margin-bottom: 40px;
}
.design-card {
background: white;
border-radius: 20px;
padding: 30px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}
.design-title {
font-size: 1.5rem;
margin-bottom: 20px;
color: #333;
text-align: center;
}
.icon-preview {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 30px;
}
.size-tests {
display: flex;
justify-content: center;
gap: 20px;
flex-wrap: wrap;
margin-top: 20px;
}
.size-test {
text-align: center;
}
.size-label {
font-size: 0.85rem;
color: #666;
margin-top: 8px;
}
.description {
font-size: 0.95rem;
color: #666;
line-height: 1.6;
text-align: center;
}
.instructions {
background: white;
border-radius: 20px;
padding: 30px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
margin-top: 30px;
}
.instructions h2 {
color: #333;
margin-bottom: 20px;
}
.instructions ol {
margin-left: 20px;
color: #666;
line-height: 1.8;
}
.instructions li {
margin-bottom: 10px;
}
.color-palette {
display: flex;
justify-content: center;
gap: 15px;
margin: 20px 0;
flex-wrap: wrap;
}
.color-swatch {
text-align: center;
}
.color-box {
width: 80px;
height: 80px;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
margin-bottom: 8px;
}
.color-label {
font-size: 0.85rem;
color: #666;
}
.color-code {
font-size: 0.75rem;
color: #999;
font-family: monospace;
}
</style>
</head>
<body>
<div class="container">
<h1>🎨 FocusBuddy App Icon Preview</h1>
<p class="subtitle">Choose your favorite design and create it in Figma or Canva</p>
<!-- Color Palette -->
<div class="design-card">
<h2 class="design-title">App Color Palette</h2>
<div class="color-palette">
<div class="color-swatch">
<div class="color-box" style="background: #A7C4BC;"></div>
<div class="color-label">Primary</div>
<div class="color-code">#A7C4BC</div>
</div>
<div class="color-swatch">
<div class="color-box" style="background: #88C9A1;"></div>
<div class="color-label">Success</div>
<div class="color-code">#88C9A1</div>
</div>
<div class="color-swatch">
<div class="color-box" style="background: #F8F6F2;"></div>
<div class="color-label">Background</div>
<div class="color-code">#F8F6F2</div>
</div>
<div class="color-swatch">
<div class="color-box" style="background: #5B6D6D;"></div>
<div class="color-label">Text</div>
<div class="color-code">#5B6D6D</div>
</div>
</div>
</div>
<!-- Design Options -->
<div class="designs">
<!-- Design 1: Focus Circle with Face -->
<div class="design-card">
<h2 class="design-title">Design 1: Gentle Focus Buddy</h2>
<div class="icon-preview">
<svg width="300" height="300" viewBox="0 0 1024 1024">
<!-- Background gradient -->
<defs>
<linearGradient id="bg1" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#A7C4BC"/>
<stop offset="100%" style="stop-color:#88C9A1"/>
</linearGradient>
</defs>
<!-- Background -->
<rect width="1024" height="1024" fill="url(#bg1)" rx="180"/>
<!-- Outer focus ring -->
<circle cx="512" cy="512" r="400" fill="none" stroke="#F8F6F2" stroke-width="60" opacity="0.9"/>
<!-- Inner circle -->
<circle cx="512" cy="512" r="280" fill="#F8F6F2" opacity="0.95"/>
<!-- Friendly face -->
<!-- Left eye -->
<circle cx="452" cy="480" r="24" fill="#5B6D6D" opacity="0.7"/>
<!-- Right eye -->
<circle cx="572" cy="480" r="24" fill="#5B6D6D" opacity="0.7"/>
<!-- Gentle smile -->
<path d="M 432 560 Q 512 600 592 560"
stroke="#5B6D6D" stroke-width="16"
fill="none" opacity="0.7"
stroke-linecap="round"/>
<!-- Center focus dot -->
<circle cx="512" cy="512" r="40" fill="#A7C4BC" opacity="0.3"/>
</svg>
</div>
<div class="size-tests">
<div class="size-test">
<svg width="180" height="180" viewBox="0 0 1024 1024">
<defs><linearGradient id="bg1a" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#A7C4BC"/>
<stop offset="100%" style="stop-color:#88C9A1"/>
</linearGradient></defs>
<rect width="1024" height="1024" fill="url(#bg1a)" rx="180"/>
<circle cx="512" cy="512" r="400" fill="none" stroke="#F8F6F2" stroke-width="60" opacity="0.9"/>
<circle cx="512" cy="512" r="280" fill="#F8F6F2" opacity="0.95"/>
<circle cx="452" cy="480" r="24" fill="#5B6D6D" opacity="0.7"/>
<circle cx="572" cy="480" r="24" fill="#5B6D6D" opacity="0.7"/>
<path d="M 432 560 Q 512 600 592 560" stroke="#5B6D6D" stroke-width="16" fill="none" opacity="0.7" stroke-linecap="round"/>
</svg>
<div class="size-label">180×180</div>
</div>
<div class="size-test">
<svg width="120" height="120" viewBox="0 0 1024 1024">
<defs><linearGradient id="bg1b" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#A7C4BC"/>
<stop offset="100%" style="stop-color:#88C9A1"/>
</linearGradient></defs>
<rect width="1024" height="1024" fill="url(#bg1b)" rx="180"/>
<circle cx="512" cy="512" r="400" fill="none" stroke="#F8F6F2" stroke-width="60" opacity="0.9"/>
<circle cx="512" cy="512" r="280" fill="#F8F6F2" opacity="0.95"/>
<circle cx="452" cy="480" r="24" fill="#5B6D6D" opacity="0.7"/>
<circle cx="572" cy="480" r="24" fill="#5B6D6D" opacity="0.7"/>
<path d="M 432 560 Q 512 600 592 560" stroke="#5B6D6D" stroke-width="16" fill="none" opacity="0.7" stroke-linecap="round"/>
</svg>
<div class="size-label">120×120</div>
</div>
<div class="size-test">
<svg width="48" height="48" viewBox="0 0 1024 1024">
<defs><linearGradient id="bg1c" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#A7C4BC"/>
<stop offset="100%" style="stop-color:#88C9A1"/>
</linearGradient></defs>
<rect width="1024" height="1024" fill="url(#bg1c)" rx="180"/>
<circle cx="512" cy="512" r="400" fill="none" stroke="#F8F6F2" stroke-width="60" opacity="0.9"/>
<circle cx="512" cy="512" r="280" fill="#F8F6F2" opacity="0.95"/>
<circle cx="452" cy="480" r="24" fill="#5B6D6D" opacity="0.7"/>
<circle cx="572" cy="480" r="24" fill="#5B6D6D" opacity="0.7"/>
<path d="M 432 560 Q 512 600 592 560" stroke="#5B6D6D" stroke-width="16" fill="none" opacity="0.7" stroke-linecap="round"/>
</svg>
<div class="size-label">48×48</div>
</div>
</div>
<p class="description">Friendly and approachable with a subtle smile. Represents a supportive buddy helping you focus.</p>
</div>
<!-- Design 2: Simple Focus Circle -->
<div class="design-card">
<h2 class="design-title">Design 2: Pure Focus</h2>
<div class="icon-preview">
<svg width="300" height="300" viewBox="0 0 1024 1024">
<!-- Background -->
<defs>
<linearGradient id="bg2" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#A7C4BC"/>
<stop offset="100%" style="stop-color:#88C9A1"/>
</linearGradient>
</defs>
<rect width="1024" height="1024" fill="url(#bg2)" rx="180"/>
<!-- Three concentric circles (ripple effect) -->
<circle cx="512" cy="512" r="420" fill="none" stroke="#F8F6F2" stroke-width="40" opacity="0.4"/>
<circle cx="512" cy="512" r="340" fill="none" stroke="#F8F6F2" stroke-width="50" opacity="0.6"/>
<circle cx="512" cy="512" r="260" fill="none" stroke="#F8F6F2" stroke-width="60" opacity="0.8"/>
<!-- Center circle -->
<circle cx="512" cy="512" r="180" fill="#F8F6F2"/>
<!-- Center dot -->
<circle cx="512" cy="512" r="100" fill="#A7C4BC"/>
</svg>
</div>
<div class="size-tests">
<div class="size-test">
<svg width="180" height="180" viewBox="0 0 1024 1024">
<defs><linearGradient id="bg2a" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#A7C4BC"/>
<stop offset="100%" style="stop-color:#88C9A1"/>
</linearGradient></defs>
<rect width="1024" height="1024" fill="url(#bg2a)" rx="180"/>
<circle cx="512" cy="512" r="420" fill="none" stroke="#F8F6F2" stroke-width="40" opacity="0.4"/>
<circle cx="512" cy="512" r="340" fill="none" stroke="#F8F6F2" stroke-width="50" opacity="0.6"/>
<circle cx="512" cy="512" r="260" fill="none" stroke="#F8F6F2" stroke-width="60" opacity="0.8"/>
<circle cx="512" cy="512" r="180" fill="#F8F6F2"/>
<circle cx="512" cy="512" r="100" fill="#A7C4BC"/>
</svg>
<div class="size-label">180×180</div>
</div>
<div class="size-test">
<svg width="120" height="120" viewBox="0 0 1024 1024">
<defs><linearGradient id="bg2b" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#A7C4BC"/>
<stop offset="100%" style="stop-color:#88C9A1"/>
</linearGradient></defs>
<rect width="1024" height="1024" fill="url(#bg2b)" rx="180"/>
<circle cx="512" cy="512" r="420" fill="none" stroke="#F8F6F2" stroke-width="40" opacity="0.4"/>
<circle cx="512" cy="512" r="340" fill="none" stroke="#F8F6F2" stroke-width="50" opacity="0.6"/>
<circle cx="512" cy="512" r="260" fill="none" stroke="#F8F6F2" stroke-width="60" opacity="0.8"/>
<circle cx="512" cy="512" r="180" fill="#F8F6F2"/>
<circle cx="512" cy="512" r="100" fill="#A7C4BC"/>
</svg>
<div class="size-label">120×120</div>
</div>
<div class="size-test">
<svg width="48" height="48" viewBox="0 0 1024 1024">
<defs><linearGradient id="bg2c" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#A7C4BC"/>
<stop offset="100%" style="stop-color:#88C9A1"/>
</linearGradient></defs>
<rect width="1024" height="1024" fill="url(#bg2c)" rx="180"/>
<circle cx="512" cy="512" r="420" fill="none" stroke="#F8F6F2" stroke-width="40" opacity="0.4"/>
<circle cx="512" cy="512" r="340" fill="none" stroke="#F8F6F2" stroke-width="50" opacity="0.6"/>
<circle cx="512" cy="512" r="260" fill="none" stroke="#F8F6F2" stroke-width="60" opacity="0.8"/>
<circle cx="512" cy="512" r="180" fill="#F8F6F2"/>
<circle cx="512" cy="512" r="100" fill="#A7C4BC"/>
</svg>
<div class="size-label">48×48</div>
</div>
</div>
<p class="description">Minimalist and meditative. Concentric circles represent focused attention rippling outward.</p>
</div>
<!-- Design 3: Timer -->
<div class="design-card">
<h2 class="design-title">Design 3: Focus Timer</h2>
<div class="icon-preview">
<svg width="300" height="300" viewBox="0 0 1024 1024">
<defs>
<linearGradient id="bg3" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#A7C4BC"/>
<stop offset="100%" style="stop-color:#88C9A1"/>
</linearGradient>
</defs>
<rect width="1024" height="1024" fill="url(#bg3)" rx="180"/>
<!-- Clock circle -->
<circle cx="512" cy="550" r="360" fill="#F8F6F2" stroke="#5B6D6D" stroke-width="8" opacity="0.95"/>
<!-- Hour markers -->
<circle cx="512" cy="210" r="16" fill="#5B6D6D" opacity="0.3"/>
<circle cx="852" cy="550" r="16" fill="#5B6D6D" opacity="0.3"/>
<circle cx="512" cy="890" r="16" fill="#5B6D6D" opacity="0.3"/>
<circle cx="172" cy="550" r="16" fill="#5B6D6D" opacity="0.3"/>
<!-- Clock hands -->
<!-- Hour hand (pointing to 2 - Pomodoro 25 min reference) -->
<line x1="512" y1="550" x2="650" y2="420"
stroke="#5B6D6D" stroke-width="24"
stroke-linecap="round" opacity="0.8"/>
<!-- Minute hand (pointing to 5 - 25 minutes) -->
<line x1="512" y1="550" x2="512" y2="240"
stroke="#A7C4BC" stroke-width="20"
stroke-linecap="round"/>
<!-- Center dot -->
<circle cx="512" cy="550" r="32" fill="#5B6D6D"/>
<!-- Small button on top -->
<rect x="482" y="120" width="60" height="40" rx="10" fill="#F8F6F2" opacity="0.9"/>
</svg>
</div>
<div class="size-tests">
<div class="size-test">
<svg width="180" height="180" viewBox="0 0 1024 1024">
<defs><linearGradient id="bg3a" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#A7C4BC"/>
<stop offset="100%" style="stop-color:#88C9A1"/>
</linearGradient></defs>
<rect width="1024" height="1024" fill="url(#bg3a)" rx="180"/>
<circle cx="512" cy="550" r="360" fill="#F8F6F2" stroke="#5B6D6D" stroke-width="8" opacity="0.95"/>
<circle cx="512" cy="210" r="16" fill="#5B6D6D" opacity="0.3"/>
<line x1="512" y1="550" x2="650" y2="420" stroke="#5B6D6D" stroke-width="24" stroke-linecap="round" opacity="0.8"/>
<line x1="512" y1="550" x2="512" y2="240" stroke="#A7C4BC" stroke-width="20" stroke-linecap="round"/>
<circle cx="512" cy="550" r="32" fill="#5B6D6D"/>
<rect x="482" y="120" width="60" height="40" rx="10" fill="#F8F6F2" opacity="0.9"/>
</svg>
<div class="size-label">180×180</div>
</div>
<div class="size-test">
<svg width="120" height="120" viewBox="0 0 1024 1024">
<defs><linearGradient id="bg3b" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#A7C4BC"/>
<stop offset="100%" style="stop-color:#88C9A1"/>
</linearGradient></defs>
<rect width="1024" height="1024" fill="url(#bg3b)" rx="180"/>
<circle cx="512" cy="550" r="360" fill="#F8F6F2" stroke="#5B6D6D" stroke-width="8" opacity="0.95"/>
<circle cx="512" cy="210" r="16" fill="#5B6D6D" opacity="0.3"/>
<line x1="512" y1="550" x2="650" y2="420" stroke="#5B6D6D" stroke-width="24" stroke-linecap="round" opacity="0.8"/>
<line x1="512" y1="550" x2="512" y2="240" stroke="#A7C4BC" stroke-width="20" stroke-linecap="round"/>
<circle cx="512" cy="550" r="32" fill="#5B6D6D"/>
<rect x="482" y="120" width="60" height="40" rx="10" fill="#F8F6F2" opacity="0.9"/>
</svg>
<div class="size-label">120×120</div>
</div>
<div class="size-test">
<svg width="48" height="48" viewBox="0 0 1024 1024">
<defs><linearGradient id="bg3c" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#A7C4BC"/>
<stop offset="100%" style="stop-color:#88C9A1"/>
</linearGradient></defs>
<rect width="1024" height="1024" fill="url(#bg3c)" rx="180"/>
<circle cx="512" cy="550" r="360" fill="#F8F6F2" stroke="#5B6D6D" stroke-width="8" opacity="0.95"/>
<line x1="512" y1="550" x2="512" y2="240" stroke="#A7C4BC" stroke-width="20" stroke-linecap="round"/>
<circle cx="512" cy="550" r="32" fill="#5B6D6D"/>
</svg>
<div class="size-label">48×48</div>
</div>
</div>
<p class="description">Clearly communicates the timer function. Clock hands set to 25 minutes (Pomodoro technique).</p>
</div>
</div>
<!-- Instructions -->
<div class="instructions">
<h2>📝 How to Create Your Icon</h2>
<ol>
<li><strong>Choose your favorite design</strong> from the three options above</li>
<li><strong>Open Figma</strong> (figma.com - free account) or Canva (canva.com)</li>
<li><strong>Create a 1024×1024 canvas</strong></li>
<li><strong>Recreate the design</strong> using the color codes and measurements shown</li>
<li><strong>Export as PNG</strong> at 1024×1024 resolution</li>
<li><strong>Generate all sizes</strong> using appicon.co (upload your 1024×1024 PNG)</li>
<li><strong>Download and install</strong> the generated icon sets to your Flutter project</li>
</ol>
<h2 style="margin-top: 30px;">💡 Design Tips</h2>
<ul style="margin-left: 20px; color: #666; line-height: 1.8;">
<li><strong>Keep it simple</strong> - Icons need to be recognizable at small sizes</li>
<li><strong>Test visibility</strong> - Check how it looks at 48×48 pixels (smallest size shown above)</li>
<li><strong>Use the app colors</strong> - Stick to the palette for brand consistency</li>
<li><strong>Avoid text</strong> - Text becomes unreadable at small sizes</li>
<li><strong>Think about emotion</strong> - Should feel calm, supportive, and friendly</li>
</ul>
<h2 style="margin-top: 30px;">🔧 Quick Tools</h2>
<ul style="margin-left: 20px; color: #666; line-height: 1.8;">
<li><strong>Design:</strong> <a href="https://www.figma.com" target="_blank">Figma</a> (recommended) or <a href="https://www.canva.com" target="_blank">Canva</a></li>
<li><strong>Generate sizes:</strong> <a href="https://appicon.co" target="_blank">AppIcon.co</a> - Upload 1024×1024, get all sizes</li>
<li><strong>Documentation:</strong> See APP_ICON_DESIGN.md for full technical specs</li>
</ul>
</div>
</div>
</body>
</html>