feat: replace Starlight docs with simple HTML product website

- Removed docs/ (Starlight)
- Added www/ with pure HTML/CSS/JS landing page
- Product website with features, how it works, get started
- Basic HTML documentation pages (installation, quick start, AI providers)
- Dockerfile.docs now serves static files from www/
- Updated README and AGENTS.md
This commit is contained in:
lotherk
2026-03-27 10:42:22 +00:00
parent f414161fd8
commit 36474db276
40 changed files with 1193 additions and 9682 deletions

178
www/css/docs.css Normal file
View File

@@ -0,0 +1,178 @@
.docs-layout {
display: flex;
padding-top: 72px;
min-height: 100vh;
}
.docs-sidebar {
width: 260px;
flex-shrink: 0;
background: var(--bg-secondary);
border-right: 1px solid var(--border);
padding: 32px 24px;
position: fixed;
top: 72px;
left: 0;
bottom: 0;
overflow-y: auto;
}
.sidebar-section {
margin-bottom: 32px;
}
.sidebar-section h3 {
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-muted);
margin-bottom: 12px;
}
.sidebar-section a {
display: block;
padding: 8px 12px;
color: var(--text-secondary);
border-radius: var(--radius-sm);
transition: all 0.2s;
font-size: 0.95rem;
}
.sidebar-section a:hover {
color: var(--text-primary);
background: rgba(109, 40, 217, 0.1);
}
.sidebar-section a.active {
color: var(--accent-light);
background: rgba(109, 40, 217, 0.15);
}
.docs-content {
flex: 1;
max-width: 800px;
margin: 0 auto;
padding: 48px 48px 100px;
margin-left: 260px;
}
.docs-content h1 {
font-size: 2.5rem;
margin-bottom: 32px;
}
.docs-content h2 {
font-size: 1.5rem;
margin-top: 48px;
margin-bottom: 16px;
color: var(--text-primary);
}
.docs-content h3 {
font-size: 1.1rem;
margin-top: 32px;
margin-bottom: 12px;
color: var(--text-primary);
}
.docs-content p {
color: var(--text-secondary);
margin-bottom: 16px;
line-height: 1.8;
}
.docs-content ul,
.docs-content ol {
color: var(--text-secondary);
margin-bottom: 16px;
padding-left: 24px;
}
.docs-content li {
margin-bottom: 8px;
}
.docs-content pre {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: 16px 20px;
margin-bottom: 24px;
overflow-x: auto;
}
.docs-content code {
font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
font-size: 0.9rem;
color: var(--accent-light);
}
.docs-content table {
width: 100%;
border-collapse: collapse;
margin-bottom: 24px;
}
.docs-content th,
.docs-content td {
padding: 12px 16px;
text-align: left;
border-bottom: 1px solid var(--border);
}
.docs-content th {
color: var(--text-muted);
font-size: 0.85rem;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.docs-content td {
color: var(--text-secondary);
}
.docs-content .tip {
background: rgba(109, 40, 217, 0.15);
border: 1px solid var(--accent);
border-radius: var(--radius-sm);
padding: 16px 20px;
margin-bottom: 24px;
}
.docs-content .tip strong {
color: var(--accent-light);
}
.docs-content .next-steps {
margin-top: 48px;
padding-top: 32px;
border-top: 1px solid var(--border);
}
.docs-content .btn {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 12px 24px;
background: linear-gradient(135deg, var(--accent), var(--accent-dark));
color: white;
border-radius: var(--radius-sm);
font-weight: 600;
transition: all 0.2s;
}
.docs-content .btn:hover {
transform: translateY(-1px);
box-shadow: 0 4px 20px rgba(109, 40, 217, 0.3);
}
@media (max-width: 900px) {
.docs-sidebar {
display: none;
}
.docs-content {
margin-left: 0;
padding: 32px 24px;
}
}

367
www/css/styles.css Normal file
View File

@@ -0,0 +1,367 @@
:root {
--bg-primary: #0f172a;
--bg-secondary: #1e293b;
--bg-card: #1e293b;
--text-primary: #f8fafc;
--text-secondary: #94a3b8;
--text-muted: #64748b;
--accent: #6d28d9;
--accent-light: #a78bfa;
--accent-dark: #4c1d95;
--border: #334155;
--radius: 12px;
--radius-sm: 8px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
background: var(--bg-primary);
color: var(--text-primary);
line-height: 1.6;
}
a {
color: inherit;
text-decoration: none;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 0 24px;
}
.navbar {
position: fixed;
top: 0;
left: 0;
right: 0;
background: rgba(15, 23, 42, 0.9);
backdrop-filter: blur(12px);
border-bottom: 1px solid var(--border);
z-index: 100;
}
.nav-container {
max-width: 1200px;
margin: 0 auto;
padding: 16px 24px;
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
display: flex;
align-items: center;
gap: 12px;
font-size: 1.25rem;
font-weight: 700;
}
.nav-links {
display: flex;
align-items: center;
gap: 32px;
}
.nav-links a:not(.btn) {
color: var(--text-secondary);
transition: color 0.2s;
}
.nav-links a:not(.btn):hover {
color: var(--text-primary);
}
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 10px 20px;
border-radius: var(--radius-sm);
font-weight: 600;
font-size: 0.95rem;
transition: all 0.2s;
cursor: pointer;
border: none;
}
.btn-primary {
background: linear-gradient(135deg, var(--accent), var(--accent-dark));
color: white;
}
.btn-primary:hover {
background: linear-gradient(135deg, var(--accent-light), var(--accent));
transform: translateY(-1px);
}
.btn-secondary {
background: var(--bg-secondary);
color: var(--text-primary);
border: 1px solid var(--border);
}
.btn-secondary:hover {
border-color: var(--accent);
color: var(--accent-light);
}
.btn-large {
padding: 14px 28px;
font-size: 1rem;
}
.hero {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
padding: 120px 24px 80px;
background: radial-gradient(ellipse at top, rgba(109, 40, 217, 0.15) 0%, transparent 60%);
}
.hero-content {
max-width: 800px;
}
.hero h1 {
font-size: clamp(2.5rem, 6vw, 4.5rem);
font-weight: 800;
line-height: 1.1;
margin-bottom: 24px;
}
.gradient-text {
background: linear-gradient(135deg, var(--accent-light), #818cf8);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.hero-subtitle {
font-size: 1.25rem;
color: var(--text-secondary);
max-width: 600px;
margin: 0 auto 40px;
}
.hero-actions {
display: flex;
gap: 16px;
justify-content: center;
flex-wrap: wrap;
margin-bottom: 32px;
}
.hero-meta {
display: flex;
gap: 12px;
justify-content: center;
color: var(--text-muted);
font-size: 0.9rem;
}
.features {
padding: 100px 0;
}
.features h2 {
text-align: center;
font-size: 2.5rem;
margin-bottom: 60px;
}
.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 24px;
}
.feature-card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 32px;
transition: all 0.3s;
}
.feature-card:hover {
border-color: var(--accent);
transform: translateY(-4px);
box-shadow: 0 12px 40px rgba(109, 40, 217, 0.15);
}
.feature-icon {
font-size: 2.5rem;
margin-bottom: 16px;
}
.feature-card h3 {
font-size: 1.25rem;
margin-bottom: 12px;
}
.feature-card p {
color: var(--text-secondary);
font-size: 0.95rem;
}
.how {
padding: 100px 0;
background: var(--bg-secondary);
}
.how h2 {
text-align: center;
font-size: 2.5rem;
margin-bottom: 60px;
}
.steps {
max-width: 700px;
margin: 0 auto;
}
.step {
display: flex;
gap: 24px;
margin-bottom: 48px;
}
.step:last-child {
margin-bottom: 0;
}
.step-number {
flex-shrink: 0;
width: 48px;
height: 48px;
background: linear-gradient(135deg, var(--accent), var(--accent-dark));
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
font-size: 1.25rem;
}
.step-content h3 {
font-size: 1.25rem;
margin-bottom: 8px;
}
.step-content p {
color: var(--text-secondary);
}
.try {
padding: 100px 0;
}
.try-content {
text-align: center;
max-width: 700px;
margin: 0 auto;
}
.try-content h2 {
font-size: 2.5rem;
margin-bottom: 16px;
}
.try-content > p {
color: var(--text-secondary);
margin-bottom: 32px;
}
.try-code {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 20px 24px;
margin-bottom: 16px;
overflow-x: auto;
}
.try-code code {
font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
font-size: 0.9rem;
color: var(--accent-light);
}
.try-hint {
color: var(--text-muted);
font-size: 0.9rem;
}
.footer {
padding: 60px 0 40px;
border-top: 1px solid var(--border);
}
.footer-links {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 40px;
margin-bottom: 40px;
}
.footer-col h4 {
font-size: 0.9rem;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-muted);
margin-bottom: 16px;
}
.footer-col a {
display: block;
color: var(--text-secondary);
padding: 6px 0;
transition: color 0.2s;
}
.footer-col a:hover {
color: var(--accent-light);
}
.footer-bottom {
text-align: center;
padding-top: 40px;
border-top: 1px solid var(--border);
color: var(--text-muted);
font-size: 0.9rem;
}
@media (max-width: 768px) {
.nav-links a:not(.btn) {
display: none;
}
.hero h1 {
font-size: 2.5rem;
}
.feature-grid {
grid-template-columns: 1fr;
}
.step {
flex-direction: column;
align-items: center;
text-align: center;
}
}

