tududi/index.html
2026-02-12 12:20:14 +02:00

2038 lines
76 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-VC2N7ZBPEE"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-VC2N7ZBPEE');
</script>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>tududi - Self-Hosted Task & Project Management</title>
<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=Inter:wght@400;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--primary-color: #2563eb;
--primary-hover: #1d4ed8;
--secondary-color: #64748b;
--accent-color: #06b6d4;
--light-color: #f8fafc;
--dark-color: #0f172a;
--success-color: #059669;
--bg-color: #ffffff;
--text-color: #1e293b;
--text-muted: #64748b;
--card-bg: #ffffff;
--border-color: rgba(0, 0, 0, 0.08);
--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-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--gradient-primary: linear-gradient(135deg, #faf8f5 0%, #f5f2ee 100%);
--gradient-elegant: linear-gradient(135deg, #f0b575 0%, #e0a465 100%);
--gradient-surface: linear-gradient(145deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0.05) 100%);
}
[data-theme="dark"] {
--primary-color: #3b82f6;
--primary-hover: #2563eb;
--secondary-color: #94a3b8;
--accent-color: #06b6d4;
--light-color: #1e293b;
--dark-color: #f1f5f9;
--success-color: #10b981;
--bg-color: #0f172a;
--text-color: #f1f5f9;
--text-muted: #94a3b8;
--card-bg: #1e293b;
--border-color: rgba(255, 255, 255, 0.1);
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.3);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.4), 0 2px 4px -2px rgb(0 0 0 / 0.4);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.4), 0 4px 6px -4px rgb(0 0 0 / 0.4);
--gradient-primary: linear-gradient(135deg, #1e3a8a 0%, #3b82f6 100%);
--gradient-elegant: linear-gradient(135deg, #f0b575 0%, #e0a465 100%);
--gradient-surface: linear-gradient(145deg, rgba(255,255,255,0.05) 0%, rgba(255,255,255,0.02) 100%);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes float {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
}
body {
line-height: 1.7;
color: var(--text-color);
background-color: var(--bg-color);
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
font-weight: 400;
transition: all 0.3s ease;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.container {
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 0 15px;
}
/* Header */
header {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-bottom: 1px solid var(--border-color);
position: fixed;
width: 100%;
top: 0;
z-index: 1000;
transition: all 0.3s ease;
}
[data-theme="dark"] header {
background: rgba(15, 23, 42, 0.95);
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
header::before {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 1px;
background: var(--gradient-primary);
opacity: 0.3;
}
nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 0;
}
.logo {
display: flex;
align-items: center;
text-decoration: none;
transition: all 0.3s ease;
}
.logo:hover {
transform: translateY(-1px);
}
.logo-image {
height: 36px;
width: auto;
}
.logo-light {
display: block;
}
.logo-dark {
display: none;
}
[data-theme="dark"] .logo-light {
display: none;
}
[data-theme="dark"] .logo-dark {
display: block;
}
.nav-links {
display: flex;
list-style: none;
align-items: center;
}
.nav-links li {
margin-left: 8px;
}
.nav-links a {
text-decoration: none;
color: var(--text-color);
font-weight: 500;
transition: all 0.3s ease;
position: relative;
padding: 8px 16px;
border-radius: 8px;
}
.nav-links a::before {
content: '';
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 2px;
background: var(--gradient-primary);
transition: all 0.3s ease;
transform: translateX(-50%);
}
.nav-links a:hover {
color: var(--primary-color);
background: rgba(37, 99, 235, 0.05);
}
.nav-links a:hover::before {
width: 100%;
}
.theme-switch {
margin-left: 8px;
display: flex;
align-items: center;
}
.theme-switch-label {
margin-right: 10px;
font-size: 0.9rem;
color: var(--text-color);
}
.switch {
position: relative;
display: inline-block;
width: 50px;
height: 24px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: .4s;
border-radius: 24px;
}
.slider:before {
position: absolute;
content: "";
height: 16px;
width: 16px;
left: 4px;
bottom: 4px;
background-color: white;
transition: .4s;
border-radius: 50%;
}
input:checked + .slider {
background-color: var(--primary-color);
}
input:checked + .slider:before {
transform: translateX(26px);
}
.cta-button {
background: var(--gradient-primary);
color: white;
padding: 12px 24px;
border-radius: 8px;
text-decoration: none;
font-weight: 600;
transition: all 0.3s ease;
box-shadow: var(--shadow-sm);
}
.cta-button:hover {
transform: translateY(-1px);
box-shadow: var(--shadow-md);
color: white;
}
/* Hero Section */
.hero {
padding: 220px 0 120px;
text-align: center;
background: var(--gradient-primary);
position: relative;
overflow: hidden;
}
.hero::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60" width="60" height="60"><defs><pattern id="hero-pattern" x="0" y="0" width="60" height="60" patternUnits="userSpaceOnUse"><circle cx="30" cy="30" r="1.5" fill="rgba(255,255,255,0.1)"/></pattern></defs><rect width="60" height="60" fill="url(%23hero-pattern)"/></svg>') repeat;
opacity: 0.6;
}
.hero::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: radial-gradient(circle at 50% 50%, rgba(255,255,255,0.1) 0%, transparent 70%);
}
.hero-content {
max-width: 900px;
margin: 0 auto;
position: relative;
z-index: 1;
}
.hero h1 {
font-size: 3.5rem;
font-weight: 800;
margin-bottom: 16px;
color: #1e293b;
line-height: 1.1;
letter-spacing: -0.02em;
position: relative;
z-index: 1;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
animation: fadeInUp 0.8s ease-out;
}
[data-theme="dark"] .hero h1 {
color: white;
}
[data-theme="dark"] .hero p {
color: rgba(255, 255, 255, 0.9);
}
[data-theme="dark"] .github-stars-display {
color: rgba(255, 255, 255, 0.8) !important;
}
[data-theme="dark"] .testimonials .section-header h2 {
color: white !important;
}
[data-theme="dark"] .testimonials .section-header p {
color: rgba(255, 255, 255, 0.9) !important;
}
.testimonial-quote {
color: #2d3748;
}
.testimonial-source {
color: #4a5568;
}
[data-theme="dark"] .testimonial-quote {
color: white !important;
}
[data-theme="dark"] .testimonial-source {
color: rgba(255, 255, 255, 0.8) !important;
}
.testimonial-card {
background: white;
border: 1px solid rgba(0, 0, 0, 0.1);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
[data-theme="dark"] .testimonial-card {
background: rgba(255, 255, 255, 0.15) !important;
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.2) !important;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3) !important;
}
.hero-subtitle {
font-size: 1.5rem;
font-weight: 400;
color: rgba(255, 255, 255, 0.8);
margin-bottom: 24px;
font-style: italic;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
animation: fadeInUp 0.8s ease-out 0.1s both;
}
.hero-spacer {
height: 40px;
}
.hero p {
font-size: 1.3rem;
color: #4a5568;
margin-bottom: 40px;
max-width: 600px;
margin-left: auto;
margin-right: auto;
line-height: 1.6;
position: relative;
z-index: 1;
animation: fadeInUp 0.8s ease-out 0.2s both;
}
.hero-buttons {
display: flex;
justify-content: center;
gap: 20px;
margin-top: 60px;
margin-bottom: 60px;
flex-wrap: wrap;
position: relative;
z-index: 1;
animation: fadeInUp 0.8s ease-out 0.4s both;
}
.hero-buttons a {
text-decoration: none;
padding: 16px 32px;
border-radius: 12px;
font-weight: 600;
font-size: 1.1rem;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 8px;
}
.primary-button {
background-color: white;
color: var(--primary-color);
box-shadow: var(--shadow-lg);
}
.primary-button:hover {
transform: translateY(-2px);
box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
}
.secondary-button {
border: 2px solid var(--primary-color);
color: var(--primary-color);
}
.secondary-button:hover {
background-color: var(--primary-color);
color: white;
}
[data-theme="dark"] .secondary-button {
border: 2px solid white;
color: white;
}
[data-theme="dark"] .secondary-button:hover {
background-color: white;
color: var(--primary-color);
}
.video-container {
position: relative;
padding-bottom: 56.25%;
height: 0;
overflow: hidden;
max-width: 100%;
background: #000;
margin-bottom: 20px;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1), inset 0 0 0 10px rgba(0, 0, 0, 0.5);
}
.video-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 5px;
}
.hero-image-container {
margin-bottom: 40px;
position: relative;
z-index: 1;
}
.mobile-overlay {
position: absolute;
bottom: -20px;
right: -20px;
width: 180px;
height: auto;
border-radius: 6px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.4);
z-index: 2;
transition: opacity 0.3s ease;
pointer-events: none;
animation: fadeInUp 0.8s ease-out 0.8s both;
}
.mobile-overlay-light {
display: block;
}
.mobile-overlay-dark {
display: none;
}
[data-theme="dark"] .mobile-overlay-light {
display: none;
}
[data-theme="dark"] .mobile-overlay-dark {
display: block;
}
@media (max-width: 768px) {
.mobile-overlay {
width: 120px;
bottom: -10px;
right: -10px;
}
}
.hero-image {
max-width: 100%;
width: 100%;
border-radius: 8px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
margin: 0 auto;
transition: all 0.3s ease;
animation: fadeInUp 0.8s ease-out 0.6s both;
}
.hero-image-light {
display: block;
}
.hero-image-dark {
display: none;
}
[data-theme="dark"] .hero-image-light {
display: none;
}
[data-theme="dark"] .hero-image-dark {
display: block;
}
/* Features */
.features {
padding: 120px 0;
background-color: var(--light-color);
}
[data-theme="dark"] .features {
background-color: var(--bg-color);
}
.section-header {
text-align: center;
margin-bottom: 80px;
max-width: 700px;
margin-left: auto;
margin-right: auto;
}
.section-header h2 {
font-size: 2.4rem;
font-weight: 800;
margin-bottom: 24px;
color: var(--text-color);
line-height: 1.2;
letter-spacing: -0.02em;
}
.section-header p {
font-size: 1.25rem;
color: var(--text-muted);
line-height: 1.6;
max-width: 700px;
margin: 0 auto;
}
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 24px;
}
.feature-card {
background-color: var(--card-bg);
padding: 24px 20px;
border-radius: 12px;
box-shadow: var(--shadow-md);
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
text-align: left;
border: 1px solid var(--border-color);
position: relative;
overflow: hidden;
}
.feature-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: var(--gradient-primary);
transition: all 0.3s ease;
}
.feature-card::after {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.1), transparent);
transition: left 0.5s ease;
}
.feature-card:hover {
transform: translateY(-8px) scale(1.02);
box-shadow: var(--shadow-lg);
}
.feature-card:hover::after {
left: 100%;
}
.feature-card:hover::before {
height: 6px;
}
.feature-icon {
background: var(--gradient-primary);
color: white;
width: 48px;
height: 48px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 16px;
font-size: 1.2rem;
box-shadow: var(--shadow-md);
}
.feature-card h3 {
font-size: 1.2rem;
font-weight: 700;
margin-bottom: 12px;
color: var(--text-color);
line-height: 1.3;
}
.feature-card p {
color: var(--text-muted);
line-height: 1.6;
font-size: 0.9rem;
}
/* Languages Section */
.languages {
padding: 100px 0;
background: linear-gradient(135deg, var(--primary-color) 0%, #1565c0 100%);
color: white;
position: relative;
overflow: hidden;
}
.languages::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse"><path d="M 10 0 L 0 0 0 10" fill="none" stroke="rgba(255,255,255,0.1)" stroke-width="0.5"/></pattern></defs><rect width="100" height="100" fill="url(%23grid)"/></svg>');
opacity: 0.3;
}
.languages .container {
position: relative;
z-index: 1;
}
.languages .section-header {
margin-bottom: 60px;
}
.languages .section-header h2 {
color: white;
font-size: 2.8rem;
margin-bottom: 20px;
}
.languages .section-header p {
color: rgba(255, 255, 255, 0.9);
font-size: 1.2rem;
}
.languages-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 20px;
max-width: 1000px;
margin: 0 auto;
}
.language-item {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 15px;
padding: 20px 15px;
text-align: center;
transition: all 0.3s ease;
cursor: pointer;
}
.language-item:hover {
transform: translateY(-5px) scale(1.02);
background: rgba(255, 255, 255, 0.15);
border-color: rgba(255, 255, 255, 0.4);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}
.language-flag {
font-size: 2.5rem;
margin-bottom: 10px;
display: block;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
}
.language-name {
font-weight: 600;
font-size: 0.9rem;
color: white;
margin: 0;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}
/* Screenshots */
.screenshots {
padding: 100px 0;
background-color: var(--card-bg);
}
.screenshots-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 30px;
margin-top: 50px;
}
.screenshot {
border-radius: 6px;
overflow: hidden;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
.screenshot img {
width: 100%;
height: auto;
display: block;
transition: transform 0.3s;
}
.screenshot:hover img {
transform: scale(1.03);
}
/* Installation */
.installation {
padding: 100px 0;
background-color: var(--bg-color);
}
.installation-steps {
max-width: 800px;
margin: 0 auto;
background-color: var(--card-bg);
border-radius: 10px;
padding: 40px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
}
.step {
margin-bottom: 30px;
display: flex;
align-items: flex-start;
}
.step:last-child {
margin-bottom: 0;
}
.step-number {
background-color: var(--primary-color);
color: white;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-weight: 700;
margin-right: 15px;
flex-shrink: 0;
}
.step-content h3 {
font-size: 1.3rem;
margin-bottom: 10px;
color: var(--text-color);
}
.step-content p {
color: var(--secondary-color);
margin-bottom: 15px;
}
code {
background-color: #f0f0f0;
padding: 10px 15px;
border-radius: 5px;
font-family: 'Courier New', Courier, monospace;
display: block;
margin: 15px 0;
white-space: pre-wrap;
color: #333;
}
[data-theme="dark"] code {
background-color: #2a2a2a;
color: #f0f0f0;
}
/* CTA */
.cta {
padding: 100px 0;
background-color: var(--primary-color);
color: white;
text-align: center;
}
.cta h2 {
font-size: 2.5rem;
margin-bottom: 20px;
}
.cta p {
font-size: 1.2rem;
max-width: 700px;
margin: 0 auto 30px;
}
.cta-buttons {
display: flex;
justify-content: center;
gap: 20px;
}
.cta-white {
background-color: white;
color: var(--primary-color);
padding: 15px 30px;
border-radius: 5px;
text-decoration: none;
font-weight: 600;
transition: background-color 0.3s;
}
.cta-white:hover {
background-color: #f0f0f0;
}
.cta-outline {
border: 2px solid white;
color: white;
padding: 15px 30px;
border-radius: 5px;
text-decoration: none;
font-weight: 600;
transition: background-color 0.3s;
}
.cta-outline:hover {
background-color: rgba(255, 255, 255, 0.1);
}
/* Footer */
footer {
background-color: #212121;
color: white;
padding: 60px 0 30px;
}
.footer-content {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 40px;
margin-bottom: 40px;
}
.footer-column h3 {
font-size: 1.3rem;
margin-bottom: 20px;
position: relative;
padding-bottom: 10px;
}
.footer-column h3::after {
content: '';
position: absolute;
left: 0;
bottom: 0;
width: 50px;
height: 2px;
background-color: var(--primary-color);
}
.footer-links {
list-style: none;
}
.footer-links li {
margin-bottom: 10px;
}
.footer-links a {
color: #b0b0b0;
text-decoration: none;
transition: color 0.3s;
}
.footer-links a:hover {
color: white;
}
.footer-bottom {
text-align: center;
padding-top: 30px;
border-top: 1px solid var(--border-color);
color: #b0b0b0;
font-size: 0.9rem;
}
.social-icons {
display: flex;
gap: 15px;
margin-top: 20px;
}
.social-icons a {
color: white;
font-size: 1.2rem;
transition: color 0.3s;
}
.social-icons a:hover {
color: var(--primary-color);
}
.mobile-menu-toggle {
display: none;
}
/* Responsive */
@media (max-width: 768px) {
.container {
padding: 0 20px;
}
/* Header */
nav {
padding: 15px 0;
}
.logo-image {
height: 28px;
}
.nav-links {
display: none;
position: fixed;
top: 70px;
left: 0;
right: 0;
background: var(--card-bg);
border-bottom: 1px solid var(--border-color);
padding: 20px;
flex-direction: column;
gap: 15px;
box-shadow: var(--shadow-lg);
z-index: 1000;
}
.nav-links.active {
display: flex;
}
.mobile-menu-toggle {
display: block;
background: none;
border: none;
font-size: 1.5rem;
color: var(--text-color);
cursor: pointer;
padding: 5px;
}
.nav-links a {
padding: 10px 15px;
border-radius: 8px;
text-align: center;
}
.theme-switch {
justify-content: center;
margin: 10px 0;
}
/* Hero */
.hero {
padding: 150px 0 60px;
text-align: center;
}
.hero h1 {
font-size: 2.2rem;
margin-bottom: 12px;
}
.hero-subtitle {
font-size: 1.1rem;
margin-bottom: 20px;
}
.hero-spacer {
height: 25px;
}
.hero p {
font-size: 1rem;
margin-bottom: 30px;
}
.hero-buttons {
flex-direction: column;
gap: 12px;
align-items: center;
}
.hero-buttons a {
width: 100%;
max-width: 280px;
text-align: center;
padding: 12px 20px;
font-size: 0.95rem;
}
.hero-image {
max-width: 100%;
margin-bottom: 30px;
}
/* Sections */
.section-header h2 {
font-size: 2rem;
margin-bottom: 12px;
}
.section-header p {
font-size: 0.95rem;
}
/* Features */
.features-grid {
grid-template-columns: 1fr;
gap: 20px;
}
.feature-card {
padding: 20px;
text-align: left;
display: grid;
grid-template-columns: auto 1fr;
grid-template-rows: auto 1fr;
gap: 15px 15px;
align-items: start;
}
.feature-icon {
grid-row: 1 / 3;
grid-column: 1;
margin-bottom: 0;
align-self: start;
margin-top: 3px;
}
.feature-card h3 {
grid-row: 1;
grid-column: 2;
font-size: 1.1rem;
margin: 0;
align-self: start;
}
.feature-card p {
grid-row: 2;
grid-column: 2;
font-size: 0.9rem;
margin: 0;
line-height: 1.4;
align-self: start;
}
/* Testimonials */
.testimonials {
padding: 50px 0;
}
.testimonial-card {
padding: 25px 20px !important;
flex-direction: column;
gap: 20px !important;
text-align: center;
height: auto !important;
background: rgba(255, 255, 255, 0.95) !important;
backdrop-filter: blur(10px) !important;
}
.testimonial-card blockquote {
font-size: 1.1rem !important;
order: 2;
color: #2d3748 !important;
font-weight: 500;
line-height: 1.5;
margin: 0 !important;
}
.testimonial-card > div:first-child {
font-size: 2.5rem !important;
order: 1;
}
.testimonial-card > div:last-child {
order: 3;
justify-content: center;
color: #4a5568 !important;
font-weight: 600;
}
/* Languages */
.languages-grid {
grid-template-columns: repeat(3, 1fr);
gap: 15px;
}
.language-item {
padding: 10px;
}
.language-flag {
font-size: 1.5rem;
}
.language-name {
font-size: 0.8rem;
}
/* Screenshots */
.screenshots-grid {
grid-template-columns: 1fr;
gap: 20px;
}
/* Installation */
.installation-steps {
gap: 30px;
}
.step {
flex-direction: column;
text-align: center;
gap: 15px;
}
.step-number {
margin: 0 auto 15px;
}
.step-content h3 {
font-size: 1.1rem;
word-wrap: break-word;
}
.step-content p {
font-size: 0.9rem;
}
.step-content code {
font-size: 0.8rem;
word-break: break-all;
white-space: pre-wrap;
overflow-wrap: break-word;
}
.step-content div {
margin: 10px 0;
overflow: hidden;
}
.step-content h4 {
font-size: 1rem !important;
word-wrap: break-word;
}
.step-content ul {
text-align: left;
padding-left: 15px !important;
}
.step-content li {
font-size: 0.85rem;
margin-bottom: 8px;
word-wrap: break-word;
}
.step-content strong {
word-wrap: break-word;
display: inline-block;
max-width: 100%;
}
/* CTA */
.cta h2 {
font-size: 2rem;
}
.cta p {
font-size: 0.95rem;
}
.cta-buttons {
flex-direction: column;
gap: 12px;
align-items: center;
}
.cta-buttons a {
width: 100%;
max-width: 280px;
text-align: center;
}
}
</style>
</head>
<body data-theme="dark">
<header>
<div class="container">
<nav>
<a href="/" class="logo">
<img src="public/wide-logo-dark.png" alt="tududi" class="logo-image logo-light">
<img src="public/wide-logo-light.png" alt="tududi" class="logo-image logo-dark">
</a>
<button class="mobile-menu-toggle" onclick="toggleMobileMenu()">
<i class="fas fa-bars"></i>
</button>
<ul class="nav-links">
<li><a href="#features">Features</a></li>
<li><a href="#languages">Languages</a></li>
<li><a href="#screenshots">Screenshots</a></li>
<li><a href="#installation">Installation</a></li>
<li><a href="https://docs.tududi.com">Docs</a></li>
<li class="theme-switch">
<span class="theme-switch-label"><i class="fas fa-moon"></i></span>
<label class="switch">
<input type="checkbox" id="theme-toggle" checked>
<span class="slider"></span>
</label>
</li>
<li><a href="https://github.com/chrisvel/tududi" class="cta-button">GitHub</a></li>
</ul>
</nav>
</div>
</header>
<section class="hero">
<div class="container">
<div class="hero-content">
<h1>Productivity Made Simple</h1>
<div style="height: 20px;"></div>
<p>Join hundreds of users who stay organized with smart task management that adapts to their workflow.</p>
<div class="github-stars-display" style="margin-top: 15px; display: flex; align-items: center; justify-content: center; gap: 8px; color: #4a5568;">
<i class="fab fa-github" style="font-size: 1.1rem;"></i>
<span id="github-stars" style="font-weight: 800;">Loading...</span>
<span>stars</span>
</div>
<div class="hero-spacer"></div>
<div class="hero-image-container">
<img src="screenshots/all-light.png" alt="tududi - Light Mode Interface" class="hero-image hero-image-light">
<img src="screenshots/all-dark.png" alt="tududi - Dark Mode Interface" class="hero-image hero-image-dark">
<img src="screenshots/mobile-all-light.png" alt="tududi - Mobile Light Mode" class="mobile-overlay mobile-overlay-light">
<img src="screenshots/mobile-all-dark.png" alt="tududi - Mobile Dark Mode" class="mobile-overlay mobile-overlay-dark">
</div>
<div class="hero-buttons">
<a href="https://docs.tududi.com" class="secondary-button">
<i class="fas fa-book"></i>
Documentation
</a>
<a href="https://github.com/chrisvel/tududi" class="secondary-button">
<i class="fab fa-github"></i>
View on GitHub
</a>
<a href="#installation" class="primary-button">Quick Install</a>
</div>
</div>
</div>
</section>
<!-- Testimonials Section -->
<section class="testimonials" style="padding: 80px 0; background: var(--gradient-primary); position: relative; overflow: hidden;">
<style>
@keyframes testimonialFade {
0% { opacity: 0; transform: translateY(20px); }
5% { opacity: 1; transform: translateY(0); }
15% { opacity: 1; transform: translateY(0); }
20% { opacity: 0; transform: translateY(-20px); }
100% { opacity: 0; transform: translateY(-20px); }
}
.testimonial-card {
animation: testimonialFade 20s infinite;
position: absolute;
width: 100%;
opacity: 0;
}
.testimonial-card:nth-child(1) { animation-delay: 0s; }
.testimonial-card:nth-child(2) { animation-delay: 4s; }
.testimonial-card:nth-child(3) { animation-delay: 8s; }
.testimonial-card:nth-child(4) { animation-delay: 12s; }
.testimonial-card:nth-child(5) { animation-delay: 16s; }
</style>
<div style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: url('data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 60 60%22 width=%2260%22 height=%2260%22%3E%3Cdefs%3E%3Cpattern id=%22testimonial-pattern%22 x=%220%22 y=%220%22 width=%2260%22 height=%2260%22 patternUnits=%22userSpaceOnUse%22%3E%3Ccircle cx=%2230%22 cy=%2230%22 r=%221.5%22 fill=%22rgba(255,255,255,0.1)%22/%3E%3C/pattern%3E%3C/defs%3E%3Crect width=%2260%22 height=%2260%22 fill=%22url(%23testimonial-pattern)%22/%3E%3C/svg%3E') repeat; opacity: 0.3;"></div>
<div class="container" style="position: relative; z-index: 1;">
<div class="section-header" style="text-align: center; margin-bottom: 60px;">
<h2 style="color: #1e293b; font-size: 2.5rem; font-weight: 700; margin-bottom: 16px;">What Users Are Saying</h2>
<p style="color: #4a5568; font-size: 1.1rem;">Join hundreds of satisfied users who have transformed their productivity with <strong>tududi</strong></p>
</div>
<div style="position: relative; max-width: 900px; margin: 0 auto; height: 120px; display: flex; align-items: center;">
<div class="testimonial-card" style="border-radius: 16px; padding: 30px; display: flex; align-items: center; gap: 25px;">
<div style="font-size: 3rem; flex-shrink: 0;">💎</div>
<blockquote class="testimonial-quote" style="font-size: 1.2rem; line-height: 1.6; margin: 0; font-style: italic; flex: 1; text-align: center; font-weight: 600;">"This may be the perfect to-do management tool available."</blockquote>
<div class="testimonial-source" style="display: flex; align-items: center; gap: 10px; flex-shrink: 0;">
<i class="fab fa-github" style="font-size: 1.2rem;"></i>
<span style="font-weight: 500;">GitHub</span>
</div>
</div>
<div class="testimonial-card" style="border-radius: 16px; padding: 30px; display: flex; align-items: center; gap: 25px;">
<div style="font-size: 3rem; flex-shrink: 0;">❤️</div>
<blockquote class="testimonial-quote" style="font-size: 1.2rem; line-height: 1.6; margin: 0; font-style: italic; flex: 1; text-align: center; font-weight: 600;">"I stumbled across this and love it"</blockquote>
<div class="testimonial-source" style="display: flex; align-items: center; gap: 10px; flex-shrink: 0;">
<i class="fab fa-medium" style="font-size: 1.2rem;"></i>
<span style="font-weight: 500;">Medium</span>
</div>
</div>
<div class="testimonial-card" style="border-radius: 16px; padding: 30px; display: flex; align-items: center; gap: 25px;">
<div style="font-size: 3rem; flex-shrink: 0;"></div>
<blockquote class="testimonial-quote" style="font-size: 1.2rem; line-height: 1.6; margin: 0; font-style: italic; flex: 1; text-align: center; font-weight: 600;">"Looks somewhat like super productivity"</blockquote>
<div class="testimonial-source" style="display: flex; align-items: center; gap: 10px; flex-shrink: 0;">
<i class="fab fa-reddit" style="font-size: 1.2rem;"></i>
<span style="font-weight: 500;">Reddit</span>
</div>
</div>
<div class="testimonial-card" style="border-radius: 16px; padding: 30px; display: flex; align-items: center; gap: 25px;">
<div style="font-size: 3rem; flex-shrink: 0;"></div>
<blockquote class="testimonial-quote" style="font-size: 1.2rem; line-height: 1.6; margin: 0; font-style: italic; flex: 1; text-align: center; font-weight: 600;">"Why does this look so good?"</blockquote>
<div class="testimonial-source" style="display: flex; align-items: center; gap: 10px; flex-shrink: 0;">
<i class="fab fa-reddit" style="font-size: 1.2rem;"></i>
<span style="font-weight: 500;">Reddit</span>
</div>
</div>
<div class="testimonial-card" style="border-radius: 16px; padding: 30px; display: flex; align-items: center; gap: 25px;">
<div style="font-size: 3rem; flex-shrink: 0;">🎉</div>
<blockquote class="testimonial-quote" style="font-size: 1.2rem; line-height: 1.6; margin: 0; font-style: italic; flex: 1; text-align: center; font-weight: 600;">"This is amazing"</blockquote>
<div class="testimonial-source" style="display: flex; align-items: center; gap: 10px; flex-shrink: 0;">
<i class="fab fa-reddit" style="font-size: 1.2rem;"></i>
<span style="font-weight: 500;">Reddit</span>
</div>
</div>
</div>
</div>
</section>
<section class="features" id="features">
<div class="container">
<div class="section-header">
<h2>Powerful Features for Modern Productivity</h2>
<p><strong>tududi</strong> combines the simplicity of personal task management with the power of professional project organization. Built for individuals and teams who value privacy, control, and efficiency.</p>
</div>
<div class="features-grid">
<div class="feature-card">
<div class="feature-icon">
<i class="fas fa-sync-alt"></i>
</div>
<h3>Smart Recurring Tasks</h3>
<p>Daily, weekly, monthly patterns with completion-based recurrence and parent-child relationships.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<i class="fas fa-tasks"></i>
</div>
<h3>Advanced Task Management</h3>
<p>Rich metadata with priorities, due dates, and tags. Smart sorting and powerful filtering options.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<i class="fas fa-list-ul"></i>
</div>
<h3>Subtasks & Breakdown</h3>
<p>Break down complex tasks into manageable subtasks with progress tracking and seamless navigation between parent and child tasks.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<i class="fas fa-sticky-note"></i>
</div>
<h3>Project Documentation</h3>
<p>Rich text notes for projects with full search and organization capabilities.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<i class="fas fa-tag"></i>
</div>
<h3>Flexible Tagging System</h3>
<p>Custom tags for tasks and notes with instant filtering and cross-project organization.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<i class="fas fa-project-diagram"></i>
</div>
<h3>Hierarchical Organization</h3>
<p>GTD-style Areas → Projects → Tasks structure for clear work separation.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<i class="fas fa-layer-group"></i>
</div>
<h3>Life Area Management</h3>
<p>Organize projects by life areas - Work, Personal, Health, Learning - with clear boundaries.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<i class="fas fa-calendar-check"></i>
</div>
<h3>Intelligent Due Date Management</h3>
<p>Set due dates with smart categorization: Today's priorities, Upcoming deadlines, and Someday tasks. Visual indicators and automatic sorting keep you focused on what matters now.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<i class="fas fa-language"></i>
</div>
<h3>Multi-Language Support</h3>
<p>Available in 24 languages with full localization support for a truly global productivity experience.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<i class="fas fa-paper-plane"></i>
</div>
<h3>Telegram Integration</h3>
<p>Create tasks directly through Telegram messages, receive daily digests of your tasks, and quick capture ideas on the go. Never miss important deadlines with automated notifications.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<i class="fas fa-code"></i>
</div>
<h3>API Access & Swagger</h3>
<p>Versioned Swagger docs at <code>/api/v1</code> and personal access tokens let you build automations or integrations around tududis data.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<i class="fas fa-mobile-alt"></i>
</div>
<h3>Responsive Design</h3>
<p>Seamlessly works across all devices - desktop, tablet, and mobile. Dark and light themes with automatic system preference detection.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<i class="fas fa-server"></i>
</div>
<h3>Self-Hosted Privacy</h3>
<p>Keep your data completely private and under your control. No cloud dependencies, no data mining, no subscription fees - just your own secure installation.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<i class="fas fa-filter"></i>
</div>
<h3>Smart Filtering & Search</h3>
<p>Advanced filtering by status, priority, due dates, tags, and projects. Quick search functionality to find exactly what you need instantly.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<i class="fas fa-chart-line"></i>
</div>
<h3>Productivity Insights</h3>
<p>Track your progress with task completion statistics, project timelines, and productivity patterns to optimize your workflow.</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<i class="fas fa-user-friends"></i>
</div>
<h3>Project Sharing & Collaboration</h3>
<p>Share projects with team members using granular access controls. Grant read-only or read-write permissions to collaborate effectively while maintaining ownership and security.</p>
</div>
</div>
</div>
</section>
<section class="languages" id="languages">
<div class="container">
<div class="section-header">
<h2>🌍 Global Language Support</h2>
<p><strong>tududi</strong> speaks your language! Available in 24 languages with full localization support, making productivity accessible to users worldwide.</p>
</div>
<div class="languages-grid">
<div class="language-item">
<span class="language-flag">🇸🇦</span>
<p class="language-name">Arabic</p>
</div>
<div class="language-item">
<span class="language-flag">🇧🇬</span>
<p class="language-name">Bulgarian</p>
</div>
<div class="language-item">
<span class="language-flag">🇨🇳</span>
<p class="language-name">Chinese</p>
</div>
<div class="language-item">
<span class="language-flag">🇩🇰</span>
<p class="language-name">Danish</p>
</div>
<div class="language-item">
<span class="language-flag">🇳🇱</span>
<p class="language-name">Dutch</p>
</div>
<div class="language-item">
<span class="language-flag">🇺🇸</span>
<p class="language-name">English</p>
</div>
<div class="language-item">
<span class="language-flag">🇫🇮</span>
<p class="language-name">Finnish</p>
</div>
<div class="language-item">
<span class="language-flag">🇫🇷</span>
<p class="language-name">French</p>
</div>
<div class="language-item">
<span class="language-flag">🇩🇪</span>
<p class="language-name">German</p>
</div>
<div class="language-item">
<span class="language-flag">🇬🇷</span>
<p class="language-name">Greek</p>
</div>
<div class="language-item">
<span class="language-flag">🇮🇩</span>
<p class="language-name">Indonesian</p>
</div>
<div class="language-item">
<span class="language-flag">🇮🇹</span>
<p class="language-name">Italian</p>
</div>
<div class="language-item">
<span class="language-flag">🇯🇵</span>
<p class="language-name">Japanese</p>
</div>
<div class="language-item">
<span class="language-flag">🇰🇷</span>
<p class="language-name">Korean</p>
</div>
<div class="language-item">
<span class="language-flag">🇳🇴</span>
<p class="language-name">Norwegian</p>
</div>
<div class="language-item">
<span class="language-flag">🇵🇱</span>
<p class="language-name">Polish</p>
</div>
<div class="language-item">
<span class="language-flag">🇵🇹</span>
<p class="language-name">Portuguese</p>
</div>
<div class="language-item">
<span class="language-flag">🇷🇴</span>
<p class="language-name">Romanian</p>
</div>
<div class="language-item">
<span class="language-flag">🇷🇺</span>
<p class="language-name">Russian</p>
</div>
<div class="language-item">
<span class="language-flag">🇪🇸</span>
<p class="language-name">Spanish</p>
</div>
<div class="language-item">
<span class="language-flag">🇸🇮</span>
<p class="language-name">Slovenian</p>
</div>
<div class="language-item">
<span class="language-flag">🇸🇪</span>
<p class="language-name">Swedish</p>
</div>
<div class="language-item">
<span class="language-flag">🇹🇷</span>
<p class="language-name">Turkish</p>
</div>
<div class="language-item">
<span class="language-flag">🇺🇦</span>
<p class="language-name">Ukrainian</p>
</div>
<div class="language-item">
<span class="language-flag">🇻🇳</span>
<p class="language-name">Vietnamese</p>
</div>
</div>
</div>
</section>
<section class="screenshots" id="screenshots">
<div class="container">
<div class="section-header">
<h2>Clean, Intuitive Interface</h2>
<p>Experience <strong>tududi's</strong> thoughtfully designed interface that adapts to your workflow. Dark and light themes, responsive design, and distraction-free focus on what matters most.</p>
</div>
<div class="screenshots-grid">
<div class="screenshot">
<img src="screenshots/all-light.png" alt="Light Mode - Desktop">
</div>
<div class="screenshot">
<img src="screenshots/all-dark.png" alt="Dark Mode - Desktop">
</div>
<div class="screenshot">
<img src="screenshots/mobile-all-light.png" alt="Light Mode - Mobile">
</div>
<div class="screenshot">
<img src="screenshots/mobile-all-dark.png" alt="Dark Mode - Mobile">
</div>
</div>
</div>
</section>
<section class="installation" id="installation">
<div class="container">
<div class="section-header">
<h2>Easy Self-Hosted Setup</h2>
<p>Deploy <strong>tududi</strong> in minutes with Docker. No complex configuration, no external dependencies - just pull, configure, and run. Your data stays completely under your control.</p>
</div>
<div class="installation-steps">
<div class="step">
<div class="step-number">1</div>
<div class="step-content">
<h3>Pull the latest image</h3>
<p>First, pull the latest Docker image:</p>
<code>docker pull chrisvel/tududi:latest</code>
</div>
</div>
<div class="step">
<div class="step-number">2</div>
<div class="step-content">
<h3>Configure Environment Variables</h3>
<p>Set up the required environment variables for your installation:</p>
<div style="background-color: var(--card-bg); padding: 20px; border-radius: 8px; margin: 15px 0; border-left: 4px solid var(--primary-color);">
<h4 style="color: var(--text-color); margin-bottom: 10px; font-size: 1.1rem;">Required Variables:</h4>
<ul style="color: var(--secondary-color); margin: 0; padding-left: 20px; line-height: 1.6;">
<li><strong style="color: var(--text-color);">TUDUDI_USER_EMAIL</strong> - Initial admin user's email</li>
<li><strong style="color: var(--text-color);">TUDUDI_USER_PASSWORD</strong> - Initial admin user's password</li>
<li><strong style="color: var(--text-color);">TUDUDI_SESSION_SECRET</strong> - Session encryption key</li>
</ul>
<h4 style="color: var(--text-color); margin: 15px 0 10px 0; font-size: 1.1rem;">Optional Variables:</h4>
<ul style="color: var(--secondary-color); margin: 0; padding-left: 20px; line-height: 1.6;">
<li><strong style="color: var(--text-color);">TUDUDI_ALLOWED_ORIGINS</strong> - Controls CORS access</li>
</ul>
</div>
<p>Generate a secure session secret with: <code style="background-color: var(--card-bg); padding: 4px 8px; border-radius: 4px; font-family: monospace;">openssl rand -hex 64</code></p>
</div>
</div>
<div class="step">
<div class="step-number">3</div>
<div class="step-content">
<h3>Run the Docker container</h3>
<p>Launch the application with your configuration:</p>
<code>docker run \
-e TUDUDI_USER_EMAIL=myemail@example.com \
-e TUDUDI_USER_PASSWORD=mysecurepassword \
-e TUDUDI_SESSION_SECRET=$(openssl rand -hex 64) \
-e TUDUDI_ALLOWED_ORIGINS=https://tududi,http://tududi:3002 \
-v ~/tududi_db:/app/backend/db \
-v ~/tududi_uploads:/app/backend/uploads \
-p 3002:3002 \
-d chrisvel/tududi:latest</code>
</div>
</div>
<div class="step">
<div class="step-number">4</div>
<div class="step-content">
<h3>Access the application</h3>
<p>Navigate to <a href="http://localhost:3002" style="color: var(--primary-color);">http://localhost:3002</a> and login with your credentials.</p>
</div>
</div>
</div>
</div>
</section>
<section class="sponsor" style="padding: 100px 0; background: linear-gradient(135deg, var(--primary-color) 0%, #1565c0 100%); color: white; position: relative; overflow: hidden;">
<style>
.sponsor::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="sponsor-grid" width="10" height="10" patternUnits="userSpaceOnUse"><path d="M 10 0 L 0 0 0 10" fill="none" stroke="rgba(255,255,255,0.1)" stroke-width="0.5"/></pattern></defs><rect width="100" height="100" fill="url(%23sponsor-grid)"/></svg>');
opacity: 0.3;
}
.sponsor-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
max-width: 800px;
margin: 0 auto;
}
.sponsor-link {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 15px;
padding: 20px 15px;
text-align: center;
text-decoration: none;
color: white;
font-weight: 600;
font-size: 0.95rem;
transition: all 0.3s ease;
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
.sponsor-link:hover {
transform: translateY(-5px) scale(1.02);
background: rgba(255, 255, 255, 0.2);
border-color: rgba(255, 255, 255, 0.4);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
color: white;
}
.sponsor-link i {
font-size: 1.8rem;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.3));
}
.sponsor-link span {
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}
@media (max-width: 768px) {
.sponsor-grid {
grid-template-columns: repeat(2, 1fr);
gap: 15px;
}
.sponsor-link {
padding: 15px 10px;
}
.sponsor-link i {
font-size: 1.5rem;
}
}
</style>
<div class="container" style="position: relative; z-index: 1;">
<div class="section-header" style="margin-bottom: 60px;">
<h2 style="color: white; font-size: 2.8rem; margin-bottom: 20px;">Support tududi</h2>
<p style="color: rgba(255, 255, 255, 0.9); font-size: 1.2rem;"><strong>tududi</strong> is free and open-source. If it helps you stay productive, consider supporting its development — every contribution keeps the project alive and growing.</p>
</div>
<div class="sponsor-grid">
<a href="https://github.com/sponsors/chrisvel" class="sponsor-link">
<i class="fab fa-github"></i>
<span>GitHub Sponsors</span>
</a>
<a href="https://www.patreon.com/ChrisVeleris" class="sponsor-link">
<i class="fab fa-patreon"></i>
<span>Patreon</span>
</a>
<a href="https://coff.ee/chrisveleris" class="sponsor-link">
<i class="fas fa-mug-hot"></i>
<span>Buy Me a Coffee</span>
</a>
<a href="https://www.paypal.com/donate/?hosted_button_id=QEQCKLXPB6XAE" class="sponsor-link">
<i class="fab fa-paypal"></i>
<span>PayPal</span>
</a>
</div>
</div>
</section>
<section class="cta">
<div class="container">
<h2>Take Control of Your Productivity</h2>
<p>Join thousands of users who've chosen privacy and control over their task management. Start your self-hosted <strong>tududi</strong> instance today and experience distraction-free productivity.</p>
<div class="cta-buttons">
<a href="https://docs.tududi.com" class="cta-white">Read the Docs</a>
<a href="https://github.com/chrisvel/tududi" class="cta-outline">View on GitHub</a>
</div>
</div>
</section>
<section class="installation" style="padding: 60px 0; background-color: var(--bg-color);">
<div class="container">
<div class="section-header">
<h2>Join the <strong>tududi</strong> Community</h2>
<p>Connect with other users, get support, share ideas, and stay updated with the latest developments. Our community is here to help you get the most out of <strong>tududi</strong>.</p>
</div>
<div style="display: flex; justify-content: center; gap: 30px; flex-wrap: wrap; margin-top: 40px;">
<a href="https://discord.gg/fkbeJ9CmcH" style="display: inline-block;">
<img src="https://img.shields.io/badge/Discord-Join%20Server-7289da?logo=discord&logoColor=white&style=for-the-badge" alt="Join Discord" style="height: 40px; transition: transform 0.3s ease;" onmouseover="this.style.transform='translateY(-2px)'" onmouseout="this.style.transform='translateY(0)'">
</a>
<a href="https://www.reddit.com/r/tududi/" style="display: inline-block;">
<img src="https://img.shields.io/reddit/subreddit-subscribers/tududi?color=ff4500&label=Reddit&logo=reddit&logoColor=white&style=for-the-badge" alt="Join Reddit" style="height: 40px; transition: transform 0.3s ease;" onmouseover="this.style.transform='translateY(-2px)'" onmouseout="this.style.transform='translateY(0)'">
</a>
</div>
<div style="text-align: center; margin-top: 30px;">
<p style="color: var(--secondary-color); font-size: 1rem;">Get help with installation, share your workflows, request features, and connect with fellow productivity enthusiasts!</p>
</div>
</div>
</section>
<section class="installation" style="padding: 50px 0; background-color: var(--bg-color);">
<div class="container">
<div class="installation-steps" style="text-align: center;">
<h3 style="color: var(--text-color); margin-bottom: 30px;">Check my other projects</h3>
<div style="display: flex; justify-content: center; gap: 30px; flex-wrap: wrap; max-width: 900px; margin: 0 auto;">
<a href="https://reconya.com" style="display: flex; flex-direction: column; align-items: center; gap: 8px; color: var(--text-color); text-decoration: none; padding: 20px; border: 1px solid var(--border-color); border-radius: 12px; transition: all 0.3s ease; background-color: var(--card-bg); text-align: center; min-width: 200px;" onmouseover="this.style.borderColor='var(--primary-color)'; this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='var(--border-color)'; this.style.transform='translateY(0)'">
<div style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px;">
<i class="fas fa-network-wired" style="font-size: 1.2rem; color: var(--primary-color);"></i>
<span style="font-weight: 600; font-size: 1.1rem;">Reconya</span>
<i class="fas fa-external-link-alt" style="font-size: 0.8rem; opacity: 0.7;"></i>
</div>
<p style="font-size: 0.9rem; color: var(--secondary-color); margin: 0; line-height: 1.4;">Network reconnaissance and asset discovery tool</p>
</a>
<a href="https://breachharbor.com" style="display: flex; flex-direction: column; align-items: center; gap: 8px; color: var(--text-color); text-decoration: none; padding: 20px; border: 1px solid var(--border-color); border-radius: 12px; transition: all 0.3s ease; background-color: var(--card-bg); text-align: center; min-width: 200px;" onmouseover="this.style.borderColor='var(--primary-color)'; this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='var(--border-color)'; this.style.transform='translateY(0)'">
<div style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px;">
<i class="fas fa-shield-alt" style="font-size: 1.2rem; color: var(--primary-color);"></i>
<span style="font-weight: 600; font-size: 1.1rem;">BreachHarbor</span>
<i class="fas fa-external-link-alt" style="font-size: 0.8rem; opacity: 0.7;"></i>
</div>
<p style="font-size: 0.9rem; color: var(--secondary-color); margin: 0; line-height: 1.4;">Cybersecurity suite for digital asset protection</p>
</a>
<a href="https://hevetra.com" style="display: flex; flex-direction: column; align-items: center; gap: 8px; color: var(--text-color); text-decoration: none; padding: 20px; border: 1px solid var(--border-color); border-radius: 12px; transition: all 0.3s ease; background-color: var(--card-bg); text-align: center; min-width: 200px;" onmouseover="this.style.borderColor='var(--primary-color)'; this.style.transform='translateY(-2px)'" onmouseout="this.style.borderColor='var(--border-color)'; this.style.transform='translateY(0)'">
<div style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px;">
<i class="fas fa-baby" style="font-size: 1.2rem; color: var(--primary-color);"></i>
<span style="font-weight: 600; font-size: 1.1rem;">Hevetra</span>
<i class="fas fa-external-link-alt" style="font-size: 0.8rem; opacity: 0.7;"></i>
</div>
<p style="font-size: 0.9rem; color: var(--secondary-color); margin: 0; line-height: 1.4;">Digital tracking for child health milestones</p>
</a>
</div>
</div>
</div>
</section>
<footer>
<div class="container">
<div class="footer-content">
<div class="footer-column">
<h3>tududi</h3>
<p>Self-hosted task management with functional programming architecture, hierarchical organization, and multi-language support.</p>
<div class="social-icons">
<a href="https://github.com/chrisvel/tududi"><i class="fab fa-github"></i></a>
</div>
</div>
<div class="footer-column">
<h3>Links</h3>
<ul class="footer-links">
<li><a href="#features">Features</a></li>
<li><a href="#languages">Languages</a></li>
<li><a href="#screenshots">Screenshots</a></li>
<li><a href="#installation">Installation</a></li>
<li><a href="https://github.com/chrisvel/tududi">GitHub Repository</a></li>
</ul>
</div>
<div class="footer-column">
<h3>Resources</h3>
<ul class="footer-links">
<li><a href="https://docs.tududi.com"><i class="fas fa-book"></i> Documentation</a></li>
<li><a href="https://github.com/users/chrisvel/projects/2">Roadmap</a></li>
<li><a href="https://github.com/chrisvel/tududi/issues">Issues</a></li>
<li><a href="https://github.com/chrisvel/tududi#-contributing">Contributing</a></li>
</ul>
</div>
<div class="footer-column">
<h3>Community</h3>
<ul class="footer-links">
<li><a href="https://discord.gg/fkbeJ9CmcH"><i class="fab fa-discord"></i> Discord Server</a></li>
<li><a href="https://www.reddit.com/r/tududi/"><i class="fab fa-reddit"></i> r/tududi</a></li>
<li><a href="mailto:info@tududi.com"><i class="fas fa-envelope"></i> info@tududi.com</a></li>
</ul>
<p style="font-size: 0.9rem; color: #b0b0b0; margin-top: 15px;">Join our community for support, discussions, and updates!</p>
</div>
</div>
<div class="footer-bottom">
<p>&copy; 2025 <strong>tududi</strong>. All rights reserved.</p>
</div>
</div>
</footer>
<script>
// Dark mode toggle functionality
const themeToggle = document.getElementById('theme-toggle');
// Check for saved theme preference or use system preference
const prefersDarkScheme = window.matchMedia('(prefers-color-scheme: dark)');
const savedTheme = localStorage.getItem('theme');
// Initialize theme based on preference
function initializeTheme() {
const shouldUseDark = savedTheme === 'dark' || (!savedTheme && prefersDarkScheme.matches);
if (shouldUseDark) {
document.body.setAttribute('data-theme', 'dark');
themeToggle.checked = true;
document.querySelector('.theme-switch-label i').classList.remove('fa-moon');
document.querySelector('.theme-switch-label i').classList.add('fa-sun');
} else {
document.body.removeAttribute('data-theme');
themeToggle.checked = false;
document.querySelector('.theme-switch-label i').classList.remove('fa-sun');
document.querySelector('.theme-switch-label i').classList.add('fa-moon');
}
}
// Initialize theme on page load
initializeTheme();
// Theme toggle event listener
themeToggle.addEventListener('change', function() {
if (this.checked) {
document.body.setAttribute('data-theme', 'dark');
localStorage.setItem('theme', 'dark');
document.querySelector('.theme-switch-label i').classList.remove('fa-moon');
document.querySelector('.theme-switch-label i').classList.add('fa-sun');
} else {
document.body.removeAttribute('data-theme');
localStorage.setItem('theme', 'light');
document.querySelector('.theme-switch-label i').classList.remove('fa-sun');
document.querySelector('.theme-switch-label i').classList.add('fa-moon');
}
});
// Listen for system theme changes
prefersDarkScheme.addEventListener('change', function() {
// Only update if user hasn't set a manual preference
if (!localStorage.getItem('theme')) {
initializeTheme();
}
});
// Fetch GitHub stars
async function fetchGitHubStars() {
try {
const response = await fetch('https://api.github.com/repos/chrisvel/tududi');
const data = await response.json();
const stars = data.stargazers_count;
document.getElementById('github-stars').textContent = stars.toLocaleString();
} catch (error) {
console.log('GitHub API error:', error);
document.getElementById('github-stars').textContent = '100+';
}
}
// Fetch stars when page loads
fetchGitHubStars();
// Mobile menu toggle functionality
function toggleMobileMenu() {
const navLinks = document.querySelector('.nav-links');
navLinks.classList.toggle('active');
const menuIcon = document.querySelector('.mobile-menu-toggle i');
if (navLinks.classList.contains('active')) {
menuIcon.classList.remove('fa-bars');
menuIcon.classList.add('fa-times');
} else {
menuIcon.classList.remove('fa-times');
menuIcon.classList.add('fa-bars');
}
}
// Close mobile menu when clicking on a link
document.querySelectorAll('.nav-links a').forEach(link => {
link.addEventListener('click', () => {
const navLinks = document.querySelector('.nav-links');
const menuIcon = document.querySelector('.mobile-menu-toggle i');
navLinks.classList.remove('active');
menuIcon.classList.remove('fa-times');
menuIcon.classList.add('fa-bars');
});
});
</script>
</body>
</html>