12ec14af7b
- Füge Documents, Recipes und Birthdays zu Feature-Grid hinzu (8 statt 6 Features für ausgewogene 4+4 Darstellung) - Aktualisiere Calendar-Sync-Beschreibung mit CalDAV-Anbietern und ICS-Subscriptions - Aktualisiere Budget (15 Währungen, Loan-Tracking), Contacts (CardDAV-Sync), Notes (Markdown-Support) - Entferne Kanban Board aus Grid (bereits Teil von Task Management) - Ergänze alle Übersetzungen (EN/DE) für neue und aktualisierte Features Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
728 lines
46 KiB
HTML
Executable File
728 lines
46 KiB
HTML
Executable File
<!DOCTYPE html><html lang="en"><head>
|
|
|
|
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Oikos — The Self-Hosted Family Planner</title>
|
|
<meta name="description" content="A privacy-first, self-hosted family planner with tasks, shopping lists, meal planning, calendar sync, budget tracking, and more.">
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:title" content="Oikos — The Self-Hosted Family Planner">
|
|
<meta property="og:description" content="Tasks, shopping, meals, calendar, budget — all self-hosted, no cloud dependency.">
|
|
<meta property="og:image" content="https://ulsklyc.github.io/oikos/og-image.png">
|
|
<meta property="og:url" content="https://ulsklyc.github.io/oikos/">
|
|
<meta name="twitter:card" content="summary_large_image">
|
|
<link rel="icon" type="image/svg+xml" href="logo.svg">
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300..800;1,9..40,300..800&family=DM+Serif+Display&display=swap" rel="stylesheet">
|
|
<style>
|
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
|
|
:root {
|
|
--ff-display: 'DM Serif Display', Georgia, serif;
|
|
--ff-body: 'DM Sans', system-ui, -apple-system, sans-serif;
|
|
--bg: #FAFAFB;
|
|
--bg-alt: #F2F1F6;
|
|
--surface: #FFFFFF;
|
|
--border: #E5E4EA;
|
|
--text-1: #181620;
|
|
--text-2: #5E5C6B;
|
|
--text-3: #8F8D9A;
|
|
--accent: #6C3AED;
|
|
--accent-hover: #5B21B6;
|
|
--accent-soft: #EDE9FE;
|
|
--accent-glow: rgba(108, 58, 237, 0.12);
|
|
--blue: #0A84FF;
|
|
--code-bg: #1C1B22;
|
|
--code-text: #E2E1EC;
|
|
--radius: 16px;
|
|
--shadow-card: 0 1px 3px rgba(0,0,0,0.04), 0 4px 12px rgba(0,0,0,0.03);
|
|
--shadow-lg: 0 8px 32px rgba(0,0,0,0.08);
|
|
--shadow-hero: 0 20px 60px rgba(0,0,0,0.12), 0 4px 16px rgba(0,0,0,0.06);
|
|
}
|
|
|
|
[data-theme="dark"] {
|
|
--bg: #1A1A18;
|
|
--bg-alt: #141413;
|
|
--surface: #222220;
|
|
--border: #2A2A28;
|
|
--text-1: #F5F4F1;
|
|
--text-2: #AEADB0;
|
|
--text-3: #8E8D89;
|
|
--accent: #818CF8;
|
|
--accent-hover: #6366F1;
|
|
--accent-soft: #2E2D5B;
|
|
--accent-glow: rgba(129, 140, 248, 0.15);
|
|
--code-bg: #141413;
|
|
--code-text: #E2E1DC;
|
|
--shadow-card: 0 1px 3px rgba(0,0,0,0.25);
|
|
--shadow-lg: 0 8px 24px rgba(0,0,0,0.45);
|
|
--shadow-hero: 0 20px 60px rgba(0,0,0,0.55);
|
|
}
|
|
|
|
@media (prefers-color-scheme: dark) {
|
|
:root:not([data-theme="light"]) {
|
|
--bg: #1A1A18; --bg-alt: #141413; --surface: #222220; --border: #2A2A28;
|
|
--text-1: #F5F4F1; --text-2: #AEADB0; --text-3: #8E8D89;
|
|
--accent: #818CF8; --accent-hover: #6366F1; --accent-soft: #2E2D5B;
|
|
--accent-glow: rgba(129, 140, 248, 0.15);
|
|
--code-bg: #141413; --code-text: #E2E1DC;
|
|
--shadow-card: 0 1px 3px rgba(0,0,0,0.25); --shadow-lg: 0 8px 24px rgba(0,0,0,0.45);
|
|
--shadow-hero: 0 20px 60px rgba(0,0,0,0.55);
|
|
}
|
|
}
|
|
|
|
html { scroll-behavior: smooth; }
|
|
body {
|
|
font-family: var(--ff-body);
|
|
background: var(--bg);
|
|
color: var(--text-1);
|
|
line-height: 1.6;
|
|
-webkit-font-smoothing: antialiased;
|
|
overflow-x: hidden;
|
|
}
|
|
a { color: var(--accent); text-decoration: none; }
|
|
img { max-width: 100%; height: auto; display: block; }
|
|
|
|
.wrap { max-width: 1200px; margin: 0 auto; padding: 0 24px; }
|
|
|
|
/* ===== NAV ===== */
|
|
nav {
|
|
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
|
|
background: color-mix(in srgb, var(--bg) 80%, transparent);
|
|
backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
|
|
border-bottom: 1px solid var(--border);
|
|
height: 60px;
|
|
}
|
|
nav .wrap { display: flex; align-items: center; justify-content: space-between; height: 100%; }
|
|
.nav-logo { display: flex; align-items: center; gap: 10px; font-family: var(--ff-display); font-size: 1.3rem; color: var(--text-1); }
|
|
.nav-logo svg { width: 32px; height: 32px; }
|
|
.nav-right { display: flex; align-items: center; gap: 8px; }
|
|
.nav-btn {
|
|
background: none; border: 1px solid var(--border); color: var(--text-2);
|
|
cursor: pointer; padding: 7px 12px; border-radius: 10px; font-size: 0.8125rem;
|
|
font-family: var(--ff-body); display: flex; align-items: center; gap: 5px;
|
|
transition: all 0.15s ease;
|
|
}
|
|
.nav-btn:hover { background: var(--surface); color: var(--text-1); border-color: var(--text-3); }
|
|
.nav-btn svg { width: 16px; height: 16px; }
|
|
.nav-gh {
|
|
background: var(--text-1); color: var(--bg); border-color: var(--text-1); font-weight: 600;
|
|
}
|
|
.nav-gh:hover { opacity: 0.85; color: var(--bg); }
|
|
|
|
/* ===== HERO ===== */
|
|
.hero {
|
|
padding: 140px 0 80px;
|
|
position: relative;
|
|
}
|
|
.hero::before {
|
|
content: ''; position: absolute; top: -200px; left: 50%; transform: translateX(-50%);
|
|
width: 900px; height: 900px;
|
|
background: radial-gradient(ellipse at center, var(--accent-glow) 0%, transparent 65%);
|
|
pointer-events: none;
|
|
}
|
|
.hero > * { position: relative; }
|
|
.hero .wrap { display: grid; grid-template-columns: 1fr 520px; gap: 64px; align-items: center; }
|
|
.hero-content { text-align: left; }
|
|
.hero-badge {
|
|
display: inline-flex; align-items: center; gap: 6px;
|
|
padding: 6px 16px; border-radius: 999px; font-size: 0.8125rem; font-weight: 500;
|
|
background: var(--accent-soft); color: var(--accent); margin-bottom: 24px;
|
|
}
|
|
.hero h1 {
|
|
font-family: var(--ff-display); font-size: clamp(2.5rem, 5vw, 3.8rem);
|
|
font-weight: 400; line-height: 1.1; letter-spacing: -0.02em; margin-bottom: 20px;
|
|
}
|
|
.hero h1 em { font-style: italic; color: var(--accent); }
|
|
.hero-sub {
|
|
font-size: clamp(1.05rem, 2vw, 1.2rem); color: var(--text-2);
|
|
max-width: 520px; margin: 0 0 36px; line-height: 1.7;
|
|
}
|
|
.hero-actions { display: flex; justify-content: flex-start; gap: 12px; flex-wrap: wrap; }
|
|
.btn-primary {
|
|
display: inline-flex; align-items: center; gap: 8px;
|
|
background: var(--accent); color: #fff; padding: 14px 28px;
|
|
border-radius: 12px; font-weight: 600; font-size: 1rem;
|
|
transition: all 0.2s ease; box-shadow: 0 2px 8px var(--accent-glow);
|
|
}
|
|
.btn-primary:hover { background: var(--accent-hover); transform: translateY(-1px); box-shadow: 0 4px 16px var(--accent-glow); }
|
|
.btn-secondary {
|
|
display: inline-flex; align-items: center; gap: 8px;
|
|
background: var(--surface); color: var(--text-1); padding: 14px 28px;
|
|
border-radius: 12px; font-weight: 600; font-size: 1rem; border: 1px solid var(--border);
|
|
transition: all 0.2s ease;
|
|
}
|
|
.btn-secondary:hover { border-color: var(--text-3); transform: translateY(-1px); }
|
|
.btn-primary svg, .btn-secondary svg { width: 18px; height: 18px; }
|
|
.hero-tags {
|
|
display: flex; justify-content: flex-start; gap: 8px; margin-top: 20px; flex-wrap: wrap;
|
|
}
|
|
.tag {
|
|
padding: 4px 12px; border-radius: 999px; font-size: 0.75rem; font-weight: 500;
|
|
background: var(--surface); color: var(--text-3); border: 1px solid var(--border);
|
|
}
|
|
|
|
/* ===== HERO MOCKUP ===== */
|
|
.hero-mockup {
|
|
position: relative; perspective: 1200px;
|
|
}
|
|
.mockup-tablet {
|
|
width: 100%; max-width: 520px; border-radius: 16px; overflow: hidden;
|
|
box-shadow: var(--shadow-hero); border: 1px solid var(--border);
|
|
transform: rotateY(2deg) rotateX(2deg);
|
|
transition: transform 0.4s ease;
|
|
}
|
|
.mockup-tablet:hover { transform: rotateY(0) rotateX(0); }
|
|
.mockup-tablet img { width: 100%; display: block; }
|
|
|
|
/* ===== FEATURES SHOWCASE ===== */
|
|
.showcase { padding: 100px 0; }
|
|
.showcase-header { text-align: center; margin-bottom: 64px; }
|
|
.section-label {
|
|
font-size: 0.8125rem; font-weight: 600; text-transform: uppercase;
|
|
letter-spacing: 0.06em; color: var(--accent); margin-bottom: 8px;
|
|
}
|
|
.section-title {
|
|
font-family: var(--ff-display); font-size: clamp(1.8rem, 4vw, 2.8rem);
|
|
font-weight: 400; line-height: 1.15; margin-bottom: 12px;
|
|
}
|
|
.section-desc { font-size: 1.0625rem; color: var(--text-2); max-width: 520px; margin: 0 auto; line-height: 1.7; }
|
|
|
|
/* Feature rows */
|
|
.feat-row {
|
|
display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: center;
|
|
margin-bottom: 80px;
|
|
}
|
|
.feat-row.reverse .feat-visual { order: -1; }
|
|
.feat-info { max-width: 460px; }
|
|
.feat-info h3 {
|
|
font-family: var(--ff-display); font-size: 1.6rem; font-weight: 400; margin-bottom: 12px;
|
|
}
|
|
.feat-info p { color: var(--text-2); font-size: 0.9375rem; line-height: 1.7; }
|
|
.feat-visual { position: relative; }
|
|
.feat-visual img {
|
|
border-radius: var(--radius); box-shadow: var(--shadow-lg);
|
|
border: 1px solid var(--border);
|
|
}
|
|
.feat-mobile-img {
|
|
width: 160px !important; border-radius: 20px !important;
|
|
border: 3px solid var(--text-1) !important;
|
|
position: absolute; bottom: -24px; right: -24px; z-index: 2;
|
|
}
|
|
|
|
/* ===== FEATURE GRID ===== */
|
|
.features-alt { background: var(--bg-alt); padding: 100px 0; }
|
|
.feat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; }
|
|
.feat-card {
|
|
background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
|
|
padding: 28px; transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
}
|
|
.feat-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
|
|
.feat-card-icon {
|
|
width: 44px; height: 44px; border-radius: 12px; display: flex; align-items: center;
|
|
justify-content: center; margin-bottom: 16px; background: var(--accent-soft); color: var(--accent);
|
|
}
|
|
.feat-card-icon svg { width: 22px; height: 22px; }
|
|
.feat-card h3 { font-size: 1rem; font-weight: 600; margin-bottom: 6px; }
|
|
.feat-card p { font-size: 0.8375rem; color: var(--text-2); line-height: 1.6; }
|
|
|
|
/* ===== PHILOSOPHY ===== */
|
|
.philosophy { padding: 100px 0; }
|
|
.phil-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px; }
|
|
.phil-card {
|
|
display: flex; gap: 16px; padding: 28px; border-radius: var(--radius);
|
|
background: var(--surface); border: 1px solid var(--border);
|
|
}
|
|
.phil-icon {
|
|
flex-shrink: 0; width: 44px; height: 44px; border-radius: 12px;
|
|
display: flex; align-items: center; justify-content: center;
|
|
background: var(--accent-soft); color: var(--accent);
|
|
}
|
|
.phil-icon svg { width: 20px; height: 20px; }
|
|
.phil-card h3 { font-size: 0.9375rem; font-weight: 600; margin-bottom: 4px; }
|
|
.phil-card p { font-size: 0.8375rem; color: var(--text-2); line-height: 1.6; }
|
|
|
|
/* ===== SETUP ===== */
|
|
.setup { background: var(--bg-alt); padding: 100px 0; }
|
|
.setup-inner { max-width: 680px; }
|
|
.code-block {
|
|
background: var(--code-bg); color: var(--code-text); border-radius: var(--radius);
|
|
padding: 24px 28px; font-family: 'SF Mono', 'Fira Code', monospace;
|
|
font-size: 0.8125rem; line-height: 2; overflow-x: auto; margin: 24px 0;
|
|
}
|
|
.code-block .c { color: #706F80; }
|
|
.code-block .h { color: var(--accent); }
|
|
.setup-note { font-size: 0.875rem; color: var(--text-2); line-height: 1.7; }
|
|
.setup-note code { background: var(--surface); padding: 2px 6px; border-radius: 5px; font-size: 0.8125rem; border: 1px solid var(--border); }
|
|
|
|
/* ===== SCREENSHOT CAROUSEL ===== */
|
|
.carousel-section { padding: 100px 0; overflow: hidden; }
|
|
.carousel-track {
|
|
display: flex; gap: 20px; overflow-x: auto; padding: 8px 24px 24px;
|
|
scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
|
|
scrollbar-width: none;
|
|
}
|
|
.carousel-track::-webkit-scrollbar { display: none; }
|
|
.carousel-item {
|
|
flex: 0 0 auto; scroll-snap-align: center; text-align: center;
|
|
}
|
|
.carousel-item img {
|
|
height: 440px; width: auto; border-radius: 20px;
|
|
box-shadow: var(--shadow-lg); border: 3px solid var(--text-1);
|
|
}
|
|
.carousel-item span {
|
|
display: block; margin-top: 12px; font-size: 0.8125rem;
|
|
font-weight: 500; color: var(--text-3);
|
|
}
|
|
|
|
/* ===== CTA ===== */
|
|
.cta-section {
|
|
padding: 100px 0; text-align: center;
|
|
}
|
|
.cta-box {
|
|
background: var(--accent-soft); border: 1px solid color-mix(in srgb, var(--accent) 20%, transparent);
|
|
border-radius: 24px; padding: 64px 40px; max-width: 720px; margin: 0 auto;
|
|
}
|
|
.cta-box h2 { font-family: var(--ff-display); font-size: clamp(1.5rem, 3.5vw, 2.2rem); margin-bottom: 12px; }
|
|
.cta-box p { color: var(--text-2); margin-bottom: 28px; max-width: 420px; margin-left: auto; margin-right: auto; }
|
|
|
|
/* ===== FOOTER ===== */
|
|
footer {
|
|
border-top: 1px solid var(--border); padding: 40px 0; text-align: center;
|
|
}
|
|
footer p { font-size: 0.875rem; color: var(--text-2); margin-bottom: 12px; }
|
|
.footer-links { display: flex; justify-content: center; gap: 24px; font-size: 0.8125rem; }
|
|
.footer-links a { color: var(--text-3); }
|
|
.footer-links a:hover { color: var(--accent); }
|
|
|
|
/* ===== ANIMATIONS ===== */
|
|
.reveal { opacity: 0; transform: translateY(24px); transition: opacity 0.6s ease, transform 0.6s ease; }
|
|
.reveal.vis { opacity: 1; transform: none; }
|
|
.reveal-d1 { transition-delay: 0.1s; }
|
|
.reveal-d2 { transition-delay: 0.2s; }
|
|
.reveal-d3 { transition-delay: 0.3s; }
|
|
|
|
/* ===== RESPONSIVE ===== */
|
|
@media (max-width: 1024px) {
|
|
.hero .wrap { grid-template-columns: 1fr; gap: 48px; }
|
|
.hero-content { text-align: center; }
|
|
.hero-sub { margin: 0 auto 36px; }
|
|
.hero-actions { justify-content: center; }
|
|
.hero-tags { justify-content: center; }
|
|
.mockup-tablet { max-width: 640px; margin: 0 auto; }
|
|
}
|
|
@media (max-width: 900px) {
|
|
.feat-row { grid-template-columns: 1fr; gap: 32px; }
|
|
.feat-row.reverse .feat-visual { order: 0; }
|
|
.feat-mobile-img { width: 120px !important; bottom: -16px; right: -8px; }
|
|
.phil-grid { grid-template-columns: 1fr; }
|
|
}
|
|
@media (max-width: 600px) {
|
|
.hero { padding: 110px 0 60px; }
|
|
.carousel-item img { height: 360px; }
|
|
.feat-grid { grid-template-columns: 1fr; }
|
|
.cta-box { padding: 40px 24px; }
|
|
.nav-gh span { display: none; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<nav>
|
|
<div class="wrap">
|
|
<a href="#" class="nav-logo">
|
|
<svg viewBox="0 0 160 160" fill="none"><defs><linearGradient id="g" x1="0" y1="0" x2="160" y2="160" gradientUnits="userSpaceOnUse"><stop offset="0%" stop-color="#8B5CF6"></stop><stop offset="100%" stop-color="#6C3AED"></stop></linearGradient></defs><rect width="160" height="160" rx="36" fill="url(#g)"></rect><path d="M80 36L36 72V120C36 122.2 37.8 124 40 124H68V96H92V124H120C122.2 124 124 122.2 124 120V72L80 36Z" fill="white"></path><rect x="100" y="46" width="12" height="22" rx="2" fill="white"></rect></svg>
|
|
Oikos
|
|
</a>
|
|
<div class="nav-right">
|
|
<button class="nav-btn" id="langBtn" type="button"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><path d="M2 12h20"></path><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10A15.3 15.3 0 0 1 12 2z"></path></svg><span id="langLbl">DE</span></button>
|
|
<button class="nav-btn" id="themeBtn" type="button"><svg id="sunIco" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display: none;"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></svg><svg id="moonIco" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display: block; width: 16px; height: 16px;"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg></button>
|
|
<a href="https://github.com/ulsklyc/oikos" class="nav-btn nav-gh" target="_blank" rel="noopener"><svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z"></path></svg><span data-t="nav_gh">GitHub</span></a>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- HERO -->
|
|
<header class="hero">
|
|
<div class="wrap">
|
|
<div class="hero-content">
|
|
<div class="hero-badge" data-t="hero_badge">Open Source · Self-Hosted · Private</div>
|
|
<h1><span data-t="hero_h1_pre">Your household,</span><br><em data-t="hero_h1_em">organized together.</em></h1>
|
|
<p class="hero-sub" data-t="hero_sub">Tasks, shopping, meals, calendar, budget — everything your family needs in one place. Self-hosted on your own server. No cloud, no tracking, no subscriptions.</p>
|
|
<div class="hero-actions">
|
|
<a href="https://github.com/ulsklyc/oikos" class="btn-primary" target="_blank" rel="noopener">
|
|
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z"></path></svg>
|
|
<span data-t="hero_cta">View on GitHub</span>
|
|
</a>
|
|
<a href="install.html" class="btn-secondary">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>
|
|
<span data-t="hero_install">Installation Guide</span>
|
|
</a>
|
|
</div>
|
|
<div class="hero-tags">
|
|
<span class="tag">MIT License</span>
|
|
<span class="tag">Docker</span>
|
|
<span class="tag">PWA</span>
|
|
<span class="tag" data-t="tag_nocloud">No Cloud Required</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="hero-mockup">
|
|
<div class="mockup-tablet">
|
|
<img class="sc" data-light="screenshots/01-web-light.png" data-dark="screenshots/01-web-dark.png" src="screenshots/01-web-light.png" alt="Oikos Dashboard">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- YOUR DATA. YOUR PRIVATE PLACE -->
|
|
<section class="features-alt">
|
|
<div class="wrap">
|
|
<div class="showcase-header reveal vis">
|
|
<p class="section-label" data-t="more_label">Your Data. Your Private Place</p>
|
|
<h2 class="section-title" data-t="more_title">Built for real family life</h2>
|
|
</div>
|
|
<div class="feat-grid">
|
|
<div class="feat-card reveal vis">
|
|
<div class="feat-card-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path></svg></div>
|
|
<h3 data-t="f_shop_t">Shopping Lists</h3>
|
|
<p data-t="f_shop_d">Collaborative lists with aisle categories. Import ingredients directly from your meal plans.</p>
|
|
</div>
|
|
<div class="feat-card reveal reveal-d1 vis">
|
|
<div class="feat-card-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line></svg></div>
|
|
<h3 data-t="f_docs_t">Documents</h3>
|
|
<p data-t="f_docs_d">Upload and manage family files with 14 category tags, per-document visibility, and drag-and-drop support.</p>
|
|
</div>
|
|
<div class="feat-card reveal reveal-d2 vis">
|
|
<div class="feat-card-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 2v7c0 1.1.9 2 2 2h4a2 2 0 0 0 2-2V2"></path><path d="M7 2v20"></path><path d="M21 15V2v0a5 5 0 0 0-5 5v6c0 1.1.9 2 2 2h3Zm0 0v7"></path></svg></div>
|
|
<h3 data-t="f_recipes_t">Recipes</h3>
|
|
<p data-t="f_recipes_d">Create, duplicate, and scale reusable recipes. Pre-fill meal slots or save any meal as a recipe.</p>
|
|
</div>
|
|
<div class="feat-card reveal reveal-d3 vis">
|
|
<div class="feat-card-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="7" width="20" height="15" rx="2" ry="2"></rect><polyline points="17 2 12 7 7 2"></polyline></svg></div>
|
|
<h3 data-t="f_birthdays_t">Birthdays</h3>
|
|
<p data-t="f_birthdays_d">Birthday tracker with automatic annual calendar events, age display, and 1-day-before reminders.</p>
|
|
</div>
|
|
<div class="feat-card reveal vis">
|
|
<div class="feat-card-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="1" x2="12" y2="23"></line><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"></path></svg></div>
|
|
<h3 data-t="f_budget_t">Budget Tracking</h3>
|
|
<p data-t="f_budget_d">Track income and expenses with 15 currency options, recurring entries, loan tracking, and CSV export.</p>
|
|
</div>
|
|
<div class="feat-card reveal reveal-d1 vis">
|
|
<div class="feat-card-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="12" y1="11" x2="12" y2="17"></line><line x1="12" y1="11" x2="12" y2="17"></line><polyline points="9 14 12 17 15 14"></polyline></svg></div>
|
|
<h3 data-t="f_notes_t">Notes</h3>
|
|
<p data-t="f_notes_d">Colored sticky notes with Markdown support. Perfect for recipes, family memos, and quick reminders.</p>
|
|
</div>
|
|
<div class="feat-card reveal reveal-d2 vis">
|
|
<div class="feat-card-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path></svg></div>
|
|
<h3 data-t="f_contacts_t">Contacts</h3>
|
|
<p data-t="f_contacts_d">Shared family contact directory with CardDAV sync, vCard import/export, and multi-account support.</p>
|
|
</div>
|
|
<div class="feat-card reveal reveal-d3 vis">
|
|
<div class="feat-card-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect><line x1="8" y1="21" x2="16" y2="21"></line><line x1="12" y1="17" x2="12" y2="21"></line></svg></div>
|
|
<h3 data-t="f_pwa_t">Works Everywhere</h3>
|
|
<p data-t="f_pwa_d">Installable PWA on any device. Offline support, dark mode, fully responsive from phone to desktop.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- FEATURE SHOWCASE -->
|
|
<section class="showcase">
|
|
<div class="wrap">
|
|
<div class="showcase-header reveal vis">
|
|
<p class="section-label" data-t="feat_label">Features</p>
|
|
<h2 class="section-title" data-t="feat_title">Everything your household needs</h2>
|
|
<p class="section-desc" data-t="feat_desc">A complete set of tools designed for families — seamlessly working together.</p>
|
|
</div>
|
|
|
|
<div class="feat-row reveal vis">
|
|
<div class="feat-info">
|
|
<h3 data-t="f_tasks_t">Task Management</h3>
|
|
<p data-t="f_tasks_d">Shared tasks with deadlines, priorities, subtasks, recurring schedules, and a Kanban board. Assign to family members with one-tap status changes.</p>
|
|
</div>
|
|
<div class="feat-visual">
|
|
<img class="sc" data-light="screenshots/02-web-light.png" data-dark="screenshots/02-web-dark.png" src="screenshots/02-web-light.png" alt="Tasks">
|
|
<img class="sc feat-mobile-img" data-light="screenshots/02-mobile-light.png" data-dark="screenshots/02-mobile-dark.png" src="screenshots/02-mobile-light.png" alt="Tasks Mobile">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="feat-row reverse reveal vis">
|
|
<div class="feat-info">
|
|
<h3 data-t="f_meals_t">Meal Planning</h3>
|
|
<p data-t="f_meals_d">Weekly drag-and-drop planner with ingredient lists. Automatically export ingredients to your shopping list with one click.</p>
|
|
</div>
|
|
<div class="feat-visual">
|
|
<img class="sc" data-light="screenshots/04-web-light.png" data-dark="screenshots/04-web-dark.png" src="screenshots/04-web-light.png" alt="Meals">
|
|
<img class="sc feat-mobile-img" data-light="screenshots/04-mobile-light.png" data-dark="screenshots/04-mobile-dark.png" src="screenshots/04-mobile-light.png" alt="Meals Mobile" style="left:-24px;right:auto">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="feat-row reveal vis">
|
|
<div class="feat-info">
|
|
<h3 data-t="f_cal_t">Calendar Sync</h3>
|
|
<p data-t="f_cal_d">Two-way sync with Google Calendar and CalDAV providers (iCloud, Nextcloud, Radicale). Subscribe to public ICS calendars. File attachments support for events.</p>
|
|
</div>
|
|
<div class="feat-visual">
|
|
<img class="sc" data-light="screenshots/05-web-light.png" data-dark="screenshots/05-web-dark.png" src="screenshots/05-web-light.png" alt="Calendar">
|
|
<img class="sc feat-mobile-img" data-light="screenshots/03-mobile-light.png" data-dark="screenshots/03-mobile-dark.png" src="screenshots/03-mobile-light.png" alt="Calendar Mobile">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ALL SCREENS CAROUSEL -->
|
|
<section class="carousel-section">
|
|
<div class="wrap">
|
|
<div class="showcase-header reveal vis">
|
|
<p class="section-label" data-t="screens_label">Preview</p>
|
|
<h2 class="section-title" data-t="screens_title">Every screen, beautifully crafted</h2>
|
|
<p class="section-desc" data-t="screens_desc">A clean, intuitive interface that adapts to your device and preferred theme.</p>
|
|
</div>
|
|
</div>
|
|
<div class="carousel-track">
|
|
<div class="carousel-item"><img class="sc" data-light="screenshots/01-mobile-light.png" data-dark="screenshots/01-mobile-dark.png" src="screenshots/01-mobile-light.png" alt="Dashboard"><span>Dashboard</span></div>
|
|
<div class="carousel-item"><img class="sc" data-light="screenshots/02-mobile-light.png" data-dark="screenshots/02-mobile-dark.png" src="screenshots/02-mobile-light.png" alt="Tasks"><span data-t="f_tasks_t2">Tasks</span></div>
|
|
<div class="carousel-item"><img class="sc" data-light="screenshots/03-mobile-light.png" data-dark="screenshots/03-mobile-dark.png" src="screenshots/03-mobile-light.png" alt="Calendar"><span data-t="f_cal_t2">Calendar</span></div>
|
|
<div class="carousel-item"><img class="sc" data-light="screenshots/04-mobile-light.png" data-dark="screenshots/04-mobile-dark.png" src="screenshots/04-mobile-light.png" alt="Shopping"><span data-t="f_shop_t2">Shopping</span></div>
|
|
<div class="carousel-item"><img class="sc" data-light="screenshots/05-mobile-light.png" data-dark="screenshots/05-mobile-dark.png" src="screenshots/05-mobile-light.png" alt="Meals"><span data-t="f_meals_t2">Meals</span></div>
|
|
<div class="carousel-item"><img class="sc" data-light="screenshots/06-mobile-light.png" data-dark="screenshots/06-mobile-dark.png" src="screenshots/06-mobile-light.png" alt="Budget"><span data-t="f_budget_t2">Budget</span></div>
|
|
<div class="carousel-item"><img class="sc" data-light="screenshots/07-mobile-light.png" data-dark="screenshots/07-mobile-dark.png" src="screenshots/07-mobile-light.png" alt="Notes"><span data-t="f_notes_t2">Notes</span></div>
|
|
<div class="carousel-item"><img class="sc" data-light="screenshots/08-mobile-light.png" data-dark="screenshots/08-mobile-dark.png" src="screenshots/08-mobile-light.png" alt="Contacts"><span data-t="f_contacts_t2">Contacts</span></div>
|
|
<div class="carousel-item"><img class="sc" data-light="screenshots/09-mobile-light.png" data-dark="screenshots/09-mobile-dark.png" src="screenshots/09-mobile-light.png" alt="Settings"><span data-t="f_settings_t">Settings</span></div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- PHILOSOPHY -->
|
|
<section class="philosophy">
|
|
<div class="wrap">
|
|
<div class="showcase-header reveal vis">
|
|
<p class="section-label" data-t="phil_label">Philosophy</p>
|
|
<h2 class="section-title" data-t="phil_title">Built different, on purpose</h2>
|
|
<p class="section-desc" data-t="phil_desc">No subscriptions, no vendor lock-in, no data leaving your home.</p>
|
|
</div>
|
|
<div class="phil-grid">
|
|
<div class="phil-card reveal vis">
|
|
<div class="phil-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg></div>
|
|
<div>
|
|
<h3 data-t="p_priv_t">Privacy First</h3>
|
|
<p data-t="p_priv_d">AES-256 encrypted database with SQLCipher. Zero telemetry. Your data never leaves your server.</p>
|
|
</div>
|
|
</div>
|
|
<div class="phil-card reveal reveal-d1 vis">
|
|
<div class="phil-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="8" rx="2" ry="2"></rect><rect x="2" y="14" width="20" height="8" rx="2" ry="2"></rect><line x1="6" y1="6" x2="6.01" y2="6"></line><line x1="6" y1="18" x2="6.01" y2="18"></line></svg></div>
|
|
<div>
|
|
<h3 data-t="p_self_t">Fully Self-Hosted</h3>
|
|
<p data-t="p_self_d">Runs on a Raspberry Pi, a NAS, or any server. Docker makes setup a one-liner.</p>
|
|
</div>
|
|
</div>
|
|
<div class="phil-card reveal reveal-d2 vis">
|
|
<div class="phil-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"></path></svg></div>
|
|
<div>
|
|
<h3 data-t="p_build_t">Zero Build Step</h3>
|
|
<p data-t="p_build_d">Pure ES modules, vanilla JS, plain CSS. No bundler, no transpiler, no framework. Ships what you write.</p>
|
|
</div>
|
|
</div>
|
|
<div class="phil-card reveal reveal-d3 vis">
|
|
<div class="phil-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"></path><line x1="4" y1="22" x2="4" y2="15"></line></svg></div>
|
|
<div>
|
|
<h3 data-t="p_open_t">Open Source</h3>
|
|
<p data-t="p_open_d">MIT licensed. Inspect, modify, extend, contribute. Built in the open for families who care about transparency.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- SETUP -->
|
|
<section class="setup" id="setup">
|
|
<div class="wrap">
|
|
<div class="section-label reveal vis" data-t="setup_label">Get Started</div>
|
|
<h2 class="section-title reveal vis" data-t="setup_title">Up and running in minutes</h2>
|
|
<div class="setup-inner reveal vis">
|
|
<div class="code-block"><span class="c"># Pull and start with Docker</span>
|
|
curl -O https://raw.githubusercontent.com/ulsklyc/oikos/main/docker-compose.yml
|
|
curl -O https://raw.githubusercontent.com/ulsklyc/oikos/main/.env.example
|
|
cp .env.example .env
|
|
<span class="c"># Set SESSION_SECRET and DB_ENCRYPTION_KEY in .env</span>
|
|
<span class="h">docker compose up -d</span>
|
|
<span class="h">docker compose exec oikos node setup.js</span></div>
|
|
<p class="setup-note" data-t="setup_note">Then open <code>http://localhost:3000</code> and log in. Need a step-by-step guide, HTTPS setup, or troubleshooting? See the <a href="https://github.com/ulsklyc/oikos/blob/main/docs/installation.md" target="_blank" rel="noopener">Installation Guide</a>.</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- CTA -->
|
|
<section class="cta-section">
|
|
<div class="wrap">
|
|
<div class="cta-box reveal vis">
|
|
<h2 data-t="cta_title">Ready to take back control?</h2>
|
|
<p data-t="cta_desc">Oikos is free, open-source, and built for families who value their privacy.</p>
|
|
<div class="hero-actions">
|
|
<a href="https://github.com/ulsklyc/oikos" class="btn-primary" target="_blank" rel="noopener">
|
|
<svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z"></path></svg>
|
|
<span data-t="cta_btn">Get Started on GitHub</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<footer>
|
|
<div class="wrap">
|
|
<p data-t="footer_heart">Built with care for families who value privacy and simplicity.</p>
|
|
<div class="footer-links">
|
|
<a href="https://github.com/ulsklyc/oikos" target="_blank" rel="noopener">GitHub</a>
|
|
<a href="https://github.com/ulsklyc/oikos/blob/main/LICENSE" target="_blank" rel="noopener">MIT License</a>
|
|
<a href="https://github.com/ulsklyc/oikos/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener" data-t="footer_contrib">Contributing</a>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
|
|
<script>
|
|
(function(){
|
|
'use strict';
|
|
|
|
var T = {
|
|
en: {
|
|
nav_gh:'GitHub', hero_badge:'Open Source · Self-Hosted · Private',
|
|
hero_h1_pre:'Your household,', hero_h1_em:'organized together.',
|
|
hero_sub:'Tasks, shopping, meals, calendar, budget — everything your family needs in one place. Self-hosted on your own server. No cloud, no tracking, no subscriptions.',
|
|
hero_cta:'View on GitHub', hero_install:'Installation Guide', tag_nocloud:'No Cloud Required',
|
|
feat_label:'Features', feat_title:'Everything your household needs',
|
|
feat_desc:'A complete set of tools designed for families — seamlessly working together.',
|
|
f_tasks_t:'Task Management', f_tasks_d:'Shared tasks with deadlines, priorities, subtasks, recurring schedules, and a Kanban board. Assign to family members with one-tap status changes.',
|
|
f_meals_t:'Meal Planning', f_meals_d:'Weekly drag-and-drop planner with ingredient lists. Automatically export ingredients to your shopping list with one click.',
|
|
f_cal_t:'Calendar Sync', f_cal_d:'Two-way sync with Google Calendar and CalDAV providers (iCloud, Nextcloud, Radicale). Subscribe to public ICS calendars. File attachments support for events.',
|
|
more_label:'Your Data. Your Private Place', more_title:'Built for real family life',
|
|
f_shop_t:'Shopping Lists', f_shop_d:'Collaborative lists with aisle categories. Import ingredients directly from your meal plans.',
|
|
f_docs_t:'Documents', f_docs_d:'Upload and manage family files with 14 category tags, per-document visibility, and drag-and-drop support.',
|
|
f_recipes_t:'Recipes', f_recipes_d:'Create, duplicate, and scale reusable recipes. Pre-fill meal slots or save any meal as a recipe.',
|
|
f_birthdays_t:'Birthdays', f_birthdays_d:'Birthday tracker with automatic annual calendar events, age display, and 1-day-before reminders.',
|
|
f_budget_t:'Budget Tracking', f_budget_d:'Track income and expenses with 15 currency options, recurring entries, loan tracking, and CSV export.',
|
|
f_notes_t:'Notes', f_notes_d:'Colored sticky notes with Markdown support. Perfect for recipes, family memos, and quick reminders.',
|
|
f_contacts_t:'Contacts', f_contacts_d:'Shared family contact directory with CardDAV sync, vCard import/export, and multi-account support.',
|
|
f_pwa_t:'Works Everywhere', f_pwa_d:'Installable PWA on any device. Offline support, dark mode, fully responsive from phone to desktop.',
|
|
f_tasks_t2:'Tasks', f_cal_t2:'Calendar', f_shop_t2:'Shopping', f_meals_t2:'Meals',
|
|
f_budget_t2:'Budget', f_notes_t2:'Notes', f_contacts_t2:'Contacts', f_settings_t:'Settings',
|
|
screens_label:'Preview', screens_title:'Every screen, beautifully crafted',
|
|
screens_desc:'A clean, intuitive interface that adapts to your device and preferred theme.',
|
|
phil_label:'Philosophy', phil_title:'Built different, on purpose',
|
|
phil_desc:'No subscriptions, no vendor lock-in, no data leaving your home.',
|
|
p_priv_t:'Privacy First', p_priv_d:'AES-256 encrypted database with SQLCipher. Zero telemetry. Your data never leaves your server.',
|
|
p_self_t:'Fully Self-Hosted', p_self_d:'Runs on a Raspberry Pi, a NAS, or any server. Docker makes setup a one-liner.',
|
|
p_build_t:'Zero Build Step', p_build_d:'Pure ES modules, vanilla JS, plain CSS. No bundler, no transpiler, no framework. Ships what you write.',
|
|
p_open_t:'Open Source', p_open_d:'MIT licensed. Inspect, modify, extend, contribute. Built in the open for families who care about transparency.',
|
|
setup_label:'Get Started', setup_title:'Up and running in minutes',
|
|
setup_note:'Then open <code>http://localhost:3000</code> and log in. Need a step-by-step guide, HTTPS setup, or troubleshooting? See the <a href="https://github.com/ulsklyc/oikos/blob/main/docs/installation.md" target="_blank" rel="noopener">Installation Guide</a>.',
|
|
cta_title:'Ready to take back control?', cta_desc:'Oikos is free, open-source, and built for families who value their privacy.',
|
|
cta_btn:'Get Started on GitHub',
|
|
footer_heart:'Built with care for families who value privacy and simplicity.', footer_contrib:'Contributing'
|
|
},
|
|
de: {
|
|
nav_gh:'GitHub', hero_badge:'Open Source · Self-Hosted · Privat',
|
|
hero_h1_pre:'Euer Haushalt,', hero_h1_em:'gemeinsam organisiert.',
|
|
hero_sub:'Aufgaben, Einkauf, Mahlzeiten, Kalender, Budget — alles, was eure Familie braucht, an einem Ort. Selbstgehostet auf eurem eigenen Server. Keine Cloud, kein Tracking, keine Abos.',
|
|
hero_cta:'Auf GitHub ansehen', hero_install:'Installationsanleitung', tag_nocloud:'Keine Cloud nötig',
|
|
feat_label:'Funktionen', feat_title:'Alles, was euer Haushalt braucht',
|
|
feat_desc:'Ein vollständiges Werkzeugset für Familien — nahtlos aufeinander abgestimmt.',
|
|
f_tasks_t:'Aufgabenverwaltung', f_tasks_d:'Gemeinsame Aufgaben mit Fristen, Prioritäten, Unteraufgaben, wiederkehrenden Terminen und Kanban-Board mit Ein-Tipp-Status.',
|
|
f_meals_t:'Mahlzeitenplanung', f_meals_d:'Wöchentlicher Drag-and-Drop-Planer mit Zutatenlisten. Zutaten per Klick auf die Einkaufsliste exportieren.',
|
|
f_cal_t:'Kalender-Sync', f_cal_d:'Zwei-Wege-Sync mit Google Calendar und CalDAV-Anbietern (iCloud, Nextcloud, Radicale). Öffentliche ICS-Kalender abonnieren. Dateianhänge für Termine.',
|
|
more_label:'Deine Daten. Dein privater Raum', more_title:'Gebaut für echtes Familienleben',
|
|
f_shop_t:'Einkaufslisten', f_shop_d:'Gemeinsame Listen mit Gang-Kategorien. Zutaten direkt aus Mahlzeitenplänen importieren.',
|
|
f_docs_t:'Dokumente', f_docs_d:'Familiendateien verwalten mit 14 Kategorien, individueller Sichtbarkeit und Drag-and-Drop-Upload.',
|
|
f_recipes_t:'Rezepte', f_recipes_d:'Wiederverwendbare Rezepte erstellen, duplizieren und skalieren. Mahlzeiten vorausfüllen oder als Rezept speichern.',
|
|
f_birthdays_t:'Geburtstage', f_birthdays_d:'Geburtstags-Tracker mit automatischen jährlichen Kalendereinträgen, Altersanzeige und 1-Tages-Erinnerung.',
|
|
f_budget_t:'Budgetverwaltung', f_budget_d:'Einnahmen und Ausgaben verfolgen mit 15 Währungen, wiederkehrenden Einträgen, Kreditverwaltung und CSV-Export.',
|
|
f_notes_t:'Notizen', f_notes_d:'Farbige Haftnotizen mit Markdown-Support. Perfekt für Rezepte, Familien-Memos und schnelle Erinnerungen.',
|
|
f_contacts_t:'Kontakte', f_contacts_d:'Gemeinsames Familien-Kontaktverzeichnis mit CardDAV-Sync, vCard-Import/-Export und Multi-Account-Support.',
|
|
f_pwa_t:'Überall nutzbar', f_pwa_d:'Installierbare PWA auf jedem Gerät. Offline-Support, Dark Mode, voll responsive vom Handy bis Desktop.',
|
|
f_tasks_t2:'Aufgaben', f_cal_t2:'Kalender', f_shop_t2:'Einkauf', f_meals_t2:'Mahlzeiten',
|
|
f_budget_t2:'Budget', f_notes_t2:'Notizen', f_contacts_t2:'Kontakte', f_settings_t:'Einstellungen',
|
|
screens_label:'Vorschau', screens_title:'Jeder Screen, schön gestaltet',
|
|
screens_desc:'Eine klare, intuitive Oberfläche, die sich an euer Gerät und bevorzugtes Theme anpasst.',
|
|
phil_label:'Philosophie', phil_title:'Bewusst anders gebaut',
|
|
phil_desc:'Keine Abos, kein Vendor-Lock-in, keine Daten, die euer Zuhause verlassen.',
|
|
p_priv_t:'Datenschutz zuerst', p_priv_d:'AES-256-verschlüsselte Datenbank mit SQLCipher. Keine Telemetrie. Eure Daten verlassen nie euren Server.',
|
|
p_self_t:'Vollständig selbstgehostet', p_self_d:'Läuft auf einem Raspberry Pi, NAS oder jedem Server. Docker macht das Setup zum Einzeiler.',
|
|
p_build_t:'Kein Build-Schritt', p_build_d:'Pure ES-Module, Vanilla JS, reines CSS. Kein Bundler, kein Transpiler, kein Framework.',
|
|
p_open_t:'Open Source', p_open_d:'MIT-lizenziert. Einsehen, anpassen, erweitern, beitragen. Offen gebaut für Familien, die Transparenz schätzen.',
|
|
setup_label:'Loslegen', setup_title:'In Minuten einsatzbereit',
|
|
setup_note:'Dann <code>http://localhost:3000</code> öffnen und einloggen. Schritt-für-Schritt-Anleitung, HTTPS oder Hilfe bei Problemen? Zur <a href="https://github.com/ulsklyc/oikos/blob/main/docs/installation.md" target="_blank" rel="noopener">Installationsanleitung</a>.',
|
|
cta_title:'Bereit, die Kontrolle zurückzugewinnen?', cta_desc:'Oikos ist kostenlos, open-source und gebaut für Familien, die ihre Privatsphäre schätzen.',
|
|
cta_btn:'Auf GitHub starten',
|
|
footer_heart:'Mit Sorgfalt gebaut für Familien, die Privatsphäre und Einfachheit schätzen.', footer_contrib:'Mitmachen'
|
|
}
|
|
};
|
|
|
|
var lang = localStorage.getItem('oikos-lang') || 'en';
|
|
var theme = localStorage.getItem('oikos-theme');
|
|
|
|
function isDark() {
|
|
if (theme === 'dark') return true;
|
|
if (theme === 'light') return false;
|
|
return matchMedia('(prefers-color-scheme:dark)').matches;
|
|
}
|
|
|
|
function applyTheme() {
|
|
var d = isDark();
|
|
if (theme) document.documentElement.setAttribute('data-theme', theme);
|
|
else document.documentElement.removeAttribute('data-theme');
|
|
document.getElementById('sunIco').style.display = d ? 'none' : 'block';
|
|
document.getElementById('moonIco').style.display = d ? 'block' : 'none';
|
|
document.querySelectorAll('.sc').forEach(function(img) {
|
|
var v = d ? 'dark' : 'light';
|
|
if (img.dataset[v]) img.src = img.dataset[v];
|
|
});
|
|
}
|
|
|
|
function applyLang() {
|
|
document.documentElement.lang = lang;
|
|
var s = T[lang];
|
|
document.querySelectorAll('[data-t]').forEach(function(el) {
|
|
var k = el.getAttribute('data-t');
|
|
if (s[k]) {
|
|
if (k === 'setup_note') {
|
|
el.textContent = '';
|
|
el.insertAdjacentHTML('afterbegin', s[k]);
|
|
} else {
|
|
el.textContent = s[k];
|
|
}
|
|
}
|
|
});
|
|
document.getElementById('langLbl').textContent = lang === 'en' ? 'DE' : 'EN';
|
|
document.title = lang === 'en' ? 'Oikos — The Self-Hosted Family Planner' : 'Oikos — Der selbstgehostete Familienplaner';
|
|
}
|
|
|
|
document.getElementById('themeBtn').onclick = function() {
|
|
theme = isDark() ? 'light' : 'dark';
|
|
localStorage.setItem('oikos-theme', theme);
|
|
applyTheme();
|
|
};
|
|
document.getElementById('langBtn').onclick = function() {
|
|
lang = lang === 'en' ? 'de' : 'en';
|
|
localStorage.setItem('oikos-lang', lang);
|
|
applyLang();
|
|
};
|
|
matchMedia('(prefers-color-scheme:dark)').addEventListener('change', function() { if (!theme) applyTheme(); });
|
|
|
|
// Reveal
|
|
if ('IntersectionObserver' in window) {
|
|
var obs = new IntersectionObserver(function(entries) {
|
|
entries.forEach(function(e) { if (e.isIntersecting) { e.target.classList.add('vis'); obs.unobserve(e.target); } });
|
|
}, { threshold: 0.08, rootMargin: '0px 0px -40px 0px' });
|
|
document.querySelectorAll('.reveal').forEach(function(el) { obs.observe(el); });
|
|
} else {
|
|
document.querySelectorAll('.reveal').forEach(function(el) { el.classList.add('vis'); });
|
|
}
|
|
|
|
applyTheme();
|
|
applyLang();
|
|
})();
|
|
</script>
|
|
|
|
|
|
</body></html>
|