diff options
author | Robby Zambito <contact@robbyzambito.me> | 2025-08-06 19:01:42 -0400 |
---|---|---|
committer | Robby Zambito <contact@robbyzambito.me> | 2025-08-06 19:09:48 -0400 |
commit | 3b44ca084b946756d6b77ca693cbd24c9d3eb7ef (patch) | |
tree | f805cb32699ae942173caacc3425b682e723b22b | |
parent | 42c23d4628ab898fdbf35b7c5e3798efdd2a093a (diff) |
Add blog page
Prompt:
Add a blog page
-rw-r--r-- | static/about.html | 12 | ||||
-rw-r--r-- | static/blog-script.js | 344 | ||||
-rw-r--r-- | static/blog-styles.css | 765 | ||||
-rw-r--r-- | static/blog.html | 347 | ||||
-rw-r--r-- | static/index.html | 2 |
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>© 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> |