138
www/docs/ai-providers.html Normal file
View File

@@ -0,0 +1,138 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Providers - DearDiary</title>
<link rel="stylesheet" href="../css/styles.css">
<link rel="stylesheet" href="../css/docs.css">
</head>
<body>
<nav class="navbar">
<div class="nav-container">
<a href="../" class="logo">
<svg width="32" height="32" viewBox="0 0 100 100"><defs><linearGradient id="g" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#6d28d9"/><stop offset="100%" style="stop-color:#4c1d95"/></linearGradient></defs><rect width="100" height="100" rx="20" fill="url(#g)"/><path d="M25 25 L75 25 L75 80 L25 80 Z" fill="none" stroke="white" stroke-width="3"/></svg>
DearDiary
</a>
<div class="nav-links">
<a href="../">Home</a>
<a href="../docs/">Docs</a>
<a href="https://github.com/lotherk/deardiary" target="_blank">GitHub</a>
</div>
</div>
</nav>
<div class="docs-layout">
<aside class="docs-sidebar">
<div class="sidebar-section">
<h3>Getting Started</h3>
<a href="installation.html">Installation</a>
<a href="quick-start.html">Quick Start</a>
<a href="configuration.html">Configuration</a>
</div>
<div class="sidebar-section">
<h3>Features</h3>
<a href="events.html">Events</a>
<a href="diary-pages.html">Diary Pages</a>
<a href="ai-providers.html" class="active">AI Providers</a>
<a href="search.html">Search</a>
<a href="export-import.html">Export & Import</a>
</div>
</aside>
<main class="docs-content">
<h1>AI Providers</h1>
<p>DearDiary supports multiple AI providers for diary generation. Choose the one that best fits your needs.</p>
<h2>Supported Providers</h2>
<table>
<tr>
<th>Provider</th>
<th>Default Model</th>
<th>Type</th>
</tr>
<tr>
<td><strong>Groq</strong> (Recommended)</td>
<td>llama-3.3-70b-versatile</td>
<td>Cloud</td>
</tr>
<tr>
<td>OpenAI</td>
<td>gpt-4o</td>
<td>Cloud</td>
</tr>
<tr>
<td>Anthropic</td>
<td>claude-3-5-sonnet-latest</td>
<td>Cloud</td>
</tr>
<tr>
<td>Ollama</td>
<td>varies</td>
<td>Local</td>
</tr>
<tr>
<td>LM Studio</td>
<td>varies</td>
<td>Local</td>
</tr>
</table>
<h2>Groq (Recommended)</h2>
<p>Fast inference with a free tier available.</p>
<ol>
<li>Get an API key from <a href="https://console.groq.com" target="_blank">console.groq.com</a></li>
<li>Enter the API key in Settings</li>
<li>Select Groq as your provider</li>
<li>Test connection and save</li>
</ol>
<h2>OpenAI</h2>
<ol>
<li>Get an API key from <a href="https://platform.openai.com" target="_blank">platform.openai.com</a></li>
<li>Optionally select a specific model:
<ul>
<li><code>gpt-4o</code> - Most capable</li>
<li><code>gpt-4o-mini</code> - Faster, cheaper</li>
</ul>
</li>
</ol>
<h2>Anthropic</h2>
<ol>
<li>Get an API key from <a href="https://console.anthropic.com" target="_blank">console.anthropic.com</a></li>
<li>Select Claude model:
<ul>
<li><code>claude-3-5-sonnet-latest</code> - Recommended</li>
<li><code>claude-3-opus-latest</code> - Most capable</li>
</ul>
</li>
</ol>
<h2>Local Models (Ollama)</h2>
<p>Run models locally on your machine for complete privacy.</p>
<ol>
<li>Install <a href="https://ollama.ai" target="_blank">Ollama</a></li>
<li>Pull a model: <code>ollama pull llama3.2</code></li>
<li>Set base URL: <code>http://localhost:11434/v1</code></li>
<li>Enter model name (e.g., <code>llama3.2</code>)</li>
</ol>
<h2>Local Models (LM Studio)</h2>
<ol>
<li>Download <a href="https://lmstudio.ai" target="_blank">LM Studio</a></li>
<li>Download a model</li>
<li>Start local server (click "Start Server")</li>
<li>Set base URL: <code>http://localhost:1234/v1</code></li>
</ol>
<div class="next-steps">
<a href="diary-pages.html" class="btn">← Diary Pages</a>
<a href="events.html" class="btn">Events →</a>
</div>
</main>
</div>
</body>
</html>

