summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobby Zambito <contact@robbyzambito.me>2025-08-06 19:01:42 -0400
committerRobby Zambito <contact@robbyzambito.me>2025-08-06 19:09:48 -0400
commit3b44ca084b946756d6b77ca693cbd24c9d3eb7ef (patch)
treef805cb32699ae942173caacc3425b682e723b22b
parent42c23d4628ab898fdbf35b7c5e3798efdd2a093a (diff)
Add blog page
Prompt: Add a blog page
-rw-r--r--static/about.html12
-rw-r--r--static/blog-script.js344
-rw-r--r--static/blog-styles.css765
-rw-r--r--static/blog.html347
-rw-r--r--static/index.html2
5 files changed, 1463 insertions, 7 deletions
diff --git a/static/about.html b/static/about.html
index eb7f5a2..1b223c3 100644
--- a/static/about.html
+++ b/static/about.html
@@ -10,10 +10,10 @@
<body>
<nav class="navbar">
<div class="nav-container">
- <a href="index.html" class="nav-logo">TaskFlow</a>
+ <a href="/" class="nav-logo">TaskFlow</a>
<ul class="nav-menu">
- <li><a href="index.html#features" class="nav-link">Features</a></li>
- <li><a href="index.html#pricing" class="nav-link">Pricing</a></li>
+ <li><a href="/#features" class="nav-link">Features</a></li>
+ <li><a href="/#pricing" class="nav-link">Pricing</a></li>
<li><a href="about.html" class="nav-link active">About</a></li>
<li><a href="#contact" class="nav-link">Contact</a></li>
</ul>
@@ -240,8 +240,8 @@
<div class="footer-section">
<h4>Product</h4>
<ul>
- <li><a href="index.html#features">Features</a></li>
- <li><a href="index.html#pricing">Pricing</a></li>
+ <li><a href="/#features">Features</a></li>
+ <li><a href="/#pricing">Pricing</a></li>
<li><a href="#integrations">Integrations</a></li>
<li><a href="#security">Security</a></li>
</ul>
@@ -251,7 +251,7 @@
<ul>
<li><a href="about.html">About</a></li>
<li><a href="#careers">Careers</a></li>
- <li><a href="#blog">Blog</a></li>
+ <li><a href="/blog.html">Blog</a></li>
<li><a href="#press">Press</a></li>
</ul>
</div>
diff --git a/static/blog-script.js b/static/blog-script.js
new file mode 100644
index 0000000..73719a8
--- /dev/null
+++ b/static/blog-script.js
@@ -0,0 +1,344 @@
+// DOM Elements
+const searchInput = document.getElementById('searchInput');
+const searchBtn = document.getElementById('searchBtn');
+const blogGrid = document.getElementById('blogGrid');
+const categoryLinks = document.querySelectorAll('.category-link');
+const sortSelect = document.getElementById('sortBy');
+const paginationNumbers = document.querySelectorAll('.pagination-number');
+const prevBtn = document.getElementById('prevBtn');
+const nextBtn = document.getElementById('nextBtn');
+
+// Blog posts data (in a real app, this would come from an API)
+const blogPosts = Array.from(document.querySelectorAll('.blog-post'));
+
+// Search functionality
+const performSearch = () => {
+ const searchTerm = searchInput.value.toLowerCase().trim();
+
+ blogPosts.forEach(post => {
+ const title = post.querySelector('.post-title').textContent.toLowerCase();
+ const excerpt = post.querySelector('.post-excerpt').textContent.toLowerCase();
+ const category = post.querySelector('.post-category').textContent.toLowerCase();
+
+ const matches = title.includes(searchTerm) ||
+ excerpt.includes(searchTerm) ||
+ category.includes(searchTerm);
+
+ post.style.display = matches || searchTerm === '' ? 'block' : 'none';
+ });
+
+ // Update results count
+ const visiblePosts = blogPosts.filter(post => post.style.display !== 'none');
+ updateResultsMessage(visiblePosts.length, searchTerm);
+};
+
+const updateResultsMessage = (count, searchTerm) => {
+ let existingMessage = document.querySelector('.search-results-message');
+
+ if (existingMessage) {
+ existingMessage.remove();
+ }
+
+ if (searchTerm) {
+ const message = document.createElement('div');
+ message.className = 'search-results-message';
+ message.style.cssText = `
+ padding: 1rem;
+ background: var(--surface);
+ border-radius: 0.5rem;
+ margin-bottom: 2rem;
+ color: var(--text-secondary);
+ text-align: center;
+ `;
+ message.textContent = `Found ${count} article${count !== 1 ? 's' : ''} for "${searchTerm}"`;
+
+ blogGrid.parentNode.insertBefore(message, blogGrid);
+ }
+};
+
+// Search event listeners
+searchBtn.addEventListener('click', performSearch);
+searchInput.addEventListener('keypress', (e) => {
+ if (e.key === 'Enter') {
+ performSearch();
+ }
+});
+
+// Real-time search
+searchInput.addEventListener('input', () => {
+ if (searchInput.value.length > 2 || searchInput.value.length === 0) {
+ performSearch();
+ }
+});
+
+// Category filtering
+categoryLinks.forEach(link => {
+ link.addEventListener('click', (e) => {
+ e.preventDefault();
+
+ // Update active state
+ categoryLinks.forEach(l => l.classList.remove('active'));
+ link.classList.add('active');
+
+ const category = link.dataset.category;
+
+ blogPosts.forEach(post => {
+ if (category === 'all') {
+ post.style.display = 'block';
+ } else {
+ const postCategory = post.dataset.category;
+ post.style.display = postCategory === category ? 'block' : 'none';
+ }
+ });
+
+ // Clear search when filtering by category
+ searchInput.value = '';
+ const existingMessage = document.querySelector('.search-results-message');
+ if (existingMessage) {
+ existingMessage.remove();
+ }
+
+ // Update pagination
+ updatePagination();
+ });
+});
+
+// Sorting functionality
+sortSelect.addEventListener('change', () => {
+ const sortBy = sortSelect.value;
+ const postsArray = Array.from(blogPosts);
+
+ postsArray.sort((a, b) => {
+ const dateA = new Date(a.querySelector('.post-date').textContent);
+ const dateB = new Date(b.querySelector('.post-date').textContent);
+
+ switch (sortBy) {
+ case 'newest':
+ return dateB - dateA;
+ case 'oldest':
+ return dateA - dateB;
+ case 'popular':
+ // In a real app, this would sort by view count or engagement
+ return Math.random() - 0.5;
+ default:
+ return 0;
+ }
+ });
+
+ // Re-append sorted posts to the grid
+ postsArray.forEach(post => {
+ blogGrid.appendChild(post);
+ });
+});
+
+// Pagination functionality
+let currentPage = 1;
+const postsPerPage = 6;
+
+const updatePagination = () => {
+ const visiblePosts = blogPosts.filter(post => post.style.display !== 'none');
+ const totalPages = Math.ceil(visiblePosts.length / postsPerPage);
+
+ // Show/hide posts based on current page
+ visiblePosts.forEach((post, index) => {
+ const startIndex = (currentPage - 1) * postsPerPage;
+ const endIndex = startIndex + postsPerPage;
+
+ if (index >= startIndex && index < endIndex) {
+ post.style.display = 'block';
+ } else {
+ post.style.display = 'none';
+ }
+ });
+
+ // Update pagination buttons
+ prevBtn.disabled = currentPage === 1;
+ nextBtn.disabled = currentPage === totalPages || totalPages === 0;
+
+ // Update page numbers
+ paginationNumbers.forEach((btn, index) => {
+ btn.classList.toggle('active', index + 1 === currentPage);
+ });
+};
+
+// Pagination event listeners
+prevBtn.addEventListener('click', () => {
+ if (currentPage > 1) {
+ currentPage--;
+ updatePagination();
+ scrollToTop();
+ }
+});
+
+nextBtn.addEventListener('click', () => {
+ const visiblePosts = blogPosts.filter(post => post.style.display !== 'none');
+ const totalPages = Math.ceil(visiblePosts.length / postsPerPage);
+
+ if (currentPage < totalPages) {
+ currentPage++;
+ updatePagination();
+ scrollToTop();
+ }
+});
+
+paginationNumbers.forEach((btn, index) => {
+ btn.addEventListener('click', () => {
+ currentPage = index + 1;
+ updatePagination();
+ scrollToTop();
+ });
+});
+
+const scrollToTop = () => {
+ blogGrid.scrollIntoView({ behavior: 'smooth', block: 'start' });
+};
+
+// Newsletter form handlers
+document.querySelectorAll('.newsletter-form, .newsletter-form-large').forEach(form => {
+ form.addEventListener('submit', (e) => {
+ e.preventDefault();
+ const email = form.querySelector('input[type="email"]').value;
+
+ if (email) {
+ showToast(`Thanks for subscribing! We'll send updates to ${email}`, 'success');
+ form.reset();
+ }
+ });
+});
+
+// Toast notification function
+const showToast = (message, type = 'success') => {
+ const toast = document.createElement('div');
+ toast.className = 'toast';
+ toast.style.cssText = `
+ position: fixed;
+ top: 2rem;
+ right: 2rem;
+ background: ${type === 'success' ? 'var(--success)' : 'var(--error)'};
+ color: white;
+ padding: 1rem 1.5rem;
+ border-radius: 0.5rem;
+ box-shadow: var(--shadow-lg);
+ z-index: 1000;
+ transform: translateX(100%);
+ transition: transform 0.3s ease;
+ `;
+ toast.textContent = message;
+
+ document.body.appendChild(toast);
+
+ // Show toast
+ setTimeout(() => {
+ toast.style.transform = 'translateX(0)';
+ }, 100);
+
+ // Hide toast
+ setTimeout(() => {
+ toast.style.transform = 'translateX(100%)';
+ setTimeout(() => {
+ document.body.removeChild(toast);
+ }, 300);
+ }, 4000);
+};
+
+// Read more link handlers
+document.querySelectorAll('.read-more').forEach(link => {
+ link.addEventListener('click', (e) => {
+ e.preventDefault();
+ const postTitle = link.closest('.blog-post').querySelector('.post-title').textContent;
+ showToast(`Opening article: "${postTitle}"`, 'success');
+
+ // In a real app, this would navigate to the full article
+ setTimeout(() => {
+ window.location.href = `article.html?title=${encodeURIComponent(postTitle)}`;
+ }, 1000);
+ });
+});
+
+// Navbar background on scroll
+window.addEventListener('scroll', () => {
+ const navbar = document.querySelector('.navbar');
+ if (window.scrollY > 50) {
+ navbar.style.background = 'rgba(255, 255, 255, 0.98)';
+ } else {
+ navbar.style.background = 'rgba(255, 255, 255, 0.95)';
+ }
+});
+
+// Intersection Observer for animations
+const observerOptions = {
+ threshold: 0.1,
+ rootMargin: '0px 0px -50px 0px'
+};
+
+const observer = new IntersectionObserver((entries) => {
+ entries.forEach(entry => {
+ if (entry.isIntersecting) {
+ entry.target.style.opacity = '1';
+ entry.target.style.transform = 'translateY(0)';
+ }
+ });
+}, observerOptions);
+
+// Observe blog posts for animation
+document.querySelectorAll('.blog-post').forEach(post => {
+ post.style.opacity = '0';
+ post.style.transform = 'translateY(30px)';
+ post.style.transition = 'opacity 0.6s ease, transform 0.6s ease';
+ observer.observe(post);
+});
+
+// Initialize page
+document.addEventListener('DOMContentLoaded', () => {
+ updatePagination();
+
+ // Add loading animation to hero elements
+ const heroTitle = document.querySelector('.hero-title');
+ const heroSubtitle = document.querySelector('.hero-subtitle');
+ const heroSearch = document.querySelector('.hero-search');
+
+ [heroTitle, heroSubtitle, heroSearch].forEach((element, index) => {
+ if (element) {
+ element.style.opacity = '0';
+ element.style.transform = 'translateY(30px)';
+ element.style.transition = 'opacity 0.8s ease, transform 0.8s ease';
+
+ setTimeout(() => {
+ element.style.opacity = '1';
+ element.style.transform = 'translateY(0)';
+ }, 200 + (index * 200));
+ }
+ });
+});
+
+// Button click handlers
+document.querySelectorAll('.btn').forEach(btn => {
+ btn.addEventListener('click', (e) => {
+ const buttonText = btn.textContent.toLowerCase();
+
+ if (buttonText.includes('trial') || buttonText.includes('start')) {
+ e.preventDefault();
+ showToast('Starting your free trial! Redirecting to registration...', 'success');
+ setTimeout(() => {
+ window.location.href = 'signup.html';
+ }, 2000);
+ }
+ });
+});
+
+// Sidebar sticky behavior enhancement
+window.addEventListener('scroll', () => {
+ const sidebar = document.querySelector('.blog-sidebar');
+ const footer = document.querySelector('.footer');
+
+ if (sidebar && footer) {
+ const sidebarRect = sidebar.getBoundingClientRect();
+ const footerRect = footer.getBoundingClientRect();
+
+ if (footerRect.top < window.innerHeight && sidebarRect.bottom > footerRect.top) {
+ sidebar.style.transform = `translateY(${footerRect.top - sidebarRect.bottom - 20}px)`;
+ } else {
+ sidebar.style.transform = 'translateY(0)';
+ }
+ }
+});
diff --git a/static/blog-styles.css b/static/blog-styles.css
new file mode 100644
index 0000000..3925008
--- /dev/null
+++ b/static/blog-styles.css
@@ -0,0 +1,765 @@
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+:root {
+ --primary-color: #6366f1;
+ --primary-dark: #4f46e5;
+ --secondary-color: #f1f5f9;
+ --text-primary: #1e293b;
+ --text-secondary: #64748b;
+ --background: #ffffff;
+ --surface: #f8fafc;
+ --border: #e2e8f0;
+ --success: #10b981;
+ --warning: #f59e0b;
+ --error: #ef4444;
+ --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
+ --shadow-lg: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
+ --gradient: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
+}
+
+body {
+ font-family: 'Inter', sans-serif;
+ line-height: 1.6;
+ color: var(--text-primary);
+ background: var(--background);
+}
+
+.container {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 0 2rem;
+}
+
+/* Navigation */
+.navbar {
+ position: fixed;
+ top: 0;
+ width: 100%;
+ background: rgba(255, 255, 255, 0.95);
+ backdrop-filter: blur(10px);
+ z-index: 1000;
+ border-bottom: 1px solid var(--border);
+}
+
+.nav-container {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 1rem 2rem;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.nav-logo {
+ font-size: 1.5rem;
+ font-weight: 700;
+ background: var(--gradient);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ text-decoration: none;
+}
+
+.nav-menu {
+ display: flex;
+ list-style: none;
+ gap: 2rem;
+}
+
+.nav-link {
+ text-decoration: none;
+ color: var(--text-primary);
+ font-weight: 500;
+ transition: color 0.3s ease;
+}
+
+.nav-link:hover,
+.nav-link.active {
+ color: var(--primary-color);
+}
+
+.nav-actions {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+}
+
+/* Buttons */
+.btn {
+ padding: 0.75rem 1.5rem;
+ border: none;
+ border-radius: 0.5rem;
+ font-weight: 600;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ text-decoration: none;
+ display: inline-block;
+ font-size: 0.875rem;
+}
+
+.btn-small {
+ padding: 0.5rem 1rem;
+ font-size: 0.75rem;
+}
+
+.btn-primary {
+ background: var(--gradient);
+ color: white;
+ box-shadow: var(--shadow);
+}
+
+.btn-primary:hover {
+ transform: translateY(-2px);
+ box-shadow: var(--shadow-lg);
+}
+
+.btn-ghost {
+ background: transparent;
+ color: var(--text-primary);
+ border: none;
+}
+
+.btn-ghost:hover {
+ background: var(--surface);
+}
+
+/* Hero Section */
+.hero {
+ padding: 8rem 0 4rem;
+ background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
+ text-align: center;
+}
+
+.hero-title {
+ font-size: 3.5rem;
+ font-weight: 700;
+ line-height: 1.1;
+ margin-bottom: 1.5rem;
+}
+
+.gradient-text {
+ background: var(--gradient);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.hero-subtitle {
+ font-size: 1.25rem;
+ color: var(--text-secondary);
+ max-width: 800px;
+ margin: 0 auto 2rem;
+ line-height: 1.6;
+}
+
+.hero-search {
+ max-width: 500px;
+ margin: 0 auto;
+}
+
+.search-container {
+ position: relative;
+ display: flex;
+ align-items: center;
+}
+
+.search-input {
+ width: 100%;
+ padding: 1rem 1.5rem;
+ padding-right: 4rem;
+ border: 2px solid var(--border);
+ border-radius: 0.75rem;
+ font-size: 1rem;
+ background: white;
+ transition: border-color 0.3s ease;
+}
+
+.search-input:focus {
+ outline: none;
+ border-color: var(--primary-color);
+}
+
+.search-btn {
+ position: absolute;
+ right: 0.75rem;
+ background: var(--primary-color);
+ color: white;
+ border: none;
+ border-radius: 0.5rem;
+ padding: 0.75rem;
+ cursor: pointer;
+ transition: background-color 0.3s ease;
+}
+
+.search-btn:hover {
+ background: var(--primary-dark);
+}
+
+/* Blog Content */
+.blog-content {
+ padding: 4rem 0;
+}
+
+.blog-layout {
+ display: grid;
+ grid-template-columns: 300px 1fr;
+ gap: 3rem;
+}
+
+/* Sidebar */
+.blog-sidebar {
+ position: sticky;
+ top: 6rem;
+ height: fit-content;
+}
+
+.sidebar-section {
+ background: white;
+ border-radius: 1rem;
+ padding: 1.5rem;
+ margin-bottom: 2rem;
+ box-shadow: var(--shadow);
+}
+
+.sidebar-section h3 {
+ font-size: 1.125rem;
+ font-weight: 600;
+ margin-bottom: 1rem;
+ color: var(--text-primary);
+}
+
+.category-list {
+ list-style: none;
+}
+
+.category-list li {
+ margin-bottom: 0.5rem;
+}
+
+.category-link {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0.5rem 0.75rem;
+ border-radius: 0.5rem;
+ text-decoration: none;
+ color: var(--text-secondary);
+ font-weight: 500;
+ transition: all 0.3s ease;
+}
+
+.category-link:hover,
+.category-link.active {
+ background: var(--surface);
+ color: var(--primary-color);
+}
+
+.count {
+ font-size: 0.75rem;
+ background: var(--border);
+ color: var(--text-secondary);
+ padding: 0.25rem 0.5rem;
+ border-radius: 1rem;
+}
+
+.category-link.active .count {
+ background: var(--primary-color);
+ color: white;
+}
+
+.recent-posts {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.recent-post {
+ padding-bottom: 1rem;
+ border-bottom: 1px solid var(--border);
+}
+
+.recent-post:last-child {
+ border-bottom: none;
+ padding-bottom: 0;
+}
+
+.recent-post-meta {
+ margin-bottom: 0.5rem;
+}
+
+.recent-post-date {
+ font-size: 0.75rem;
+ color: var(--text-secondary);
+}
+
+.recent-post h4 {
+ font-size: 0.875rem;
+ line-height: 1.4;
+}
+
+.recent-post h4 a {
+ text-decoration: none;
+ color: var(--text-primary);
+ transition: color 0.3s ease;
+}
+
+.recent-post h4 a:hover {
+ color: var(--primary-color);
+}
+
+.newsletter-signup p {
+ font-size: 0.875rem;
+ color: var(--text-secondary);
+ margin-bottom: 1rem;
+}
+
+.newsletter-form {
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+}
+
+.newsletter-input {
+ padding: 0.75rem;
+ border: 2px solid var(--border);
+ border-radius: 0.5rem;
+ font-size: 0.875rem;
+}
+
+.newsletter-input:focus {
+ outline: none;
+ border-color: var(--primary-color);
+}
+
+/* Main Content */
+.blog-main {
+ min-height: 100vh;
+}
+
+.blog-filters {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 2rem;
+ padding: 1rem;
+ background: white;
+ border-radius: 0.75rem;
+ box-shadow: var(--shadow);
+}
+
+.filter-group {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+.filter-group label {
+ font-weight: 500;
+ color: var(--text-secondary);
+}
+
+.filter-select {
+ padding: 0.5rem 1rem;
+ border: 2px solid var(--border);
+ border-radius: 0.5rem;
+ background: white;
+ cursor: pointer;
+}
+
+.filter-select:focus {
+ outline: none;
+ border-color: var(--primary-color);
+}
+
+/* Blog Grid */
+.blog-grid {
+ display: grid;
+ gap: 2rem;
+ margin-bottom: 3rem;
+}
+
+.blog-post {
+ background: white;
+ border-radius: 1rem;
+ overflow: hidden;
+ box-shadow: var(--shadow);
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
+}
+
+.blog-post:hover {
+ transform: translateY(-5px);
+ box-shadow: var(--shadow-lg);
+}
+
+.blog-post.featured {
+ grid-column: 1 / -1;
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 0;
+}
+
+.post-image {
+ position: relative;
+ overflow: hidden;
+}
+
+.post-image img {
+ width: 100%;
+ height: 250px;
+ object-fit: cover;
+ transition: transform 0.3s ease;
+}
+
+.blog-post:hover .post-image img {
+ transform: scale(1.05);
+}
+
+.post-badge {
+ position: absolute;
+ top: 1rem;
+ left: 1rem;
+ background: var(--gradient);
+ color: white;
+ padding: 0.5rem 1rem;
+ border-radius: 1rem;
+ font-size: 0.75rem;
+ font-weight: 600;
+}
+
+.post-content {
+ padding: 2rem;
+}
+
+.post-meta {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+ margin-bottom: 1rem;
+ font-size: 0.875rem;
+}
+
+.post-category {
+ background: var(--surface);
+ color: var(--primary-color);
+ padding: 0.25rem 0.75rem;
+ border-radius: 1rem;
+ font-weight: 500;
+}
+
+.post-date,
+.post-read-time {
+ color: var(--text-secondary);
+}
+
+.post-title {
+ font-size: 1.5rem;
+ font-weight: 700;
+ line-height: 1.3;
+ margin-bottom: 1rem;
+ color: var(--text-primary);
+}
+
+.blog-post.featured .post-title {
+ font-size: 2rem;
+}
+
+.post-excerpt {
+ color: var(--text-secondary);
+ line-height: 1.6;
+ margin-bottom: 1.5rem;
+}
+
+.post-footer {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.post-author {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+}
+
+.author-avatar {
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+ background: var(--gradient);
+ color: white;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 0.75rem;
+ font-weight: 600;
+}
+
+.author-name {
+ font-weight: 500;
+ color: var(--text-primary);
+}
+
+.read-more {
+ color: var(--primary-color);
+ text-decoration: none;
+ font-weight: 600;
+ transition: color 0.3s ease;
+}
+
+.read-more:hover {
+ color: var(--primary-dark);
+}
+
+/* Pagination */
+.pagination {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 1rem;
+ margin-top: 3rem;
+}
+
+.pagination-btn {
+ padding: 0.75rem 1.5rem;
+ border: 2px solid var(--border);
+ background: white;
+ color: var(--text-primary);
+ border-radius: 0.5rem;
+ cursor: pointer;
+ font-weight: 500;
+ transition: all 0.3s ease;
+}
+
+.pagination-btn:hover:not(:disabled) {
+ border-color: var(--primary-color);
+ color: var(--primary-color);
+}
+
+.pagination-btn:disabled {
+ opacity: 0.5;
+ cursor: not-allowed;
+}
+
+.pagination-numbers {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+.pagination-number {
+ width: 40px;
+ height: 40px;
+ border: 2px solid var(--border);
+ background: white;
+ color: var(--text-primary);
+ border-radius: 0.5rem;
+ cursor: pointer;
+ font-weight: 500;
+ transition: all 0.3s ease;
+}
+
+.pagination-number:hover,
+.pagination-number.active {
+ border-color: var(--primary-color);
+ background: var(--primary-color);
+ color: white;
+}
+
+.pagination-dots {
+ color: var(--text-secondary);
+ margin: 0 0.5rem;
+}
+
+/* Newsletter CTA */
+.newsletter-cta {
+ padding: 4rem 0;
+ background: var(--text-primary);
+ color: white;
+ text-align: center;
+}
+
+.newsletter-content h2 {
+ font-size: 2.5rem;
+ font-weight: 700;
+ margin-bottom: 1rem;
+}
+
+.newsletter-content p {
+ font-size: 1.125rem;
+ opacity: 0.9;
+ margin-bottom: 2rem;
+}
+
+.newsletter-form-large {
+ display: flex;
+ justify-content: center;
+ gap: 1rem;
+ margin-bottom: 1rem;
+ max-width: 500px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.newsletter-input-large {
+ flex: 1;
+ padding: 1rem 1.5rem;
+ border: none;
+ border-radius: 0.5rem;
+ font-size: 1rem;
+}
+
+.newsletter-input-large:focus {
+ outline: none;
+}
+
+.newsletter-note {
+ font-size: 0.875rem;
+ opacity: 0.7;
+}
+
+/* Footer */
+.footer {
+ background: var(--text-primary);
+ color: white;
+ padding: 4rem 0 2rem;
+}
+
+.footer-content {
+ display: grid;
+ grid-template-columns: 2fr 1fr 1fr 1fr;
+ gap: 3rem;
+ margin-bottom: 3rem;
+}
+
+.footer-logo {
+ font-size: 1.5rem;
+ font-weight: 700;
+ margin-bottom: 1rem;
+}
+
+.footer-section h4 {
+ font-weight: 600;
+ margin-bottom: 1rem;
+}
+
+.footer-section ul {
+ list-style: none;
+}
+
+.footer-section ul li {
+ margin-bottom: 0.5rem;
+}
+
+.footer-section ul li a {
+ color: rgba(255, 255, 255, 0.8);
+ text-decoration: none;
+ transition: color 0.3s ease;
+}
+
+.footer-section ul li a:hover {
+ color: white;
+}
+
+.footer-bottom {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding-top: 2rem;
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
+}
+
+.footer-links {
+ display: flex;
+ gap: 2rem;
+}
+
+.footer-links a {
+ color: rgba(255, 255, 255, 0.8);
+ text-decoration: none;
+ transition: color 0.3s ease;
+}
+
+.footer-links a:hover {
+ color: white;
+}
+
+/* Responsive Design */
+@media (max-width: 768px) {
+ .nav-menu {
+ display: none;
+ }
+
+ .hero-title {
+ font-size: 2.5rem;
+ }
+
+ .blog-layout {
+ grid-template-columns: 1fr;
+ gap: 2rem;
+ }
+
+ .blog-sidebar {
+ position: static;
+ order: 2;
+ }
+
+ .blog-post.featured {
+ grid-template-columns: 1fr;
+ }
+
+ .blog-post.featured .post-title {
+ font-size: 1.5rem;
+ }
+
+ .newsletter-form-large {
+ flex-direction: column;
+ }
+
+ .footer-content {
+ grid-template-columns: 1fr;
+ text-align: center;
+ }
+
+ .footer-bottom {
+ flex-direction: column;
+ gap: 1rem;
+ text-align: center;
+ }
+}
+
+@media (max-width: 480px) {
+ .container {
+ padding: 0 1rem;
+ }
+
+ .hero {
+ padding: 6rem 0 3rem;
+ }
+
+ .hero-title {
+ font-size: 2rem;
+ }
+
+ .post-content {
+ padding: 1.5rem;
+ }
+
+ .post-title {
+ font-size: 1.25rem;
+ }
+
+ .pagination {
+ flex-wrap: wrap;
+ gap: 0.5rem;
+ }
+
+ .pagination-numbers {
+ order: -1;
+ width: 100%;
+ justify-content: center;
+ }
+}
diff --git a/static/blog.html b/static/blog.html
new file mode 100644
index 0000000..2fc128b
--- /dev/null
+++ b/static/blog.html
@@ -0,0 +1,347 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Blog - TaskFlow</title>
+ <link rel="stylesheet" href="blog-styles.css">
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
+</head>
+<body>
+ <nav class="navbar">
+ <div class="nav-container">
+ <a href="/" class="nav-logo">TaskFlow</a>
+ <ul class="nav-menu">
+ <li><a href="/#features" class="nav-link">Features</a></li>
+ <li><a href="/#pricing" class="nav-link">Pricing</a></li>
+ <li><a href="about.html" class="nav-link">About</a></li>
+ <li><a href="blog.html" class="nav-link active">Blog</a></li>
+ <li><a href="#contact" class="nav-link">Contact</a></li>
+ </ul>
+ <div class="nav-actions">
+ <a href="login.html" class="btn btn-ghost">Sign In</a>
+ <button class="btn btn-primary">Start Free Trial</button>
+ </div>
+ </div>
+ </nav>
+
+ <main>
+ <section class="hero">
+ <div class="container">
+ <div class="hero-content">
+ <h1 class="hero-title">TaskFlow <span class="gradient-text">Blog</span></h1>
+ <p class="hero-subtitle">
+ Insights, tips, and best practices for project management, team collaboration,
+ and productivity from the TaskFlow team and industry experts.
+ </p>
+ <div class="hero-search">
+ <div class="search-container">
+ <input type="text" placeholder="Search articles..." class="search-input" id="searchInput">
+ <button class="search-btn" id="searchBtn">
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
+ <circle cx="11" cy="11" r="8"></circle>
+ <path d="m21 21-4.35-4.35"></path>
+ </svg>
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+
+ <section class="blog-content">
+ <div class="container">
+ <div class="blog-layout">
+ <aside class="blog-sidebar">
+ <div class="sidebar-section">
+ <h3>Categories</h3>
+ <ul class="category-list">
+ <li><a href="#" class="category-link active" data-category="all">All Posts <span class="count">24</span></a></li>
+ <li><a href="#" class="category-link" data-category="productivity">Productivity <span class="count">8</span></a></li>
+ <li><a href="#" class="category-link" data-category="project-management">Project Management <span class="count">6</span></a></li>
+ <li><a href="#" class="category-link" data-category="team-collaboration">Team Collaboration <span class="count">5</span></a></li>
+ <li><a href="#" class="category-link" data-category="remote-work">Remote Work <span class="count">3</span></a></li>
+ <li><a href="#" class="category-link" data-category="company-news">Company News <span class="count">2</span></a></li>
+ </ul>
+ </div>
+
+ <div class="sidebar-section">
+ <h3>Recent Posts</h3>
+ <div class="recent-posts">
+ <article class="recent-post">
+ <div class="recent-post-meta">
+ <span class="recent-post-date">Jan 15, 2025</span>
+ </div>
+ <h4><a href="#post1">10 Project Management Trends to Watch in 2025</a></h4>
+ </article>
+ <article class="recent-post">
+ <div class="recent-post-meta">
+ <span class="recent-post-date">Jan 10, 2025</span>
+ </div>
+ <h4><a href="#post2">How to Build High-Performing Remote Teams</a></h4>
+ </article>
+ <article class="recent-post">
+ <div class="recent-post-meta">
+ <span class="recent-post-date">Jan 5, 2025</span>
+ </div>
+ <h4><a href="#post3">The Ultimate Guide to Agile Project Management</a></h4>
+ </article>
+ </div>
+ </div>
+
+ <div class="sidebar-section">
+ <h3>Newsletter</h3>
+ <div class="newsletter-signup">
+ <p>Get the latest insights delivered to your inbox.</p>
+ <form class="newsletter-form">
+ <input type="email" placeholder="Your email address" class="newsletter-input">
+ <button type="submit" class="btn btn-primary btn-small">Subscribe</button>
+ </form>
+ </div>
+ </div>
+ </aside>
+
+ <div class="blog-main">
+ <div class="blog-filters">
+ <div class="filter-group">
+ <label for="sortBy">Sort by:</label>
+ <select id="sortBy" class="filter-select">
+ <option value="newest">Newest First</option>
+ <option value="oldest">Oldest First</option>
+ <option value="popular">Most Popular</option>
+ </select>
+ </div>
+ </div>
+
+ <div class="blog-grid" id="blogGrid">
+ <article class="blog-post featured" data-category="project-management">
+ <div class="post-image">
+ <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 250'%3E%3Crect width='400' height='250' fill='%236366f1'/%3E%3Ctext x='200' y='130' text-anchor='middle' fill='white' font-size='24' font-family='Inter'%3EProject Trends 2025%3C/text%3E%3C/svg%3E" alt="Project Management Trends 2025">
+ <div class="post-badge">Featured</div>
+ </div>
+ <div class="post-content">
+ <div class="post-meta">
+ <span class="post-category">Project Management</span>
+ <span class="post-date">January 15, 2025</span>
+ <span class="post-read-time">8 min read</span>
+ </div>
+ <h2 class="post-title">10 Project Management Trends to Watch in 2025</h2>
+ <p class="post-excerpt">
+ Discover the emerging trends that will shape project management in 2025, from AI-powered
+ automation to hybrid work methodologies that are transforming how teams collaborate.
+ </p>
+ <div class="post-footer">
+ <div class="post-author">
+ <div class="author-avatar">AS</div>
+ <span class="author-name">Alex Smith</span>
+ </div>
+ <a href="#post1" class="read-more">Read More →</a>
+ </div>
+ </div>
+ </article>
+
+ <article class="blog-post" data-category="team-collaboration">
+ <div class="post-image">
+ <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 250'%3E%3Crect width='400' height='250' fill='%238b5cf6'/%3E%3Ctext x='200' y='130' text-anchor='middle' fill='white' font-size='20' font-family='Inter'%3ERemote Team Building%3C/text%3E%3C/svg%3E" alt="Remote Team Building">
+ </div>
+ <div class="post-content">
+ <div class="post-meta">
+ <span class="post-category">Team Collaboration</span>
+ <span class="post-date">January 10, 2025</span>
+ <span class="post-read-time">6 min read</span>
+ </div>
+ <h2 class="post-title">How to Build High-Performing Remote Teams</h2>
+ <p class="post-excerpt">
+ Learn proven strategies for creating cohesive, productive remote teams that deliver
+ exceptional results while maintaining strong communication and collaboration.
+ </p>
+ <div class="post-footer">
+ <div class="post-author">
+ <div class="author-avatar">SJ</div>
+ <span class="author-name">Sarah Johnson</span>
+ </div>
+ <a href="#post2" class="read-more">Read More →</a>
+ </div>
+ </div>
+ </article>
+
+ <article class="blog-post" data-category="productivity">
+ <div class="post-image">
+ <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 250'%3E%3Crect width='400' height='250' fill='%2310b981'/%3E%3Ctext x='200' y='130' text-anchor='middle' fill='white' font-size='22' font-family='Inter'%3EAgile Guide%3C/text%3E%3C/svg%3E" alt="Agile Project Management">
+ </div>
+ <div class="post-content">
+ <div class="post-meta">
+ <span class="post-category">Productivity</span>
+ <span class="post-date">January 5, 2025</span>
+ <span class="post-read-time">12 min read</span>
+ </div>
+ <h2 class="post-title">The Ultimate Guide to Agile Project Management</h2>
+ <p class="post-excerpt">
+ A comprehensive guide to implementing Agile methodologies in your projects, including
+ best practices, common pitfalls, and tools to maximize team efficiency.
+ </p>
+ <div class="post-footer">
+ <div class="post-author">
+ <div class="author-avatar">MC</div>
+ <span class="author-name">Mike Chen</span>
+ </div>
+ <a href="#post3" class="read-more">Read More →</a>
+ </div>
+ </div>
+ </article>
+
+ <article class="blog-post" data-category="remote-work">
+ <div class="post-image">
+ <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 250'%3E%3Crect width='400' height='250' fill='%23f59e0b'/%3E%3Ctext x='200' y='130' text-anchor='middle' fill='white' font-size='18' font-family='Inter'%3EProductivity Hacks%3C/text%3E%3C/svg%3E" alt="Productivity Hacks">
+ </div>
+ <div class="post-content">
+ <div class="post-meta">
+ <span class="post-category">Remote Work</span>
+ <span class="post-date">December 28, 2024</span>
+ <span class="post-read-time">5 min read</span>
+ </div>
+ <h2 class="post-title">5 Productivity Hacks for Remote Workers</h2>
+ <p class="post-excerpt">
+ Boost your productivity while working from home with these proven techniques that help
+ you stay focused, organized, and motivated throughout the day.
+ </p>
+ <div class="post-footer">
+ <div class="post-author">
+ <div class="author-avatar">LD</div>
+ <span class="author-name">Lisa Davis</span>
+ </div>
+ <a href="#post4" class="read-more">Read More →</a>
+ </div>
+ </div>
+ </article>
+
+ <article class="blog-post" data-category="project-management">
+ <div class="post-image">
+ <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 250'%3E%3Crect width='400' height='250' fill='%23ef4444'/%3E%3Ctext x='200' y='130' text-anchor='middle' fill='white' font-size='20' font-family='Inter'%3EProject Failures%3C/text%3E%3C/svg%3E" alt="Project Failures">
+ </div>
+ <div class="post-content">
+ <div class="post-meta">
+ <span class="post-category">Project Management</span>
+ <span class="post-date">December 20, 2024</span>
+ <span class="post-read-time">7 min read</span>
+ </div>
+ <h2 class="post-title">Why Projects Fail and How to Prevent It</h2>
+ <p class="post-excerpt">
+ Analyze the most common reasons projects fail and learn actionable strategies to
+ identify warning signs early and keep your projects on track for success.
+ </p>
+ <div class="post-footer">
+ <div class="post-author">
+ <div class="author-avatar">AS</div>
+ <span class="author-name">Alex Smith</span>
+ </div>
+ <a href="#post5" class="read-more">Read More →</a>
+ </div>
+ </div>
+ </article>
+
+ <article class="blog-post" data-category="company-news">
+ <div class="post-image">
+ <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 250'%3E%3Crect width='400' height='250' fill='%236366f1'/%3E%3Ctext x='200' y='130' text-anchor='middle' fill='white' font-size='18' font-family='Inter'%3ETaskFlow Updates%3C/text%3E%3C/svg%3E" alt="TaskFlow Updates">
+ </div>
+ <div class="post-content">
+ <div class="post-meta">
+ <span class="post-category">Company News</span>
+ <span class="post-date">December 15, 2024</span>
+ <span class="post-read-time">4 min read</span>
+ </div>
+ <h2 class="post-title">TaskFlow 2.0: New Features and Improvements</h2>
+ <p class="post-excerpt">
+ Discover the latest updates to TaskFlow, including enhanced collaboration tools,
+ improved analytics, and new integrations that make project management even easier.
+ </p>
+ <div class="post-footer">
+ <div class="post-author">
+ <div class="author-avatar">TF</div>
+ <span class="author-name">TaskFlow Team</span>
+ </div>
+ <a href="#post6" class="read-more">Read More →</a>
+ </div>
+ </div>
+ </article>
+ </div>
+
+ <div class="pagination">
+ <button class="pagination-btn" id="prevBtn" disabled>← Previous</button>
+ <div class="pagination-numbers">
+ <button class="pagination-number active">1</button>
+ <button class="pagination-number">2</button>
+ <button class="pagination-number">3</button>
+ <span class="pagination-dots">...</span>
+ <button class="pagination-number">8</button>
+ </div>
+ <button class="pagination-btn" id="nextBtn">Next →</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+
+ <section class="newsletter-cta">
+ <div class="container">
+ <div class="newsletter-content">
+ <h2>Stay Updated</h2>
+ <p>Get the latest project management insights and TaskFlow updates delivered to your inbox.</p>
+ <form class="newsletter-form-large">
+ <input type="email" placeholder="Enter your email address" class="newsletter-input-large">
+ <button type="submit" class="btn btn-primary">Subscribe Now</button>
+ </form>
+ <p class="newsletter-note">No spam, unsubscribe at any time.</p>
+ </div>
+ </div>
+ </section>
+ </main>
+
+ <footer class="footer">
+ <div class="container">
+ <div class="footer-content">
+ <div class="footer-section">
+ <div class="footer-logo">TaskFlow</div>
+ <p>Streamline your project management with the tools teams love to use.</p>
+ </div>
+ <div class="footer-section">
+ <h4>Product</h4>
+ <ul>
+ <li><a href="/#features">Features</a></li>
+ <li><a href="/#pricing">Pricing</a></li>
+ <li><a href="#integrations">Integrations</a></li>
+ <li><a href="#security">Security</a></li>
+ </ul>
+ </div>
+ <div class="footer-section">
+ <h4>Company</h4>
+ <ul>
+ <li><a href="about.html">About</a></li>
+ <li><a href="#careers">Careers</a></li>
+ <li><a href="blog.html">Blog</a></li>
+ <li><a href="#press">Press</a></li>
+ </ul>
+ </div>
+ <div class="footer-section">
+ <h4>Support</h4>
+ <ul>
+ <li><a href="#help">Help Center</a></li>
+ <li><a href="#contact">Contact</a></li>
+ <li><a href="#status">Status</a></li>
+ <li><a href="#api">API Docs</a></li>
+ </ul>
+ </div>
+ </div>
+ <div class="footer-bottom">
+ <p>&copy; 2025 TaskFlow. All rights reserved.</p>
+ <div class="footer-links">
+ <a href="#privacy">Privacy Policy</a>
+ <a href="#terms">Terms of Service</a>
+ </div>
+ </div>
+ </div>
+ </footer>
+
+ <script src="blog-script.js"></script>
+</body>
+</html>
diff --git a/static/index.html b/static/index.html
index 89ff7b7..9d8eca8 100644
--- a/static/index.html
+++ b/static/index.html
@@ -288,7 +288,7 @@
<ul>
<li><a href="/about.html">About</a></li>
<li><a href="#careers">Careers</a></li>
- <li><a href="#blog">Blog</a></li>
+ <li><a href="/blog.html">Blog</a></li>
<li><a href="#press">Press</a></li>
</ul>
</div>