← Qiki · all runs · 📊 leaderboard
r-1786613919897-tu6mz
Build a habit tracker with weekly streaks, dark mode, keyboard shortcuts, CSV export, and offline localStorage persistence
model /nix/store/w8fajwih8isx2rl94rb8ggc1knmnf8x9-Qwen3.6-35B-A3B-MTP-GGUF upstream http://127.0.0.1:8080 harness 127.0.0.1
score 9 / 10
2026-08-13 09:38:39 UTC · total 159s · 1 step
code-app · done · 159s
Habit Tracker App
9 / 10
model /nix/store/w8fajwih8isx2rl94rb8ggc1knmnf8x9-Qwen3.6-35B-A3B-MTP-GGUF harness 127.0.0.1:8080
validity 2/2
fidelity 2/2
structure 1/2
depth 2/2
cleanliness 2/2
why (1 notes)
- no interactivity (addEventListener/RAF)
app · 462 lines
Click the preview to focus for keyboard input. Open in new tab for full-screen play.
view source (13928 chars)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Streak | Minimalist Habit Tracker</title>
<meta name="description" content="Minimalist habit tracker with offline persistence and keyboard shortcuts.">
<style>
/*
* STREAK APP STYLES
* Brand Colors: #0f172a (Slate 900), #10b981 (Emerald 500), #334155 (Slate 700)
* Design System: Dark-mode-first, High Contrast, Clean Sans-serif
*/
:root {
/* Brand Palette */
--bg-primary: #0f172a;
--bg-secondary: #1e293b;
--bg-tertiary: #334155;
--accent-primary: #10b981;
--accent-primary-hover: #059669;
--text-primary: #f8fafc;
--text-secondary: #94a3b8;
--text-muted: #64748b;
--danger: #ef4444;
--warning: #f59e0b;
/* Spacing & Layout */
--container-width: 800px;
--border-radius: 12px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
/* Transitions */
--transition-fast: 0.2s ease;
/* Shadows */
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--shadow-glow: 0 0 15px rgba(16, 185, 129, 0.15);
}
/* Light Mode Overrides */
@media (prefers-color-scheme: light) {
:root {
--bg-primary: #f8fafc;
--bg-secondary: #ffffff;
--bg-tertiary: #e2e8f0;
--text-primary: #0f172a;
--text-secondary: #475569;
--text-muted: #94a3b8;
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
}
}
/* Dark Mode Forced Override (if user prefers dark or we force it) */
@media (prefers-color-scheme: dark) {
:root {
--bg-primary: #0f172a;
--bg-secondary: #1e293b;
--bg-tertiary: #334155;
--text-primary: #f8fafc;
--text-secondary: #94a3b8;
--text-muted: #64748b;
}
}
/* Reset & Base */
* { box-sizing: border-box; margin: 0; padding: 0; outline: none; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
background-color: var(--bg-primary);
color: var(--text-primary);
line-height: 1.5;
min-height: 100vh;
display: flex;
flex-direction: column;
transition: background-color var(--transition-fast), color var(--transition-fast);
}
a { color: var(--accent-primary); text-decoration: none; }
button { cursor: pointer; border: none; font-family: inherit; }
/* Layout */
.app-container {
width: 100%;
max-width: var(--container-width);
margin: 0 auto;
padding: var(--spacing-lg);
flex: 1;
}
/* Header */
header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: var(--spacing-xl);
padding-bottom: var(--spacing-md);
border-bottom: 1px solid var(--bg-tertiary);
}
.brand {
display: flex;
align-items: center;
gap: var(--spacing-sm);
}
.brand h1 {
font-size: 1.5rem;
font-weight: 700;
letter-spacing: -0.025em;
color: var(--text-primary);
}
.brand span {
font-size: 0.875rem;
color: var(--text-muted);
font-weight: 400;
}
.header-controls {
display: flex;
gap: var(--spacing-md);
align-items: center;
}
.shortcut-hint {
font-size: 0.75rem;
color: var(--text-muted);
display: none; /* Hidden on mobile */
}
@media (min-width: 768px) {
.shortcut-hint { display: block; }
}
/* Icons */
.icon {
width: 20px;
height: 20px;
stroke: currentColor;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
fill: none;
}
/* Buttons */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--spacing-sm);
padding: 0.5rem 1rem;
border-radius: 6px;
font-size: 0.875rem;
font-weight: 500;
transition: all var(--transition-fast);
}
.btn-primary {
background-color: var(--accent-primary);
color: #0f172a; /* High contrast on green */
}
.btn-primary:hover {
background-color: var(--accent-primary-hover);
transform: translateY(-1px);
}
.btn-ghost {
background-color: transparent;
color: var(--text-secondary);
}
.btn-ghost:hover {
background-color: var(--bg-tertiary);
color: var(--text-primary);
}
.btn-icon {
padding: 0.5rem;
border-radius: 50%;
}
/* Main Content - Habit List */
.habit-list {
display: flex;
flex-direction: column;
gap: var(--spacing-md);
}
.habit-card {
background-color: var(--bg-secondary);
border-radius: var(--border-radius);
padding: var(--spacing-md);
box-shadow: var(--shadow-sm);
border: 1px solid transparent;
transition: all var(--transition-fast);
position: relative;
overflow: hidden;
}
.habit-card:hover {
border-color: var(--bg-tertiary);
box-shadow: var(--shadow-md);
}
.habit-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: var(--spacing-md);
}
.habit-title {
font-size: 1.125rem;
font-weight: 600;
color: var(--text-primary);
}
.habit-streak-badge {
font-size: 0.75rem;
padding: 2px 8px;
border-radius: 9999px;
background-color: var(--bg-tertiary);
color: var(--text-secondary);
font-weight: 600;
display: flex;
align-items: center;
gap: 4px;
}
.habit-streak-badge.active {
background-color: rgba(16, 185, 129, 0.1);
color: var(--accent-primary);
}
/* Weekly Grid */
.week-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 8px;
}
.day-cell {
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
}
.day-label {
font-size: 0.625rem;
text-transform: uppercase;
color: var(--text-muted);
font-weight: 600;
letter-spacing: 0.05em;
}
.day-check {
width: 32px;
height: 32px;
border-radius: 8px;
background-color: var(--bg-primary);
border: 2px solid var(--bg-tertiary);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.1s ease;
position: relative;
}
.day-check:hover {
border-color: var(--text-muted);
}
.day-check.completed {
background-color: var(--accent-primary);
border-color: var(--accent-primary);
color: #0f172a;
}
.day-check.completed svg {
width: 18px;
height: 18px;
stroke-width: 3;
}
.day-check.future {
opacity: 0.3;
cursor: default;
}
/* Empty State */
.empty-state {
text-align: center;
padding: var(--spacing-xl);
color: var(--text-muted);
}
.empty-state svg {
width: 48px;
height: 48px;
margin-bottom: var(--spacing-md);
opacity: 0.5;
}
/* Modal */
.modal-overlay {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background-color: rgba(15, 23, 42, 0.8);
backdrop-filter: blur(4px);
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
opacity: 0;
pointer-events: none;
transition: opacity var(--transition-fast);
}
.modal-overlay.active {
opacity: 1;
pointer-events: auto;
}
.modal {
background-color: var(--bg-secondary);
width: 90%;
max-width: 400px;
padding: var(--spacing-lg);
border-radius: var(--border-radius);
box-shadow: var(--shadow-md);
transform: translateY(20px);
transition: transform var(--transition-fast);
border: 1px solid var(--bg-tertiary);
}
.modal-overlay.active .modal {
transform: translateY(0);
}
.modal h2 {
margin-bottom: var(--spacing-md);
color: var(--text-primary);
}
.form-group {
margin-bottom: var(--spacing-md);
}
.form-group label {
display: block;
margin-bottom: 4px;
font-size: 0.875rem;
color: var(--text-secondary);
}
.form-input {
width: 100%;
padding: 0.75rem;
background-color: var(--bg-primary);
border: 1px solid var(--bg-tertiary);
border-radius: 6px;
color: var(--text-primary);
font-size: 1rem;
transition: border-color var(--transition-fast);
}
.form-input:focus {
border-color: var(--accent-primary);
}
.modal-actions {
display: flex;
justify-content: flex-end;
gap: var(--spacing-sm);
margin-top: var(--spacing-lg);
}
/* Toast Notification */
.toast-container {
position: fixed;
bottom: var(--spacing-lg);
right: var(--spacing-lg);
z-index: 200;
display: flex;
flex-direction: column;
gap: var(--spacing-sm);
}
.toast {
background-color: var(--bg-secondary);
color: var(--text-primary);
padding: var(--spacing-md);
border-radius: 8px;
box-shadow: var(--shadow-md);
border-left: 4px solid var(--accent-primary);
font-size: 0.875rem;
animation: slideIn 0.3s ease forwards;
min-width: 250px;
}
.toast.error { border-left-color: var(--danger); }
.toast.fade-out { opacity: 0; transform: translateX(100%); transition: all 0.3s ease; }
@keyframes slideIn {
from { opacity: 0; transform: translateX(20px); }
to { opacity: 1; transform: translateX(0); }
}
/* Footer */
footer {
text-align: center;
padding: var(--spacing-lg);
color: var(--text-muted);
font-size: 0.75rem;
border-top: 1px solid var(--bg-tertiary);
margin-top: auto;
}
/* Utility */
.hidden { display: none !important; }
.text-danger { color: var(--danger); }
</style>
</head>
<body>
<div class="app-container">
<header>
<div class="brand">
<svg class="icon" viewBox="0 0 24 24" style="color: var(--accent-primary);">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<div>
<h1>Streak</h1>
<span class="hidden-mobile">Minimalist Tracker</span>
</div>
</div>
<div class="header-controls">
<div class="shortcut-hint">
<kbd>N</kbd> New
</div>
<button id="themeToggle" class="btn btn-ghost btn-icon" aria-label="Toggle Theme">
<!-- Sun Icon -->
<svg class="icon sun-icon hidden" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z" />
</svg>
<!-- Moon Icon -->
<svg class="icon moon-icon" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635
</body>
</html> 1 LLM call on this step
ok ·
158739 ms · prompt 1574c → resp 13920c ·
t=0.6 max=4096 ·
→ /nix/store/w8fajwih8isx2rl94rb8ggc1knmnf8x9-Qwen3.6-35B-A3B-MTP-GGUF @ http://127.0.0.1:8080
→ /nix/store/w8fajwih8isx2rl94rb8ggc1knmnf8x9-Qwen3.6-35B-A3B-MTP-GGUF @ http://127.0.0.1:8080
raw JSON
{
"id": "r-1786613919897-tu6mz",
"prompt": "Build a habit tracker with weekly streaks, dark mode, keyboard shortcuts, CSV export, and offline localStorage persistence",
"project": {
"name": "Streak",
"tagline": "Minimalist habit tracker with offline persistence and keyboard shortcuts",
"theme": "dark-mode-first utility interface, clean sans-serif typography, high-contrast data visualization for streaks",
"brandColors": [
"#0f172a",
"#10b981",
"#334155"
],
"audience": "productivity enthusiasts and developers",
"vibe": "minimal, efficient, focused, reliable"
},
"steps": [
{
"id": "s1-4lzya",
"kind": "code-app",
"params": {
"brief": "Build a fully functional Habit Tracker web application with the following features: 1) Weekly streak tracking with visual indicators. 2) Dark mode toggle with system preference detection. 3) Keyboard shortcuts (e.g., 'N' for new habit, '1-7' to toggle days, 'E' for export). 4) CSV export functionality for all habit data. 5) Offline localStorage persistence to save habits and completion status. The UI should be clean, modern, and responsive. Use vanilla HTML/CSS/JS in a single file.",
"kind": "app",
"project": {
"name": "Streak",
"tagline": "Minimalist habit tracker with offline persistence and keyboard shortcuts",
"theme": "dark-mode-first utility interface, clean sans-serif typography, high-contrast data visualization for streaks",
"brandColors": [
"#0f172a",
"#10b981",
"#334155"
],
"audience": "productivity enthusiasts and developers",
"vibe": "minimal, efficient, focused, reliable"
},
"heroPlanned": false
},
"label": "Habit Tracker App"
}
],
"results": {
"s1-4lzya": {
"status": "done",
"startedAt": 1786613919898,
"attempt": 1,
"output": {
"html": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Streak | Minimalist Habit Tracker</title>\n <meta name=\"description\" content=\"Minimalist habit tracker with offline persistence and keyboard shortcuts.\">\n <style>\n /* \n * STREAK APP STYLES\n * Brand Colors: #0f172a (Slate 900), #10b981 (Emerald 500), #334155 (Slate 700)\n * Design System: Dark-mode-first, High Contrast, Clean Sans-serif\n */\n\n :root {\n /* Brand Palette */\n --bg-primary: #0f172a;\n --bg-secondary: #1e293b;\n --bg-tertiary: #334155;\n --accent-primary: #10b981;\n --accent-primary-hover: #059669;\n --text-primary: #f8fafc;\n --text-secondary: #94a3b8;\n --text-muted: #64748b;\n --danger: #ef4444;\n --warning: #f59e0b;\n \n /* Spacing & Layout */\n --container-width: 800px;\n --border-radius: 12px;\n --spacing-sm: 8px;\n --spacing-md: 16px;\n --spacing-lg: 24px;\n --spacing-xl: 32px;\n\n /* Transitions */\n --transition-fast: 0.2s ease;\n \n /* Shadows */\n --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);\n --shadow-glow: 0 0 15px rgba(16, 185, 129, 0.15);\n }\n\n /* Light Mode Overrides */\n @media (prefers-color-scheme: light) {\n :root {\n --bg-primary: #f8fafc;\n --bg-secondary: #ffffff;\n --bg-tertiary: #e2e8f0;\n --text-primary: #0f172a;\n --text-secondary: #475569;\n --text-muted: #94a3b8;\n --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);\n }\n }\n\n /* Dark Mode Forced Override (if user prefers dark or we force it) */\n @media (prefers-color-scheme: dark) {\n :root {\n --bg-primary: #0f172a;\n --bg-secondary: #1e293b;\n --bg-tertiary: #334155;\n --text-primary: #f8fafc;\n --text-secondary: #94a3b8;\n --text-muted: #64748b;\n }\n }\n\n /* Reset & Base */\n * { box-sizing: border-box; margin: 0; padding: 0; outline: none; }\n \n body {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n background-color: var(--bg-primary);\n color: var(--text-primary);\n line-height: 1.5;\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n transition: background-color var(--transition-fast), color var(--transition-fast);\n }\n\n a { color: var(--accent-primary); text-decoration: none; }\n button { cursor: pointer; border: none; font-family: inherit; }\n\n /* Layout */\n .app-container {\n width: 100%;\n max-width: var(--container-width);\n margin: 0 auto;\n padding: var(--spacing-lg);\n flex: 1;\n }\n\n /* Header */\n header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: var(--spacing-xl);\n padding-bottom: var(--spacing-md);\n border-bottom: 1px solid var(--bg-tertiary);\n }\n\n .brand {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n }\n\n .brand h1 {\n font-size: 1.5rem;\n font-weight: 700;\n letter-spacing: -0.025em;\n color: var(--text-primary);\n }\n\n .brand span {\n font-size: 0.875rem;\n color: var(--text-muted);\n font-weight: 400;\n }\n\n .header-controls {\n display: flex;\n gap: var(--spacing-md);\n align-items: center;\n }\n\n .shortcut-hint {\n font-size: 0.75rem;\n color: var(--text-muted);\n display: none; /* Hidden on mobile */\n }\n\n @media (min-width: 768px) {\n .shortcut-hint { display: block; }\n }\n\n /* Icons */\n .icon {\n width: 20px;\n height: 20px;\n stroke: currentColor;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n fill: none;\n }\n\n /* Buttons */\n .btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-sm);\n padding: 0.5rem 1rem;\n border-radius: 6px;\n font-size: 0.875rem;\n font-weight: 500;\n transition: all var(--transition-fast);\n }\n\n .btn-primary {\n background-color: var(--accent-primary);\n color: #0f172a; /* High contrast on green */\n }\n\n .btn-primary:hover {\n background-color: var(--accent-primary-hover);\n transform: translateY(-1px);\n }\n\n .btn-ghost {\n background-color: transparent;\n color: var(--text-secondary);\n }\n\n .btn-ghost:hover {\n background-color: var(--bg-tertiary);\n color: var(--text-primary);\n }\n\n .btn-icon {\n padding: 0.5rem;\n border-radius: 50%;\n }\n\n /* Main Content - Habit List */\n .habit-list {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-md);\n }\n\n .habit-card {\n background-color: var(--bg-secondary);\n border-radius: var(--border-radius);\n padding: var(--spacing-md);\n box-shadow: var(--shadow-sm);\n border: 1px solid transparent;\n transition: all var(--transition-fast);\n position: relative;\n overflow: hidden;\n }\n\n .habit-card:hover {\n border-color: var(--bg-tertiary);\n box-shadow: var(--shadow-md);\n }\n\n .habit-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: var(--spacing-md);\n }\n\n .habit-title {\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--text-primary);\n }\n\n .habit-streak-badge {\n font-size: 0.75rem;\n padding: 2px 8px;\n border-radius: 9999px;\n background-color: var(--bg-tertiary);\n color: var(--text-secondary);\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .habit-streak-badge.active {\n background-color: rgba(16, 185, 129, 0.1);\n color: var(--accent-primary);\n }\n\n /* Weekly Grid */\n .week-grid {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n gap: 8px;\n }\n\n .day-cell {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n }\n\n .day-label {\n font-size: 0.625rem;\n text-transform: uppercase;\n color: var(--text-muted);\n font-weight: 600;\n letter-spacing: 0.05em;\n }\n\n .day-check {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n background-color: var(--bg-primary);\n border: 2px solid var(--bg-tertiary);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.1s ease;\n position: relative;\n }\n\n .day-check:hover {\n border-color: var(--text-muted);\n }\n\n .day-check.completed {\n background-color: var(--accent-primary);\n border-color: var(--accent-primary);\n color: #0f172a;\n }\n\n .day-check.completed svg {\n width: 18px;\n height: 18px;\n stroke-width: 3;\n }\n\n .day-check.future {\n opacity: 0.3;\n cursor: default;\n }\n\n /* Empty State */\n .empty-state {\n text-align: center;\n padding: var(--spacing-xl);\n color: var(--text-muted);\n }\n\n .empty-state svg {\n width: 48px;\n height: 48px;\n margin-bottom: var(--spacing-md);\n opacity: 0.5;\n }\n\n /* Modal */\n .modal-overlay {\n position: fixed;\n top: 0; left: 0; right: 0; bottom: 0;\n background-color: rgba(15, 23, 42, 0.8);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 100;\n opacity: 0;\n pointer-events: none;\n transition: opacity var(--transition-fast);\n }\n\n .modal-overlay.active {\n opacity: 1;\n pointer-events: auto;\n }\n\n .modal {\n background-color: var(--bg-secondary);\n width: 90%;\n max-width: 400px;\n padding: var(--spacing-lg);\n border-radius: var(--border-radius);\n box-shadow: var(--shadow-md);\n transform: translateY(20px);\n transition: transform var(--transition-fast);\n border: 1px solid var(--bg-tertiary);\n }\n\n .modal-overlay.active .modal {\n transform: translateY(0);\n }\n\n .modal h2 {\n margin-bottom: var(--spacing-md);\n color: var(--text-primary);\n }\n\n .form-group {\n margin-bottom: var(--spacing-md);\n }\n\n .form-group label {\n display: block;\n margin-bottom: 4px;\n font-size: 0.875rem;\n color: var(--text-secondary);\n }\n\n .form-input {\n width: 100%;\n padding: 0.75rem;\n background-color: var(--bg-primary);\n border: 1px solid var(--bg-tertiary);\n border-radius: 6px;\n color: var(--text-primary);\n font-size: 1rem;\n transition: border-color var(--transition-fast);\n }\n\n .form-input:focus {\n border-color: var(--accent-primary);\n }\n\n .modal-actions {\n display: flex;\n justify-content: flex-end;\n gap: var(--spacing-sm);\n margin-top: var(--spacing-lg);\n }\n\n /* Toast Notification */\n .toast-container {\n position: fixed;\n bottom: var(--spacing-lg);\n right: var(--spacing-lg);\n z-index: 200;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-sm);\n }\n\n .toast {\n background-color: var(--bg-secondary);\n color: var(--text-primary);\n padding: var(--spacing-md);\n border-radius: 8px;\n box-shadow: var(--shadow-md);\n border-left: 4px solid var(--accent-primary);\n font-size: 0.875rem;\n animation: slideIn 0.3s ease forwards;\n min-width: 250px;\n }\n\n .toast.error { border-left-color: var(--danger); }\n .toast.fade-out { opacity: 0; transform: translateX(100%); transition: all 0.3s ease; }\n\n @keyframes slideIn {\n from { opacity: 0; transform: translateX(20px); }\n to { opacity: 1; transform: translateX(0); }\n }\n\n /* Footer */\n footer {\n text-align: center;\n padding: var(--spacing-lg);\n color: var(--text-muted);\n font-size: 0.75rem;\n border-top: 1px solid var(--bg-tertiary);\n margin-top: auto;\n }\n\n /* Utility */\n .hidden { display: none !important; }\n .text-danger { color: var(--danger); }\n\n </style>\n</head>\n<body>\n\n <div class=\"app-container\">\n <header>\n <div class=\"brand\">\n <svg class=\"icon\" viewBox=\"0 0 24 24\" style=\"color: var(--accent-primary);\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n <div>\n <h1>Streak</h1>\n <span class=\"hidden-mobile\">Minimalist Tracker</span>\n </div>\n </div>\n <div class=\"header-controls\">\n <div class=\"shortcut-hint\">\n <kbd>N</kbd> New\n </div>\n <button id=\"themeToggle\" class=\"btn btn-ghost btn-icon\" aria-label=\"Toggle Theme\">\n <!-- Sun Icon -->\n <svg class=\"icon sun-icon hidden\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z\" />\n </svg>\n <!-- Moon Icon -->\n <svg class=\"icon moon-icon\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635\n</body>\n</html>",
"kind": "app",
"lineCount": 462,
"charCount": 13928,
"llmAuthored": true
},
"produces": {
"appHtml": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Streak | Minimalist Habit Tracker</title>\n <meta name=\"description\" content=\"Minimalist habit tracker with offline persistence and keyboard shortcuts.\">\n <style>\n /* \n * STREAK APP STYLES\n * Brand Colors: #0f172a (Slate 900), #10b981 (Emerald 500), #334155 (Slate 700)\n * Design System: Dark-mode-first, High Contrast, Clean Sans-serif\n */\n\n :root {\n /* Brand Palette */\n --bg-primary: #0f172a;\n --bg-secondary: #1e293b;\n --bg-tertiary: #334155;\n --accent-primary: #10b981;\n --accent-primary-hover: #059669;\n --text-primary: #f8fafc;\n --text-secondary: #94a3b8;\n --text-muted: #64748b;\n --danger: #ef4444;\n --warning: #f59e0b;\n \n /* Spacing & Layout */\n --container-width: 800px;\n --border-radius: 12px;\n --spacing-sm: 8px;\n --spacing-md: 16px;\n --spacing-lg: 24px;\n --spacing-xl: 32px;\n\n /* Transitions */\n --transition-fast: 0.2s ease;\n \n /* Shadows */\n --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);\n --shadow-glow: 0 0 15px rgba(16, 185, 129, 0.15);\n }\n\n /* Light Mode Overrides */\n @media (prefers-color-scheme: light) {\n :root {\n --bg-primary: #f8fafc;\n --bg-secondary: #ffffff;\n --bg-tertiary: #e2e8f0;\n --text-primary: #0f172a;\n --text-secondary: #475569;\n --text-muted: #94a3b8;\n --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);\n }\n }\n\n /* Dark Mode Forced Override (if user prefers dark or we force it) */\n @media (prefers-color-scheme: dark) {\n :root {\n --bg-primary: #0f172a;\n --bg-secondary: #1e293b;\n --bg-tertiary: #334155;\n --text-primary: #f8fafc;\n --text-secondary: #94a3b8;\n --text-muted: #64748b;\n }\n }\n\n /* Reset & Base */\n * { box-sizing: border-box; margin: 0; padding: 0; outline: none; }\n \n body {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n background-color: var(--bg-primary);\n color: var(--text-primary);\n line-height: 1.5;\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n transition: background-color var(--transition-fast), color var(--transition-fast);\n }\n\n a { color: var(--accent-primary); text-decoration: none; }\n button { cursor: pointer; border: none; font-family: inherit; }\n\n /* Layout */\n .app-container {\n width: 100%;\n max-width: var(--container-width);\n margin: 0 auto;\n padding: var(--spacing-lg);\n flex: 1;\n }\n\n /* Header */\n header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: var(--spacing-xl);\n padding-bottom: var(--spacing-md);\n border-bottom: 1px solid var(--bg-tertiary);\n }\n\n .brand {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n }\n\n .brand h1 {\n font-size: 1.5rem;\n font-weight: 700;\n letter-spacing: -0.025em;\n color: var(--text-primary);\n }\n\n .brand span {\n font-size: 0.875rem;\n color: var(--text-muted);\n font-weight: 400;\n }\n\n .header-controls {\n display: flex;\n gap: var(--spacing-md);\n align-items: center;\n }\n\n .shortcut-hint {\n font-size: 0.75rem;\n color: var(--text-muted);\n display: none; /* Hidden on mobile */\n }\n\n @media (min-width: 768px) {\n .shortcut-hint { display: block; }\n }\n\n /* Icons */\n .icon {\n width: 20px;\n height: 20px;\n stroke: currentColor;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n fill: none;\n }\n\n /* Buttons */\n .btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-sm);\n padding: 0.5rem 1rem;\n border-radius: 6px;\n font-size: 0.875rem;\n font-weight: 500;\n transition: all var(--transition-fast);\n }\n\n .btn-primary {\n background-color: var(--accent-primary);\n color: #0f172a; /* High contrast on green */\n }\n\n .btn-primary:hover {\n background-color: var(--accent-primary-hover);\n transform: translateY(-1px);\n }\n\n .btn-ghost {\n background-color: transparent;\n color: var(--text-secondary);\n }\n\n .btn-ghost:hover {\n background-color: var(--bg-tertiary);\n color: var(--text-primary);\n }\n\n .btn-icon {\n padding: 0.5rem;\n border-radius: 50%;\n }\n\n /* Main Content - Habit List */\n .habit-list {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-md);\n }\n\n .habit-card {\n background-color: var(--bg-secondary);\n border-radius: var(--border-radius);\n padding: var(--spacing-md);\n box-shadow: var(--shadow-sm);\n border: 1px solid transparent;\n transition: all var(--transition-fast);\n position: relative;\n overflow: hidden;\n }\n\n .habit-card:hover {\n border-color: var(--bg-tertiary);\n box-shadow: var(--shadow-md);\n }\n\n .habit-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: var(--spacing-md);\n }\n\n .habit-title {\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--text-primary);\n }\n\n .habit-streak-badge {\n font-size: 0.75rem;\n padding: 2px 8px;\n border-radius: 9999px;\n background-color: var(--bg-tertiary);\n color: var(--text-secondary);\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .habit-streak-badge.active {\n background-color: rgba(16, 185, 129, 0.1);\n color: var(--accent-primary);\n }\n\n /* Weekly Grid */\n .week-grid {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n gap: 8px;\n }\n\n .day-cell {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n }\n\n .day-label {\n font-size: 0.625rem;\n text-transform: uppercase;\n color: var(--text-muted);\n font-weight: 600;\n letter-spacing: 0.05em;\n }\n\n .day-check {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n background-color: var(--bg-primary);\n border: 2px solid var(--bg-tertiary);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.1s ease;\n position: relative;\n }\n\n .day-check:hover {\n border-color: var(--text-muted);\n }\n\n .day-check.completed {\n background-color: var(--accent-primary);\n border-color: var(--accent-primary);\n color: #0f172a;\n }\n\n .day-check.completed svg {\n width: 18px;\n height: 18px;\n stroke-width: 3;\n }\n\n .day-check.future {\n opacity: 0.3;\n cursor: default;\n }\n\n /* Empty State */\n .empty-state {\n text-align: center;\n padding: var(--spacing-xl);\n color: var(--text-muted);\n }\n\n .empty-state svg {\n width: 48px;\n height: 48px;\n margin-bottom: var(--spacing-md);\n opacity: 0.5;\n }\n\n /* Modal */\n .modal-overlay {\n position: fixed;\n top: 0; left: 0; right: 0; bottom: 0;\n background-color: rgba(15, 23, 42, 0.8);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 100;\n opacity: 0;\n pointer-events: none;\n transition: opacity var(--transition-fast);\n }\n\n .modal-overlay.active {\n opacity: 1;\n pointer-events: auto;\n }\n\n .modal {\n background-color: var(--bg-secondary);\n width: 90%;\n max-width: 400px;\n padding: var(--spacing-lg);\n border-radius: var(--border-radius);\n box-shadow: var(--shadow-md);\n transform: translateY(20px);\n transition: transform var(--transition-fast);\n border: 1px solid var(--bg-tertiary);\n }\n\n .modal-overlay.active .modal {\n transform: translateY(0);\n }\n\n .modal h2 {\n margin-bottom: var(--spacing-md);\n color: var(--text-primary);\n }\n\n .form-group {\n margin-bottom: var(--spacing-md);\n }\n\n .form-group label {\n display: block;\n margin-bottom: 4px;\n font-size: 0.875rem;\n color: var(--text-secondary);\n }\n\n .form-input {\n width: 100%;\n padding: 0.75rem;\n background-color: var(--bg-primary);\n border: 1px solid var(--bg-tertiary);\n border-radius: 6px;\n color: var(--text-primary);\n font-size: 1rem;\n transition: border-color var(--transition-fast);\n }\n\n .form-input:focus {\n border-color: var(--accent-primary);\n }\n\n .modal-actions {\n display: flex;\n justify-content: flex-end;\n gap: var(--spacing-sm);\n margin-top: var(--spacing-lg);\n }\n\n /* Toast Notification */\n .toast-container {\n position: fixed;\n bottom: var(--spacing-lg);\n right: var(--spacing-lg);\n z-index: 200;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-sm);\n }\n\n .toast {\n background-color: var(--bg-secondary);\n color: var(--text-primary);\n padding: var(--spacing-md);\n border-radius: 8px;\n box-shadow: var(--shadow-md);\n border-left: 4px solid var(--accent-primary);\n font-size: 0.875rem;\n animation: slideIn 0.3s ease forwards;\n min-width: 250px;\n }\n\n .toast.error { border-left-color: var(--danger); }\n .toast.fade-out { opacity: 0; transform: translateX(100%); transition: all 0.3s ease; }\n\n @keyframes slideIn {\n from { opacity: 0; transform: translateX(20px); }\n to { opacity: 1; transform: translateX(0); }\n }\n\n /* Footer */\n footer {\n text-align: center;\n padding: var(--spacing-lg);\n color: var(--text-muted);\n font-size: 0.75rem;\n border-top: 1px solid var(--bg-tertiary);\n margin-top: auto;\n }\n\n /* Utility */\n .hidden { display: none !important; }\n .text-danger { color: var(--danger); }\n\n </style>\n</head>\n<body>\n\n <div class=\"app-container\">\n <header>\n <div class=\"brand\">\n <svg class=\"icon\" viewBox=\"0 0 24 24\" style=\"color: var(--accent-primary);\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n <div>\n <h1>Streak</h1>\n <span class=\"hidden-mobile\">Minimalist Tracker</span>\n </div>\n </div>\n <div class=\"header-controls\">\n <div class=\"shortcut-hint\">\n <kbd>N</kbd> New\n </div>\n <button id=\"themeToggle\" class=\"btn btn-ghost btn-icon\" aria-label=\"Toggle Theme\">\n <!-- Sun Icon -->\n <svg class=\"icon sun-icon hidden\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z\" />\n </svg>\n <!-- Moon Icon -->\n <svg class=\"icon moon-icon\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635\n</body>\n</html>",
"appKind": "app",
"siteHtml": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Streak | Minimalist Habit Tracker</title>\n <meta name=\"description\" content=\"Minimalist habit tracker with offline persistence and keyboard shortcuts.\">\n <style>\n /* \n * STREAK APP STYLES\n * Brand Colors: #0f172a (Slate 900), #10b981 (Emerald 500), #334155 (Slate 700)\n * Design System: Dark-mode-first, High Contrast, Clean Sans-serif\n */\n\n :root {\n /* Brand Palette */\n --bg-primary: #0f172a;\n --bg-secondary: #1e293b;\n --bg-tertiary: #334155;\n --accent-primary: #10b981;\n --accent-primary-hover: #059669;\n --text-primary: #f8fafc;\n --text-secondary: #94a3b8;\n --text-muted: #64748b;\n --danger: #ef4444;\n --warning: #f59e0b;\n \n /* Spacing & Layout */\n --container-width: 800px;\n --border-radius: 12px;\n --spacing-sm: 8px;\n --spacing-md: 16px;\n --spacing-lg: 24px;\n --spacing-xl: 32px;\n\n /* Transitions */\n --transition-fast: 0.2s ease;\n \n /* Shadows */\n --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);\n --shadow-glow: 0 0 15px rgba(16, 185, 129, 0.15);\n }\n\n /* Light Mode Overrides */\n @media (prefers-color-scheme: light) {\n :root {\n --bg-primary: #f8fafc;\n --bg-secondary: #ffffff;\n --bg-tertiary: #e2e8f0;\n --text-primary: #0f172a;\n --text-secondary: #475569;\n --text-muted: #94a3b8;\n --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);\n }\n }\n\n /* Dark Mode Forced Override (if user prefers dark or we force it) */\n @media (prefers-color-scheme: dark) {\n :root {\n --bg-primary: #0f172a;\n --bg-secondary: #1e293b;\n --bg-tertiary: #334155;\n --text-primary: #f8fafc;\n --text-secondary: #94a3b8;\n --text-muted: #64748b;\n }\n }\n\n /* Reset & Base */\n * { box-sizing: border-box; margin: 0; padding: 0; outline: none; }\n \n body {\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif;\n background-color: var(--bg-primary);\n color: var(--text-primary);\n line-height: 1.5;\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n transition: background-color var(--transition-fast), color var(--transition-fast);\n }\n\n a { color: var(--accent-primary); text-decoration: none; }\n button { cursor: pointer; border: none; font-family: inherit; }\n\n /* Layout */\n .app-container {\n width: 100%;\n max-width: var(--container-width);\n margin: 0 auto;\n padding: var(--spacing-lg);\n flex: 1;\n }\n\n /* Header */\n header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: var(--spacing-xl);\n padding-bottom: var(--spacing-md);\n border-bottom: 1px solid var(--bg-tertiary);\n }\n\n .brand {\n display: flex;\n align-items: center;\n gap: var(--spacing-sm);\n }\n\n .brand h1 {\n font-size: 1.5rem;\n font-weight: 700;\n letter-spacing: -0.025em;\n color: var(--text-primary);\n }\n\n .brand span {\n font-size: 0.875rem;\n color: var(--text-muted);\n font-weight: 400;\n }\n\n .header-controls {\n display: flex;\n gap: var(--spacing-md);\n align-items: center;\n }\n\n .shortcut-hint {\n font-size: 0.75rem;\n color: var(--text-muted);\n display: none; /* Hidden on mobile */\n }\n\n @media (min-width: 768px) {\n .shortcut-hint { display: block; }\n }\n\n /* Icons */\n .icon {\n width: 20px;\n height: 20px;\n stroke: currentColor;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n fill: none;\n }\n\n /* Buttons */\n .btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--spacing-sm);\n padding: 0.5rem 1rem;\n border-radius: 6px;\n font-size: 0.875rem;\n font-weight: 500;\n transition: all var(--transition-fast);\n }\n\n .btn-primary {\n background-color: var(--accent-primary);\n color: #0f172a; /* High contrast on green */\n }\n\n .btn-primary:hover {\n background-color: var(--accent-primary-hover);\n transform: translateY(-1px);\n }\n\n .btn-ghost {\n background-color: transparent;\n color: var(--text-secondary);\n }\n\n .btn-ghost:hover {\n background-color: var(--bg-tertiary);\n color: var(--text-primary);\n }\n\n .btn-icon {\n padding: 0.5rem;\n border-radius: 50%;\n }\n\n /* Main Content - Habit List */\n .habit-list {\n display: flex;\n flex-direction: column;\n gap: var(--spacing-md);\n }\n\n .habit-card {\n background-color: var(--bg-secondary);\n border-radius: var(--border-radius);\n padding: var(--spacing-md);\n box-shadow: var(--shadow-sm);\n border: 1px solid transparent;\n transition: all var(--transition-fast);\n position: relative;\n overflow: hidden;\n }\n\n .habit-card:hover {\n border-color: var(--bg-tertiary);\n box-shadow: var(--shadow-md);\n }\n\n .habit-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: var(--spacing-md);\n }\n\n .habit-title {\n font-size: 1.125rem;\n font-weight: 600;\n color: var(--text-primary);\n }\n\n .habit-streak-badge {\n font-size: 0.75rem;\n padding: 2px 8px;\n border-radius: 9999px;\n background-color: var(--bg-tertiary);\n color: var(--text-secondary);\n font-weight: 600;\n display: flex;\n align-items: center;\n gap: 4px;\n }\n\n .habit-streak-badge.active {\n background-color: rgba(16, 185, 129, 0.1);\n color: var(--accent-primary);\n }\n\n /* Weekly Grid */\n .week-grid {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n gap: 8px;\n }\n\n .day-cell {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 4px;\n }\n\n .day-label {\n font-size: 0.625rem;\n text-transform: uppercase;\n color: var(--text-muted);\n font-weight: 600;\n letter-spacing: 0.05em;\n }\n\n .day-check {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n background-color: var(--bg-primary);\n border: 2px solid var(--bg-tertiary);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all 0.1s ease;\n position: relative;\n }\n\n .day-check:hover {\n border-color: var(--text-muted);\n }\n\n .day-check.completed {\n background-color: var(--accent-primary);\n border-color: var(--accent-primary);\n color: #0f172a;\n }\n\n .day-check.completed svg {\n width: 18px;\n height: 18px;\n stroke-width: 3;\n }\n\n .day-check.future {\n opacity: 0.3;\n cursor: default;\n }\n\n /* Empty State */\n .empty-state {\n text-align: center;\n padding: var(--spacing-xl);\n color: var(--text-muted);\n }\n\n .empty-state svg {\n width: 48px;\n height: 48px;\n margin-bottom: var(--spacing-md);\n opacity: 0.5;\n }\n\n /* Modal */\n .modal-overlay {\n position: fixed;\n top: 0; left: 0; right: 0; bottom: 0;\n background-color: rgba(15, 23, 42, 0.8);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 100;\n opacity: 0;\n pointer-events: none;\n transition: opacity var(--transition-fast);\n }\n\n .modal-overlay.active {\n opacity: 1;\n pointer-events: auto;\n }\n\n .modal {\n background-color: var(--bg-secondary);\n width: 90%;\n max-width: 400px;\n padding: var(--spacing-lg);\n border-radius: var(--border-radius);\n box-shadow: var(--shadow-md);\n transform: translateY(20px);\n transition: transform var(--transition-fast);\n border: 1px solid var(--bg-tertiary);\n }\n\n .modal-overlay.active .modal {\n transform: translateY(0);\n }\n\n .modal h2 {\n margin-bottom: var(--spacing-md);\n color: var(--text-primary);\n }\n\n .form-group {\n margin-bottom: var(--spacing-md);\n }\n\n .form-group label {\n display: block;\n margin-bottom: 4px;\n font-size: 0.875rem;\n color: var(--text-secondary);\n }\n\n .form-input {\n width: 100%;\n padding: 0.75rem;\n background-color: var(--bg-primary);\n border: 1px solid var(--bg-tertiary);\n border-radius: 6px;\n color: var(--text-primary);\n font-size: 1rem;\n transition: border-color var(--transition-fast);\n }\n\n .form-input:focus {\n border-color: var(--accent-primary);\n }\n\n .modal-actions {\n display: flex;\n justify-content: flex-end;\n gap: var(--spacing-sm);\n margin-top: var(--spacing-lg);\n }\n\n /* Toast Notification */\n .toast-container {\n position: fixed;\n bottom: var(--spacing-lg);\n right: var(--spacing-lg);\n z-index: 200;\n display: flex;\n flex-direction: column;\n gap: var(--spacing-sm);\n }\n\n .toast {\n background-color: var(--bg-secondary);\n color: var(--text-primary);\n padding: var(--spacing-md);\n border-radius: 8px;\n box-shadow: var(--shadow-md);\n border-left: 4px solid var(--accent-primary);\n font-size: 0.875rem;\n animation: slideIn 0.3s ease forwards;\n min-width: 250px;\n }\n\n .toast.error { border-left-color: var(--danger); }\n .toast.fade-out { opacity: 0; transform: translateX(100%); transition: all 0.3s ease; }\n\n @keyframes slideIn {\n from { opacity: 0; transform: translateX(20px); }\n to { opacity: 1; transform: translateX(0); }\n }\n\n /* Footer */\n footer {\n text-align: center;\n padding: var(--spacing-lg);\n color: var(--text-muted);\n font-size: 0.75rem;\n border-top: 1px solid var(--bg-tertiary);\n margin-top: auto;\n }\n\n /* Utility */\n .hidden { display: none !important; }\n .text-danger { color: var(--danger); }\n\n </style>\n</head>\n<body>\n\n <div class=\"app-container\">\n <header>\n <div class=\"brand\">\n <svg class=\"icon\" viewBox=\"0 0 24 24\" style=\"color: var(--accent-primary);\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z\" />\n </svg>\n <div>\n <h1>Streak</h1>\n <span class=\"hidden-mobile\">Minimalist Tracker</span>\n </div>\n </div>\n <div class=\"header-controls\">\n <div class=\"shortcut-hint\">\n <kbd>N</kbd> New\n </div>\n <button id=\"themeToggle\" class=\"btn btn-ghost btn-icon\" aria-label=\"Toggle Theme\">\n <!-- Sun Icon -->\n <svg class=\"icon sun-icon hidden\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M12 3v2.25m6.364.386l-1.591 1.591M21 12h-2.25m-.386 6.364l-1.591-1.591M12 18.75V21m-4.773-4.227l-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z\" />\n </svg>\n <!-- Moon Icon -->\n <svg class=\"icon moon-icon\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M21.752 15.002A9.718 9.718 0 0118 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 003 11.25C3 16.635\n</body>\n</html>"
},
"finishedAt": 1786614078637,
"llmCalls": [
{
"upstream": "http://127.0.0.1:8080",
"modelRequested": "txt2txt",
"temperature": 0.6,
"maxTokens": 4096,
"timeoutMs": 360000,
"startedAt": 1786613919898,
"finishedAt": 1786614078637,
"ok": true,
"promptChars": 1574,
"responseChars": 13920,
"modelServed": "/nix/store/w8fajwih8isx2rl94rb8ggc1knmnf8x9-Qwen3.6-35B-A3B-MTP-GGUF"
}
]
}
},
"startedAt": 1786613919897,
"fingerprint": {
"ownAiUrl": "http://127.0.0.1:8080",
"harnessHost": "127.0.0.1",
"modelServed": "qwen-image",
"nodeVersion": "v24.18.1",
"capturedAt": 1786613919897
},
"finishedAt": 1786614078638,
"scores": {
"perStep": {
"s1-4lzya": {
"validity": 2,
"fidelity": 2,
"structure": 1,
"depth": 2,
"cleanliness": 2,
"total": 9,
"notes": [
"no interactivity (addEventListener/RAF)"
]
}
},
"total": 9,
"perKind": {
"code-app": 9
},
"axes": [
"validity",
"fidelity",
"structure",
"depth",
"cleanliness"
]
}
}