84
www/docs/index.html Normal file
View File

@@ -0,0 +1,84 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documentation - DearDiary</title>
<link rel="stylesheet" href="../css/styles.css">
<link rel="stylesheet" href="../css/docs.css">
</head>
<body>
<nav class="navbar">
<div class="nav-container">
<a href="../" class="logo">
<svg width="32" height="32" viewBox="0 0 100 100"><defs><linearGradient id="g" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#6d28d9"/><stop offset="100%" style="stop-color:#4c1d95"/></linearGradient></defs><rect width="100" height="100" rx="20" fill="url(#g)"/><path d="M25 25 L75 25 L75 80 L25 80 Z" fill="none" stroke="white" stroke-width="3"/></svg>
DearDiary
</a>
<div class="nav-links">
<a href="../">Home</a>
<a href="../docs/" class="active">Docs</a>
<a href="https://github.com/lotherk/deardiary" target="_blank">GitHub</a>
</div>
</div>
</nav>
<div class="docs-layout">
<aside class="docs-sidebar">
<div class="sidebar-section">
<h3>Getting Started</h3>
<a href="installation.html">Installation</a>
<a href="quick-start.html">Quick Start</a>
<a href="configuration.html">Configuration</a>
</div>
<div class="sidebar-section">
<h3>Features</h3>
<a href="events.html">Events</a>
<a href="diary-pages.html">Diary Pages</a>
<a href="ai-providers.html">AI Providers</a>
<a href="search.html">Search</a>
<a href="export-import.html">Export & Import</a>
</div>
</aside>
<main class="docs-content">
<h1>Documentation</h1>
<p>Welcome to the DearDiary documentation. Here you'll find everything you need to get started and make the most of your AI-powered journal.</p>
<h2>Quick Links</h2>
<div class="feature-grid" style="grid-template-columns: repeat(2, 1fr);">
<div class="feature-card">
<h3><a href="installation.html">Installation</a></h3>
<p>Get DearDiary up and running with Docker in minutes.</p>
</div>
<div class="feature-card">
<h3><a href="quick-start.html">Quick Start</a></h3>
<p>Learn the basics and create your first diary entry.</p>
</div>
<div class="feature-card">
<h3><a href="ai-providers.html">AI Providers</a></h3>
<p>Configure Groq, OpenAI, Anthropic, or local models.</p>
</div>
<div class="feature-card">
<h3><a href="events.html">Events</a></h3>
<p>Learn about capturing and managing events.</p>
</div>
</div>
<h2>Need Help?</h2>
<p>If you encounter issues:</p>
<ul>
<li>Check the <a href="https://github.com/lotherk/deardiary/issues" target="_blank">GitHub Issues</a></li>
<li>Review the configuration settings</li>
<li>Ensure your AI provider API key is valid</li>
</ul>
<div class="next-steps">
<a href="installation.html" class="btn btn-primary">Get Started →</a>
</div>
</main>
</div>
</body>
</html>

121
www/docs/installation.html Normal file
View File

@@ -0,0 +1,121 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Installation - DearDiary</title>
<link rel="stylesheet" href="../css/styles.css">
<link rel="stylesheet" href="../css/docs.css">
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><defs><linearGradient id='g' x1='0%25' y1='0%25' x2='100%25' y2='100%25'><stop offset='0%25' style='stop-color:%236d28d9'/><stop offset='100%25' style='stop-color:%234c1d95'/></linearGradient></defs><rect width='100' height='100' rx='20' fill='url(%23g)'/><path d='M25 25 L75 25 L75 80 L25 80 Z' fill='none' stroke='white' stroke-width='3'/></svg>">
</head>
<body>
<nav class="navbar">
<div class="nav-container">
<a href="../" class="logo">
<svg width="32" height="32" viewBox="0 0 100 100"><defs><linearGradient id="g" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#6d28d9"/><stop offset="100%" style="stop-color:#4c1d95"/></linearGradient></defs><rect width="100" height="100" rx="20" fill="url(#g)"/><path d="M25 25 L75 25 L75 80 L25 80 Z" fill="none" stroke="white" stroke-width="3"/></svg>
DearDiary
</a>
<div class="nav-links">
<a href="../">Home</a>
<a href="../docs/">Docs</a>
<a href="https://github.com/lotherk/deardiary" target="_blank">GitHub</a>
</div>
</div>
</nav>
<div class="docs-layout">
<aside class="docs-sidebar">
<div class="sidebar-section">
<h3>Getting Started</h3>
<a href="installation.html" class="active">Installation</a>
<a href="quick-start.html">Quick Start</a>
<a href="configuration.html">Configuration</a>
</div>
<div class="sidebar-section">
<h3>Features</h3>
<a href="events.html">Events</a>
<a href="diary-pages.html">Diary Pages</a>
<a href="ai-providers.html">AI Providers</a>
<a href="search.html">Search</a>
<a href="export-import.html">Export & Import</a>
</div>
</aside>
<main class="docs-content">
<h1>Installation</h1>
<h2>Prerequisites</h2>
<ul>
<li><a href="https://docs.docker.com/get-docker/" target="_blank">Docker</a> and Docker Compose</li>
<li>Git</li>
</ul>
<h2>Quick Install</h2>
<h3>1. Clone the repository</h3>
<pre><code>git clone https://github.com/lotherk/deardiary.git
cd deardiary</code></pre>
<h3>2. Copy the environment file</h3>
<pre><code>cp backend/.env.example backend/.env</code></pre>
<h3>3. Start with Docker</h3>
<pre><code>docker compose up -d</code></pre>
<h3>4. Access the app</h3>
<p>Open <code>http://localhost:5173</code> in your browser.</p>
<h2>Default Credentials</h2>
<table>
<tr>
<td><strong>Email</strong></td>
<td><code>admin@localhost</code></td>
</tr>
<tr>
<td><strong>Password</strong></td>
<td><code>changeme123</code></td>
</tr>
</table>
<div class="tip">
<strong>Important:</strong> Change these credentials immediately after first login!
</div>
<h2>Ports</h2>
<table>
<tr>
<th>Service</th>
<th>Port</th>
<th>Description</th>
</tr>
<tr>
<td>Frontend</td>
<td>5173</td>
<td>Main application (nginx)</td>
</tr>
<tr>
<td>API</td>
<td>3000</td>
<td>Backend API (internal)</td>
</tr>
<tr>
<td>Website</td>
<td>8080</td>
<td>This website (if enabled)</td>
</tr>
</table>
<h2>Data Storage</h2>
<p>All data is stored in Docker volumes:</p>
<ul>
<li><code>./data/db/</code> - SQLite database</li>
<li><code>./data/media/</code> - Uploaded photos and voice memos</li>
</ul>
<div class="next-steps">
<a href="quick-start.html" class="btn btn-primary">Next: Quick Start →</a>
</div>
</main>
</div>
</body>
</html>

118
www/docs/quick-start.html Normal file
View File

@@ -0,0 +1,118 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Quick Start - DearDiary</title>
<link rel="stylesheet" href="../css/styles.css">
<link rel="stylesheet" href="../css/docs.css">
</head>
<body>
<nav class="navbar">
<div class="nav-container">
<a href="../" class="logo">
<svg width="32" height="32" viewBox="0 0 100 100"><defs><linearGradient id="g" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#6d28d9"/><stop offset="100%" style="stop-color:#4c1d95"/></linearGradient></defs><rect width="100" height="100" rx="20" fill="url(#g)"/><path d="M25 25 L75 25 L75 80 L25 80 Z" fill="none" stroke="white" stroke-width="3"/></svg>
DearDiary
</a>
<div class="nav-links">
<a href="../">Home</a>
<a href="../docs/">Docs</a>
<a href="https://github.com/lotherk/deardiary" target="_blank">GitHub</a>
</div>
</div>
</nav>
<div class="docs-layout">
<aside class="docs-sidebar">
<div class="sidebar-section">
<h3>Getting Started</h3>
<a href="installation.html">Installation</a>
<a href="quick-start.html" class="active">Quick Start</a>
<a href="configuration.html">Configuration</a>
</div>
<div class="sidebar-section">
<h3>Features</h3>
<a href="events.html">Events</a>
<a href="diary-pages.html">Diary Pages</a>
<a href="ai-providers.html">AI Providers</a>
<a href="search.html">Search</a>
<a href="export-import.html">Export & Import</a>
</div>
</aside>
<main class="docs-content">
<h1>Quick Start</h1>
<h2>First Steps</h2>
<h3>1. Configure AI Provider</h3>
<p>Before generating diaries, you need to set up an AI provider:</p>
<ol>
<li>Go to <strong>Settings</strong></li>
<li>Select your AI provider (Groq is recommended for free, fast inference)</li>
<li>Enter your API key</li>
<li>Click "Test Connection" to verify</li>
<li>Save settings</li>
</ol>
<h3>2. Log Your First Event</h3>
<p>Navigate to <strong>Today</strong> and start logging events:</p>
<ul>
<li>Type your event and press Enter</li>
<li>Use the type buttons to change event category</li>
<li>Events are timestamped automatically</li>
<li>Location is captured if you allow browser permission</li>
</ul>
<h3>3. Generate Your Diary</h3>
<p>When you're ready to lock in your day:</p>
<ol>
<li>Click <strong>Generate Diary Page</strong></li>
<li>Wait for AI processing</li>
<li>Your diary page appears with a generated title</li>
</ol>
<div class="tip">
Once generated, events become <strong>locked</strong> (immutable). To unlock, delete the diary page.
</div>
<h3>4. Rewrite if Needed</h3>
<p>Click <strong>Rewrite</strong> to regenerate with additional instructions:</p>
<ul>
<li>Add context like "Make it more detailed"</li>
<li>Focus on specific topics</li>
<li>Adjust the tone or style</li>
</ul>
<h2>Keyboard Shortcuts</h2>
<table>
<tr>
<th>Shortcut</th>
<th>Action</th>
</tr>
<tr>
<td><code>Ctrl + J</code></td>
<td>Quick add event</td>
</tr>
<tr>
<td><code>Ctrl + K</code></td>
<td>Search</td>
</tr>
</table>
<h2>Tips</h2>
<ul>
<li>Log events throughout the day for richer diaries</li>
<li>Use the calendar view to browse past days</li>
<li>Export your data regularly for backup</li>
<li>Try different AI providers for varied writing styles</li>
</ul>
<div class="next-steps">
<a href="installation.html" class="btn">← Previous</a>
<a href="configuration.html" class="btn">Next: Configuration →</a>
</div>
</main>
</div>
</body>
</html>

155
www/index.html Normal file
View File

@@ -0,0 +1,155 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DearDiary - AI-Powered Daily Journal</title>
<meta name="description" content="Self-hosted AI-powered daily journaling. Capture events throughout the day and let AI generate beautiful diary pages.">
<link rel="stylesheet" href="css/styles.css">
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><defs><linearGradient id='g' x1='0%25' y1='0%25' x2='100%25' y2='100%25'><stop offset='0%25' style='stop-color:%236d28d9'/><stop offset='100%25' style='stop-color:%234c1d95'/></linearGradient></defs><rect width='100' height='100' rx='20' fill='url(%23g)'/><path d='M25 25 L75 25 L75 80 L25 80 Z' fill='none' stroke='white' stroke-width='3'/><path d='M35 40 L65 40 M35 50 L65 50 M35 60 L55 60' stroke='white' stroke-width='2'/></svg>">
</head>
<body>
<nav class="navbar">
<div class="nav-container">
<a href="/" class="logo">
<svg width="32" height="32" viewBox="0 0 100 100"><defs><linearGradient id="g" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#6d28d9"/><stop offset="100%" style="stop-color:#4c1d95"/></linearGradient></defs><rect width="100" height="100" rx="20" fill="url(#g)"/><path d="M25 25 L75 25 L75 80 L25 80 Z" fill="none" stroke="white" stroke-width="3"/><path d="M35 40 L65 40 M35 50 L65 50 M35 60 L55 60" stroke="white" stroke-width="2"/></svg>
DearDiary
</a>
<div class="nav-links">
<a href="#features">Features</a>
<a href="docs/">Docs</a>
<a href="https://github.com/lotherk/deardiary" target="_blank">GitHub</a>
<a href="#try" class="btn btn-primary">Get Started</a>
</div>
</div>
</nav>
<header class="hero">
<div class="hero-content">
<h1>Your AI-Powered<br><span class="gradient-text">Daily Journal</span></h1>
<p class="hero-subtitle">Capture events throughout the day and let AI transform them into beautiful, thoughtful diary pages. Self-hosted. Private. Yours.</p>
<div class="hero-actions">
<a href="#try" class="btn btn-primary btn-large">Start Free</a>
<a href="docs/" class="btn btn-secondary btn-large">Read Docs</a>
</div>
<div class="hero-meta">
<span>v0.1.0</span>
<span></span>
<span>Docker</span>
<span></span>
<span>MIT License</span>
</div>
</div>
</header>
<section id="features" class="features">
<div class="container">
<h2>Everything you need for journaling</h2>
<div class="feature-grid">
<div class="feature-card">
<div class="feature-icon">📝</div>
<h3>Quick Capture</h3>
<p>Log events instantly with Ctrl+J. Multiple types: text, photos, voice memos, health notes.</p>
</div>
<div class="feature-card">
<div class="feature-icon">🤖</div>
<h3>AI Generation</h3>
<p>Let AI craft thoughtful diary pages from your events. Works with Groq, OpenAI, Anthropic, and local models.</p>
</div>
<div class="feature-card">
<div class="feature-icon">📍</div>
<h3>Auto Geolocation</h3>
<p>Events are automatically tagged with your location. Remember where life happened.</p>
</div>
<div class="feature-card">
<div class="feature-icon">🔒</div>
<h3>Immutable Memories</h3>
<p>Once a diary is generated, events lock. Your past stays authentic, untouched by today's edits.</p>
</div>
<div class="feature-card">
<div class="feature-icon">🔍</div>
<h3>Full-Text Search</h3>
<p>Find any event or diary entry instantly across all your data.</p>
</div>
<div class="feature-card">
<div class="feature-icon">📤</div>
<h3>Export & Import</h3>
<p>Your data, your control. Export everything as JSON. Migrate anytime.</p>
</div>
</div>
</div>
</section>
<section id="how" class="how">
<div class="container">
<h2>How it works</h2>
<div class="steps">
<div class="step">
<div class="step-number">1</div>
<div class="step-content">
<h3>Capture Throughout the Day</h3>
<p>Log events as they happen. Type, snap a photo, record a voice note. Add health data. Each entry is timestamped and geolocated.</p>
</div>
</div>
<div class="step">
<div class="step-number">2</div>
<div class="step-content">
<h3>Generate Your Diary</h3>
<p>When you're ready, click Generate. AI reads all your events and writes a thoughtful, narrative diary page just for you.</p>
</div>
</div>
<div class="step">
<div class="step-number">3</div>
<div class="step-content">
<h3>Rewrite if Needed</h3>
<p>Not happy with the result? Add instructions and regenerate. Focus on what matters to you.</p>
</div>
</div>
</div>
</div>
</section>
<section id="try" class="try">
<div class="container">
<div class="try-content">
<h2>Ready to start journaling?</h2>
<p>Self-host in minutes with Docker. Your data stays on your server.</p>
<div class="try-code">
<code>git clone https://github.com/lotherk/deardiary.git && cd deardiary && docker compose up -d</code>
</div>
<p class="try-hint">Default login: admin@localhost / changeme123</p>
</div>
</div>
</section>
<footer class="footer">
<div class="container">
<div class="footer-links">
<div class="footer-col">
<h4>Product</h4>
<a href="#features">Features</a>
<a href="docs/">Documentation</a>
<a href="#how">How it Works</a>
</div>
<div class="footer-col">
<h4>Resources</h4>
<a href="docs/getting-started/installation.html">Installation</a>
<a href="docs/getting-started/quick-start.html">Quick Start</a>
<a href="docs/features/ai-providers.html">AI Providers</a>
</div>
<div class="footer-col">
<h4>Project</h4>
<a href="https://github.com/lotherk/deardiary" target="_blank">GitHub</a>
<a href="https://github.com/lotherk/deardiary/issues" target="_blank">Issues</a>
<a href="https://github.com/lotherk/deardiary/releases" target="_blank">Releases</a>
</div>
</div>
<div class="footer-bottom">
<p>MIT License • Copyright 2026 Konrad Lother</p>
</div>
</div>
</footer>
<script src="js/main.js"></script>
</body>
</html>

21
www/js/main.js Normal file
View File

@@ -0,0 +1,21 @@
document.addEventListener('DOMContentLoaded', () => {
const navbar = document.querySelector('.navbar');
window.addEventListener('scroll', () => {
if (window.scrollY > 50) {
navbar.style.background = 'rgba(15, 23, 42, 0.98)';
} else {
navbar.style.background = 'rgba(15, 23, 42, 0.9)';
}
});
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
});
});
});