From 66610323fef9fda714d3f4be3a8ea5652293ac51 Mon Sep 17 00:00:00 2001 From: awcodify Date: Thu, 29 May 2025 20:40:18 +0700 Subject: [PATCH 01/30] Add home-v2 layout: Social Media Inspired Design - Introduced a new homepage layout (home-v2) with a modern, social media-inspired design. - Implemented CSS styles in _sass/components/_home-v2.scss for layout aesthetics and responsiveness. - Added JavaScript functionality in assets/js/home-v2.js for interactive features like stories navigation, post filtering, and share actions. - Updated extended.scss and main.scss to include the new home-v2 styles. - Created documentation (docs/home-v2-layout.md) detailing features, usage, and customization options for the new layout. - Updated layouts.md to include a summary of the home-v2 layout and its key features. - Changed the index.html layout to use home-v2 for the main page. --- _layouts/home-v2.html | 277 ++++++++++++ _sass/components/_home-v2.scss | 776 +++++++++++++++++++++++++++++++++ assets/css/extended.scss | 1 + assets/css/main.scss | 1 + assets/js/home-v2.js | 326 ++++++++++++++ docs/home-v2-layout.md | 209 +++++++++ docs/layouts.md | 23 + index.html | 2 +- 8 files changed, 1614 insertions(+), 1 deletion(-) create mode 100644 _layouts/home-v2.html create mode 100644 _sass/components/_home-v2.scss create mode 100644 assets/js/home-v2.js create mode 100644 docs/home-v2-layout.md diff --git a/_layouts/home-v2.html b/_layouts/home-v2.html new file mode 100644 index 0000000..b223da8 --- /dev/null +++ b/_layouts/home-v2.html @@ -0,0 +1,277 @@ +--- +layout: default +--- + +
+ +
+
+
+
+
+ All Categories + +
+
+ +
+ + {% assign categories_list = site.categories %} + {% for category in categories_list limit:8 %} +
+
+
+ {{ category[0] }} + +
+
+ +
+ {% endfor %} +
+
+ + +
+ +
+ +
+
+ + + +
+
+ + +
+
+ + +
+ {% assign posts_to_show = paginator.posts | default: site.posts %} + {% for post in posts_to_show limit:10 %} +
+ + +
+
+
+ {{ post.author | default: site.author }} + +
+
+ {{ post.author | default: site.author }} + +
+
+ {% if post.featured %} + + {% endif %} +
+ + +
+

+ {{ post.title | escape }} +

+ +
+ {{ post.excerpt | strip_html | truncatewords: 25 }} +
+ + {% if post.tags.size > 0 %} + + {% endif %} + + {% if post.image %} +
+ + {{ post.title }} + +
+ {% endif %} +
+ + +
+
+ + + + + + Read Article + + + + + + + Comments + + + +
+ + +
+
+ {% endfor %} +
+ + +
+ +
+
+ + + +
+
diff --git a/_sass/components/_home-v2.scss b/_sass/components/_home-v2.scss new file mode 100644 index 0000000..0b1083e --- /dev/null +++ b/_sass/components/_home-v2.scss @@ -0,0 +1,776 @@ +// Social Media Inspired Homepage Layout (home-v2) +// Modern, clean design for static Jekyll blogs with social media aesthetics + +// Define CSS custom properties for theme support +:root { + --home-v2-bg: #fafafa; + --home-v2-card-bg: #ffffff; + --home-v2-text: #1f2937; + --home-v2-text-muted: #6b7280; + --home-v2-border: #e2e8f0; + --home-v2-hover: #f3f4f6; + --home-v2-primary: #3b82f6; + --home-v2-accent: #8b5cf6; + --home-v2-success: #10b981; + --home-v2-warning: #f59e0b; + --home-v2-shadow: rgba(0, 0, 0, 0.1); + --home-v2-shadow-hover: rgba(0, 0, 0, 0.15); +} + +// Dark theme support +@media (prefers-color-scheme: dark) { + :root { + --home-v2-bg: #0f172a; + --home-v2-card-bg: #1e293b; + --home-v2-text: #f8fafc; + --home-v2-text-muted: #94a3b8; + --home-v2-border: #334155; + --home-v2-hover: #334155; + --home-v2-shadow: rgba(0, 0, 0, 0.3); + --home-v2-shadow-hover: rgba(0, 0, 0, 0.4); + } +} + +.home-v2 { + background: var(--home-v2-bg); + min-height: 100vh; + color: var(--home-v2-text); + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', sans-serif; + line-height: 1.6; + + // Stories Section - Instagram-inspired category navigation + .stories-section { + background: transparent; + padding: 1rem 0; + margin-bottom: 2rem; + position: sticky; + top: 0; + z-index: 100; + + .stories-container { + max-width: 1200px; + margin: 0 auto; + padding: 0 1rem; + display: flex; + gap: 1rem; + overflow-x: auto; + scrollbar-width: none; + -ms-overflow-style: none; + + &::-webkit-scrollbar { + display: none; + } + + .story-item { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; + min-width: 80px; + cursor: pointer; + transition: transform 0.2s ease; + + &:hover { + transform: translateY(-2px); + } + + &.active .avatar-ring { + background: linear-gradient(45deg, #f09433 0%, #e6683c 25%, #dc2743 50%, #cc2366 75%, #bc1888 100%); + padding: 3px; + } + + .story-avatar { + position: relative; + width: 66px; + height: 66px; + + .avatar-ring { + width: 100%; + height: 100%; + border-radius: 50%; + background: linear-gradient(45deg, #405de6, #5851db, #833ab4, #c13584, #e1306c, #fd1d1d); + padding: 2px; + display: flex; + align-items: center; + justify-content: center; + + img, .story-placeholder { + width: 58px; + height: 58px; + border-radius: 50%; + object-fit: cover; + background: var(--home-v2-card-bg); + border: 2px solid var(--home-v2-card-bg); + } + + .story-placeholder { + display: flex; + align-items: center; + justify-content: center; + font-size: 1.5rem; + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + } + } + } + + .story-label { + font-size: 0.75rem; + color: var(--home-v2-text-muted); + text-align: center; + max-width: 80px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-weight: 500; + } + } + } + } + + // Main Feed Container + .feed-container { + max-width: 1200px; + margin: 0 auto; + padding: 0 1rem; + display: grid; + grid-template-columns: 1fr 320px; + gap: 2rem; + + @media (max-width: 1024px) { + grid-template-columns: 1fr; + gap: 1rem; + + .social-sidebar { + display: none; + } + } + } + + // Feed Controls + .feed-controls { + background: var(--home-v2-card-bg); + border: 1px solid var(--home-v2-border); + border-radius: 16px; + padding: 1rem; + margin-bottom: 1.5rem; + display: flex; + justify-content: space-between; + align-items: center; + box-shadow: 0 1px 3px var(--home-v2-shadow); + + .filter-tabs { + display: flex; + gap: 0.5rem; + + .filter-tab { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 1rem; + border: none; + background: transparent; + border-radius: 20px; + color: var(--home-v2-text-muted); + font-size: 0.9rem; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + + &:hover { + background: var(--home-v2-hover); + color: var(--home-v2-text); + } + + &.active { + background: var(--home-v2-primary); + color: white; + } + } + } + + .view-toggles { + display: flex; + gap: 0.25rem; + + .view-toggle { + padding: 0.5rem; + border: none; + background: transparent; + border-radius: 6px; + color: var(--home-v2-text-muted); + cursor: pointer; + transition: all 0.3s ease; + + &:hover { + background: var(--home-v2-hover); + color: var(--home-v2-text); + } + + &.active { + background: var(--home-v2-primary); + color: white; + } + } + } + } + + // Posts Feed + .posts-feed { + display: flex; + flex-direction: column; + gap: 2rem; + + .post-card { + background: var(--home-v2-card-bg); + border: 1px solid var(--home-v2-border); + border-radius: 16px; + overflow: hidden; + transition: all 0.3s ease; + box-shadow: 0 1px 3px var(--home-v2-shadow); + + &:hover { + box-shadow: 0 8px 25px var(--home-v2-shadow-hover); + transform: translateY(-2px); + } + + // Post Header + .post-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 1rem 1rem 0.75rem; + + .author-info { + display: flex; + align-items: center; + gap: 0.75rem; + + .author-avatar { + width: 40px; + height: 40px; + position: relative; + + img, .avatar-placeholder { + width: 100%; + height: 100%; + border-radius: 50%; + object-fit: cover; + } + + .avatar-placeholder { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + display: flex; + align-items: center; + justify-content: center; + color: white; + font-weight: 600; + font-size: 1rem; + } + } + + .author-details { + .author-name { + font-size: 0.9rem; + font-weight: 600; + color: var(--home-v2-text); + margin: 0 0 0.2rem 0; + } + + .post-meta { + font-size: 0.8rem; + color: var(--home-v2-text-muted); + display: flex; + align-items: center; + gap: 0.5rem; + + .category { + color: var(--home-v2-primary); + font-weight: 500; + } + } + } + } + + .featured-badge { + color: #ffd700; + padding: 0.5rem; + border-radius: 50%; + background: rgba(255, 215, 0, 0.1); + } + } + + // Post Content + .post-content { + padding: 0.75rem 1rem; + + .post-title { + margin: 0 0 0.75rem 0; + + a { + color: var(--home-v2-text); + text-decoration: none; + font-size: 1.25rem; + font-weight: 700; + line-height: 1.3; + transition: color 0.3s ease; + + &:hover { + color: var(--home-v2-primary); + } + } + } + + .post-excerpt { + color: var(--home-v2-text-muted); + font-size: 0.95rem; + line-height: 1.6; + margin: 0 0 1rem 0; + } + + .post-tags { + margin-bottom: 1rem; + + .tag { + color: var(--home-v2-primary); + text-decoration: none; + font-size: 0.85rem; + margin-right: 0.75rem; + font-weight: 500; + transition: opacity 0.3s ease; + + &:hover { + text-decoration: underline; + opacity: 0.8; + } + } + } + + .post-image { + margin: 1rem 0; + border-radius: 12px; + overflow: hidden; + + img { + width: 100%; + height: auto; + max-height: 400px; + object-fit: cover; + transition: transform 0.3s ease; + + &:hover { + transform: scale(1.02); + } + } + } + } + + // Post Actions + .post-actions { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 1rem 1rem; + border-top: 1px solid var(--home-v2-border); + margin-top: 1rem; + padding-top: 1rem; + + .action-buttons { + display: flex; + gap: 1rem; + + .action-btn { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.5rem 1rem; + border: 1px solid var(--home-v2-border); + background: var(--home-v2-card-bg); + color: var(--home-v2-text); + text-decoration: none; + border-radius: 8px; + font-size: 0.85rem; + font-weight: 500; + cursor: pointer; + transition: all 0.3s ease; + + &:hover { + background: var(--home-v2-primary); + color: white; + border-color: var(--home-v2-primary); + transform: translateY(-1px); + } + + svg { + width: 16px; + height: 16px; + } + } + + .share-dropdown { + position: relative; + + .share-menu { + position: absolute; + top: 100%; + right: 0; + background: var(--home-v2-card-bg); + border: 1px solid var(--home-v2-border); + border-radius: 8px; + padding: 0.5rem; + box-shadow: 0 4px 12px var(--home-v2-shadow-hover); + display: none; + min-width: 120px; + z-index: 10; + + .share-option { + display: block; + padding: 0.5rem; + color: var(--home-v2-text); + text-decoration: none; + border-radius: 4px; + font-size: 0.85rem; + border: none; + background: none; + cursor: pointer; + width: 100%; + text-align: left; + transition: background-color 0.3s ease; + + &:hover { + background: var(--home-v2-hover); + } + } + } + + &:hover .share-menu { + display: block; + } + } + } + + .post-meta-info { + display: flex; + gap: 1rem; + font-size: 0.8rem; + color: var(--home-v2-text-muted); + } + } + } + } + + // Load More Section + .load-more-container { + text-align: center; + margin: 2rem 0; + + .load-more-btn { + display: flex; + align-items: center; + gap: 0.5rem; + background: var(--home-v2-card-bg); + border: 1px solid var(--home-v2-border); + color: var(--home-v2-text); + padding: 1rem 2rem; + border-radius: 12px; + font-weight: 600; + cursor: pointer; + transition: all 0.3s ease; + margin: 0 auto; + + &:hover { + background: var(--home-v2-primary); + color: white; + border-color: var(--home-v2-primary); + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(59, 130, 246, 0.25); + } + } + } + + // Sidebar + .social-sidebar { + > div { + background: var(--home-v2-card-bg); + border: 1px solid var(--home-v2-border); + border-radius: 16px; + padding: 1.5rem; + margin-bottom: 1.5rem; + box-shadow: 0 1px 3px var(--home-v2-shadow); + } + + .widget-title { + font-size: 1rem; + font-weight: 700; + color: var(--home-v2-text); + margin: 0 0 1rem 0; + } + + // Profile Card + .profile-card { + text-align: center; + + .profile-avatar { + width: 80px; + height: 80px; + margin: 0 auto 1rem; + position: relative; + + img, .avatar-placeholder { + width: 100%; + height: 100%; + border-radius: 50%; + object-fit: cover; + } + + .avatar-placeholder { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + display: flex; + align-items: center; + justify-content: center; + color: white; + font-weight: 600; + font-size: 2rem; + } + } + + .profile-info { + margin-bottom: 1rem; + + .profile-name { + font-size: 1.1rem; + font-weight: 700; + color: var(--home-v2-text); + margin: 0 0 0.5rem 0; + } + + .profile-bio { + color: var(--home-v2-text-muted); + font-size: 0.9rem; + line-height: 1.4; + margin: 0; + } + } + + .profile-stats { + display: flex; + justify-content: space-around; + padding-top: 1rem; + border-top: 1px solid var(--home-v2-border); + + .stat { + text-align: center; + + .stat-number { + display: block; + font-size: 1.25rem; + font-weight: 700; + color: var(--home-v2-text); + } + + .stat-label { + font-size: 0.8rem; + color: var(--home-v2-text-muted); + text-transform: uppercase; + letter-spacing: 0.5px; + font-weight: 600; + } + } + } + } + + // Trending Widget + .trending-widget { + .trending-list { + .trending-item { + display: flex; + align-items: center; + gap: 1rem; + padding: 0.75rem 0; + border-bottom: 1px solid var(--home-v2-border); + text-decoration: none; + transition: all 0.3s ease; + + &:last-child { + border-bottom: none; + } + + &:hover { + background: var(--home-v2-hover); + margin: 0 -1.5rem; + padding: 0.75rem 1.5rem; + border-radius: 8px; + } + + .trending-number { + font-size: 1.1rem; + font-weight: 700; + color: var(--home-v2-primary); + min-width: 30px; + } + + .trending-name { + color: var(--home-v2-text); + font-weight: 600; + font-size: 0.9rem; + } + + .trending-count { + font-size: 0.8rem; + color: var(--home-v2-text-muted); + } + } + } + } + + // Categories Widget + .categories-widget { + .categories-grid { + display: grid; + grid-template-columns: 1fr; + gap: 0.5rem; + + .category-chip { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.75rem; + background: var(--home-v2-hover); + border-radius: 8px; + text-decoration: none; + transition: all 0.3s ease; + + &:hover { + background: var(--home-v2-primary); + + .category-name, .category-count { + color: white; + } + } + + .category-name { + color: var(--home-v2-text); + font-weight: 600; + font-size: 0.9rem; + } + + .category-count { + font-size: 0.8rem; + color: var(--home-v2-text-muted); + } + } + } + } + + // Quick Links Widget + .quick-links-widget { + .quick-links { + list-style: none; + padding: 0; + margin: 0; + + li { + a { + display: flex; + align-items: center; + gap: 0.75rem; + padding: 0.75rem 0; + text-decoration: none; + color: var(--home-v2-text); + font-weight: 500; + font-size: 0.9rem; + border-bottom: 1px solid var(--home-v2-border); + transition: all 0.3s ease; + + &:hover { + color: var(--home-v2-primary); + background: var(--home-v2-hover); + margin: 0 -1.5rem; + padding: 0.75rem 1.5rem; + border-radius: 8px; + } + } + + &:last-child a { + border-bottom: none; + } + } + } + } + } +} + +// Responsive Design +@media (max-width: 768px) { + .home-v2 { + .stories-section { + .stories-container { + padding: 0 0.5rem; + gap: 0.75rem; + + .story-item { + min-width: 70px; + + .story-avatar { + width: 56px; + height: 56px; + + .avatar-ring { + img, .story-placeholder { + width: 50px; + height: 50px; + } + } + } + + .story-label { + font-size: 0.7rem; + max-width: 70px; + } + } + } + } + + .feed-container { + padding: 0 0.5rem; + } + + .feed-controls { + flex-direction: column; + gap: 1rem; + align-items: stretch; + + .filter-tabs { + justify-content: center; + } + } + + .posts-feed { + .post-card { + .post-header { + padding: 0.75rem 0.75rem 0.5rem; + } + + .post-content { + padding: 0.5rem 0.75rem; + } + + .post-actions { + padding: 0.75rem; + flex-direction: column; + gap: 1rem; + align-items: stretch; + + .action-buttons { + justify-content: center; + flex-wrap: wrap; + } + + .post-meta-info { + justify-content: center; + } + } + } + } + } +} diff --git a/assets/css/extended.scss b/assets/css/extended.scss index ccb88c3..6da899d 100644 --- a/assets/css/extended.scss +++ b/assets/css/extended.scss @@ -11,6 +11,7 @@ @import "components/code"; @import "components/toc"; @import "components/homepage"; +@import "components/home-v2"; @import "components/pagination"; @import "components/related-posts"; @import "components/social-sharing"; diff --git a/assets/css/main.scss b/assets/css/main.scss index e31a7f6..a8332ae 100644 --- a/assets/css/main.scss +++ b/assets/css/main.scss @@ -17,3 +17,4 @@ @import "components/taxonomy-filter"; @import "components/footer"; @import "components/contact"; +@import "components/home-v2"; diff --git a/assets/js/home-v2.js b/assets/js/home-v2.js new file mode 100644 index 0000000..c2c3b1f --- /dev/null +++ b/assets/js/home-v2.js @@ -0,0 +1,326 @@ +// Social Media Inspired Homepage (home-v2) JavaScript +// Interactive features for social media-style engagement + +document.addEventListener('DOMContentLoaded', function() { + // Only run on home-v2 layout + if (!document.querySelector('.home-v2')) return; + + // Initialize all features + initStoriesNavigation(); + initPostFiltering(); + initViewToggle(); + initShareActions(); + initLoadMore(); + + // Stories Navigation + function initStoriesNavigation() { + const storyItems = document.querySelectorAll('.story-item'); + + storyItems.forEach(item => { + item.addEventListener('click', function() { + // Remove active class from all stories + storyItems.forEach(story => story.classList.remove('active')); + + // Add active class to clicked story + this.classList.add('active'); + + // Get category filter + const category = this.dataset.category; + + // Filter posts based on category + filterPostsByCategory(category); + + // Smooth scroll to posts section + const postsSection = document.querySelector('.posts-feed'); + if (postsSection) { + postsSection.scrollIntoView({ behavior: 'smooth' }); + } + }); + }); + } + + // Post Filtering + function initPostFiltering() { + const filterButtons = document.querySelectorAll('.filter-tab'); + const posts = document.querySelectorAll('.post-card'); + + filterButtons.forEach(button => { + button.addEventListener('click', function() { + const filter = this.dataset.filter; + + // Update active button + filterButtons.forEach(btn => btn.classList.remove('active')); + this.classList.add('active'); + + // Filter posts + posts.forEach(post => { + let shouldShow = true; + + switch(filter) { + case 'featured': + shouldShow = post.dataset.featured === 'true'; + break; + case 'recent': + // Show posts from last 7 days + const postTime = new Date(post.querySelector('time').getAttribute('datetime')).getTime(); + const weekAgo = Date.now() - (7 * 24 * 60 * 60 * 1000); + shouldShow = postTime > weekAgo; + break; + case 'all': + default: + shouldShow = true; + break; + } + + if (shouldShow) { + post.style.display = 'block'; + setTimeout(() => { + post.style.opacity = '1'; + post.style.transform = 'translateY(0)'; + }, 100); + } else { + post.style.opacity = '0'; + post.style.transform = 'translateY(20px)'; + setTimeout(() => { + post.style.display = 'none'; + }, 300); + } + }); + + // Add loading animation + const postsContainer = document.querySelector('.posts-feed'); + postsContainer.style.opacity = '0.7'; + setTimeout(() => { + postsContainer.style.opacity = '1'; + }, 300); + }); + }); + } + + // View Toggle (Feed/Grid) + function initViewToggle() { + const viewToggles = document.querySelectorAll('.view-toggle'); + const postsContainer = document.querySelector('.posts-feed'); + + viewToggles.forEach(toggle => { + toggle.addEventListener('click', function() { + const view = this.dataset.view; + + // Update active toggle + viewToggles.forEach(btn => btn.classList.remove('active')); + this.classList.add('active'); + + // Apply view style + if (view === 'grid') { + postsContainer.style.display = 'grid'; + postsContainer.style.gridTemplateColumns = 'repeat(auto-fit, minmax(350px, 1fr))'; + postsContainer.style.gap = '1.5rem'; + + // Adjust post cards for grid view + document.querySelectorAll('.post-card').forEach(card => { + card.style.marginBottom = '0'; + }); + } else { + postsContainer.style.display = 'flex'; + postsContainer.style.flexDirection = 'column'; + postsContainer.style.gap = '2rem'; + postsContainer.style.gridTemplateColumns = 'none'; + + // Reset post cards for feed view + document.querySelectorAll('.post-card').forEach(card => { + card.style.marginBottom = ''; + }); + } + }); + }); + } + + // Share Actions + function initShareActions() { + // Share dropdown functionality + const shareDropdowns = document.querySelectorAll('.share-dropdown'); + + shareDropdowns.forEach(dropdown => { + const shareBtn = dropdown.querySelector('.share-btn'); + const shareMenu = dropdown.querySelector('.share-menu'); + + shareBtn.addEventListener('click', function(e) { + e.preventDefault(); + e.stopPropagation(); + + // Close other dropdowns + shareDropdowns.forEach(other => { + if (other !== dropdown) { + other.querySelector('.share-menu').style.display = 'none'; + } + }); + + // Toggle current dropdown + const isVisible = shareMenu.style.display === 'block'; + shareMenu.style.display = isVisible ? 'none' : 'block'; + + // Animate share button + shareBtn.style.transform = 'scale(1.1) rotate(15deg)'; + setTimeout(() => { + shareBtn.style.transform = 'scale(1) rotate(0deg)'; + }, 200); + }); + }); + + // Copy link functionality + document.addEventListener('click', function(e) { + if (e.target.textContent === 'Copy Link') { + const post = e.target.closest('.post-card'); + const postUrl = post.querySelector('.post-title a').href; + + navigator.clipboard.writeText(postUrl).then(() => { + showNotification('Link copied to clipboard!'); + // Close the dropdown + e.target.closest('.share-menu').style.display = 'none'; + }); + } + }); + + // Close dropdowns when clicking outside + document.addEventListener('click', function(e) { + if (!e.target.closest('.share-dropdown')) { + document.querySelectorAll('.share-menu').forEach(menu => { + menu.style.display = 'none'; + }); + } + }); + } + + // Category filtering from stories + function filterPostsByCategory(category) { + const posts = document.querySelectorAll('.post-card'); + + posts.forEach(post => { + const postCategories = post.dataset.categories || ''; + const shouldShow = category === 'all' || postCategories.includes(category); + + if (shouldShow) { + post.style.display = 'block'; + setTimeout(() => { + post.style.opacity = '1'; + post.style.transform = 'translateY(0)'; + }, 100); + } else { + post.style.opacity = '0'; + post.style.transform = 'translateY(20px)'; + setTimeout(() => { + post.style.display = 'none'; + }, 300); + } + }); + + // Update filter tabs + const filterTabs = document.querySelectorAll('.filter-tab'); + filterTabs.forEach(tab => tab.classList.remove('active')); + document.querySelector('.filter-tab[data-filter="all"]').classList.add('active'); + } + + // Load More functionality + function initLoadMore() { + const loadMoreBtn = document.querySelector('.load-more-btn'); + const postsContainer = document.querySelector('.posts-feed'); + + if (!loadMoreBtn) return; + + loadMoreBtn.addEventListener('click', function() { + // Show loading state + const loadText = this.querySelector('.load-text'); + const loadIcon = this.querySelector('.load-icon'); + + loadText.textContent = 'Loading...'; + loadIcon.style.animation = 'spin 1s linear infinite'; + this.disabled = true; + + // Simulate loading more posts (in a real implementation, you'd fetch from server) + setTimeout(() => { + // Reset button + loadText.textContent = 'Load More Posts'; + loadIcon.style.animation = ''; + this.disabled = false; + + // In a real implementation, you would append new posts here + showNotification('All posts loaded!'); + }, 2000); + }); + } + + // Helper Functions + function showNotification(message) { + // Remove existing notification + const existing = document.querySelector('.home-v2-notification'); + if (existing) existing.remove(); + + const notification = document.createElement('div'); + notification.className = 'home-v2-notification'; + notification.textContent = message; + notification.style.cssText = ` + position: fixed; + top: 20px; + right: 20px; + background: var(--home-v2-primary); + color: white; + padding: 1rem 1.5rem; + border-radius: 12px; + z-index: 9999; + transform: translateX(400px); + transition: transform 0.3s ease; + box-shadow: 0 4px 12px var(--home-v2-shadow-hover); + font-weight: 500; + `; + + document.body.appendChild(notification); + + // Animate in + setTimeout(() => { + notification.style.transform = 'translateX(0)'; + }, 100); + + // Animate out + setTimeout(() => { + notification.style.transform = 'translateX(400px)'; + setTimeout(() => { + notification.remove(); + }, 300); + }, 3000); + } + + // Add animations and transitions + const style = document.createElement('style'); + style.textContent = ` + @keyframes spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } + } + + .post-card { + transition: opacity 0.3s ease, transform 0.3s ease; + } + + .story-item.active .avatar-ring { + background: linear-gradient(45deg, #f09433 0%, #e6683c 25%, #dc2743 50%, #cc2366 75%, #bc1888 100%) !important; + padding: 3px !important; + } + + .action-btn { + transition: all 0.2s ease; + } + + .action-btn:hover { + transform: translateY(-1px); + } + + .share-menu { + transition: opacity 0.2s ease, transform 0.2s ease; + } + + .load-icon { + transition: transform 0.3s ease; + } + `; + document.head.appendChild(style); +}); diff --git a/docs/home-v2-layout.md b/docs/home-v2-layout.md new file mode 100644 index 0000000..6f01475 --- /dev/null +++ b/docs/home-v2-layout.md @@ -0,0 +1,209 @@ +--- +title: "Home-v2 Layout: Social Media Inspired Design" +description: "Learn how to use the social media-inspired home-v2 layout for modern, engaging blog homepages" +--- + +# Home-v2 Layout: Social Media Inspired Design + +The `home-v2` layout provides a modern, social media-inspired alternative to the traditional blog homepage. This layout encourages visitors to explore content through Instagram-style stories, engaging post cards, and an elegant sidebar. + +## Features + +### 🎯 Instagram-Style Stories Navigation +- Category-based story navigation with gradient rings +- Smooth scrolling and filtering +- Visual feedback for active categories + +### 📱 Social Media-Style Post Cards +- Clean, card-based design with author avatars +- Reading time estimates and publication dates +- Featured post badges +- Interactive action buttons + +### 🔧 Interactive Controls +- Filter tabs: All Posts, Featured, Recent +- View toggles: Feed view vs Grid view +- Load more functionality + +### 📊 Engaging Sidebar +- Profile card with stats +- Trending topics +- Category exploration +- Quick navigation links + +### ⚡ Smart Actions +- Read Article (direct link to post) +- Comments (links to Giscus comment section) +- Share dropdown with social platforms and copy link + +## How to Use + +### 1. Enable the Layout + +Create a new page or modify an existing one to use the `home-v2` layout: + +```yaml +--- +layout: home-v2 +title: "Social Media Inspired Home" +description: "A modern homepage layout" +--- +``` + +### 2. Configure Site Settings + +Add author information to your `_config.yml`: + +```yaml +author: "Your Name" +author_avatar: "/assets/images/author.jpg" +description: "Your site description for the profile card" +``` + +### 3. Set Up Post Metadata + +For optimal display, configure your posts with: + +```yaml +--- +title: "Your Post Title" +author: "Author Name" +author_avatar: "/assets/images/author-avatar.jpg" +featured: true # For featured badge +categories: [Category1, Category2] +tags: [tag1, tag2, tag3] +image: "post-featured-image.jpg" +reading_time: 5 # minutes (optional, auto-calculated if not provided) +--- +``` + +### 4. Add Category Images (Optional) + +Place category-specific images in `/assets/images/categories/`: +- `tutorial.jpg` +- `features.jpg` +- `demo.jpg` +- etc. + +If images aren't available, the layout will show emoji placeholders. + +## Customization + +### CSS Variables + +The layout uses CSS custom properties for easy theming: + +```css +:root { + --home-v2-bg: #fafafa; + --home-v2-card-bg: #ffffff; + --home-v2-text: #1f2937; + --home-v2-text-muted: #6b7280; + --home-v2-border: #e2e8f0; + --home-v2-primary: #3b82f6; + --home-v2-accent: #8b5cf6; + /* ... more variables */ +} +``` + +### Dark Mode + +The layout automatically supports dark mode through media queries: + +```css +@media (prefers-color-scheme: dark) { + :root { + --home-v2-bg: #0f172a; + --home-v2-card-bg: #1e293b; + /* ... dark theme variables */ + } +} +``` + +### JavaScript Features + +The layout includes interactive JavaScript features: + +- **Stories Navigation**: Click story items to filter posts by category +- **Post Filtering**: Use filter tabs to show all, featured, or recent posts +- **View Toggle**: Switch between feed and grid layouts +- **Share Actions**: Native sharing or copy-to-clipboard fallback +- **Load More**: Pagination with smooth loading states + +## Responsive Design + +The layout is fully responsive: + +- **Desktop (1024px+)**: Full layout with sidebar +- **Tablet (768px-1024px)**: Hides sidebar, single column +- **Mobile (<768px)**: Optimized touch interactions, compact design + +## Best Practices + +### Content Strategy +1. Use featured posts to highlight important content +2. Organize content with clear categories +3. Write engaging excerpts (first paragraph or custom excerpt) +4. Add relevant tags for discoverability + +### Performance +1. Optimize images (WebP format recommended) +2. Use appropriate image sizes for different screen sizes +3. Lazy load images for posts beyond the fold + +### Accessibility +1. All interactive elements have proper ARIA labels +2. Keyboard navigation support +3. High contrast colors in both light and dark modes +4. Semantic HTML structure + +## Switching Between Layouts + +You can easily switch between the traditional `home` layout and the new `home-v2` layout: + +**Traditional Blog Layout (home.html)**: +```yaml +--- +layout: home +--- +``` + +**Social Media Inspired Layout (home-v2.html)**: +```yaml +--- +layout: home-v2 +--- +``` + +## Browser Support + +The home-v2 layout supports all modern browsers: +- Chrome 80+ +- Firefox 80+ +- Safari 13+ +- Edge 80+ + +Note: Some advanced features like native sharing may not be available on all browsers, with graceful fallbacks provided. + +## Troubleshooting + +### Stories Not Showing +- Ensure you have categories defined in your posts +- Check that category images exist or emoji fallbacks are working + +### JavaScript Not Working +- Verify that `home-v2.js` is properly loaded +- Check browser console for any JavaScript errors +- Ensure the layout class `.home-v2` is present + +### Styling Issues +- Check that `_home-v2.scss` is imported in your main stylesheet +- Verify CSS custom properties are supported in your target browsers +- Test dark mode separately + +## Examples + +Check out these examples of the home-v2 layout in action: +- [Demo Site](http://127.0.0.1:4000/home-v2.html) (when development server is running) + +For more advanced customization and troubleshooting, see the [Customization Guide](customization.md) and [Troubleshooting Guide](troubleshooting.md). diff --git a/docs/layouts.md b/docs/layouts.md index 51a691c..b4a72d9 100644 --- a/docs/layouts.md +++ b/docs/layouts.md @@ -30,6 +30,29 @@ title: Home --- ``` +### Home-v2 Layout (Social Media Inspired) +**New!** The home-v2 layout provides a modern, social media-inspired alternative to the traditional blog homepage. This layout encourages visitors to explore content through Instagram-style stories, engaging post cards, and an elegant sidebar. + +**Key Features:** +- Instagram-style category stories with gradient rings +- Social media-style post cards with author avatars +- Interactive filter tabs (All, Featured, Recent posts) +- Feed/Grid view toggle +- Engaging sidebar with profile card and trending topics +- Smart action buttons (Read, Comments, Share) +- Fully responsive design with dark mode support + +**Usage:** +```yaml +--- +layout: home-v2 +title: "Social Media Inspired Home" +description: "A modern homepage layout" +--- +``` + +**Learn More:** See the [Home-v2 Layout Guide](home-v2-layout.md) for detailed setup and customization instructions. + ### Post Layout This layout is optimized for blog posts. It includes features like reading time estimation, author information, social sharing buttons, and related posts. diff --git a/index.html b/index.html index bf0c84b..f11c6cf 100644 --- a/index.html +++ b/index.html @@ -1,3 +1,3 @@ --- -layout: home +layout: home-v2 --- \ No newline at end of file From efdd82e6d02dfd776977502a3f67aed2280a691e Mon Sep 17 00:00:00 2001 From: awcodify Date: Thu, 29 May 2025 20:40:32 +0700 Subject: [PATCH 02/30] feat: add social media inspired home-v2 layout and update README --- README.md | 1 + _layouts/default.html | 3 +++ assets/images/README-avatars.md | 7 +++++++ home-v2.md | 5 +++++ 4 files changed, 16 insertions(+) create mode 100644 assets/images/README-avatars.md create mode 100644 home-v2.md diff --git a/README.md b/README.md index 02d9f4b..7471774 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ A clean, modern Jekyll theme optimized for technical blogs and documentation sit - **Clean & Modern Design** - Minimal, distraction-free reading experience - **Responsive Layout** - Optimized for all devices from mobile to desktop - **Dark Mode Support** - Built-in dark mode toggle option with logo treatment options +- **Social Media Inspired Layout** - **New!** Modern home-v2 layout with Instagram-style stories and engaging post cards - **Comment System** - Support for Giscus (GitHub Discussions) comments - **Code Highlighting** - Beautiful syntax highlighting for technical content - **Table of Contents** - Automatically generated for longer articles diff --git a/_layouts/default.html b/_layouts/default.html index fe93be9..773cb9e 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -112,5 +112,8 @@ + {% if page.layout == 'home-v2' or layout.name == 'home-v2' %} + + {% endif %} \ No newline at end of file diff --git a/assets/images/README-avatars.md b/assets/images/README-avatars.md new file mode 100644 index 0000000..45a1590 --- /dev/null +++ b/assets/images/README-avatars.md @@ -0,0 +1,7 @@ +# This is a placeholder for a default avatar image +# In a real implementation, you would place actual image files here: +# - default-avatar.jpg +# - author.jpg +# - avatar.jpg + +# For now, the layout will use CSS placeholders with initials diff --git a/home-v2.md b/home-v2.md new file mode 100644 index 0000000..7fd84b0 --- /dev/null +++ b/home-v2.md @@ -0,0 +1,5 @@ +--- +layout: home-v2 +title: "Social Media Inspired Home" +description: "A modern, social media-inspired homepage layout for Jekyll blogs" +--- From 1b831ea2b5e57503766fca1cbf398c7e14016f20 Mon Sep 17 00:00:00 2001 From: awcodify Date: Thu, 29 May 2025 20:46:52 +0700 Subject: [PATCH 03/30] feat: enhance category display with default icon and recent post images --- _layouts/home-v2.html | 33 ++++++++++++++--------- assets/images/icons/default-category.svg | 34 ++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 12 deletions(-) create mode 100644 assets/images/icons/default-category.svg diff --git a/_layouts/home-v2.html b/_layouts/home-v2.html index b223da8..b8c8bd0 100644 --- a/_layouts/home-v2.html +++ b/_layouts/home-v2.html @@ -11,7 +11,11 @@
All Categories - +
@@ -19,21 +23,26 @@ {% assign categories_list = site.categories %} {% for category in categories_list limit:8 %} + {% comment %}Find the most recent post with an image in this category{% endcomment %} + {% assign category_posts = category[1] | where_exp: "post", "post.image" %} + {% assign latest_post = category_posts | first %} +
- {{ category[0] }} + {% if latest_post.image %} + {{ category[0] }} + {% else %} + {{ category[0] }} + {% endif %}
diff --git a/assets/images/icons/default-category.svg b/assets/images/icons/default-category.svg new file mode 100644 index 0000000..92e5933 --- /dev/null +++ b/assets/images/icons/default-category.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 09af908fbcdedef06555ed9863484eeeea2efe16 Mon Sep 17 00:00:00 2001 From: awcodify Date: Thu, 29 May 2025 21:01:07 +0700 Subject: [PATCH 04/30] feat: update home-v2 layout to display more posts and add new metadata files --- _layouts/home-v2.html | 2 +- index.html | 3 --- index.md | 3 +++ home-v2.md => v2.md | 0 4 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 index.html create mode 100644 index.md rename home-v2.md => v2.md (100%) diff --git a/_layouts/home-v2.html b/_layouts/home-v2.html index b8c8bd0..bb626f5 100644 --- a/_layouts/home-v2.html +++ b/_layouts/home-v2.html @@ -80,7 +80,7 @@
{% assign posts_to_show = paginator.posts | default: site.posts %} - {% for post in posts_to_show limit:10 %} + {% for post in posts_to_show limit:15 %}
Date: Thu, 29 May 2025 21:05:09 +0700 Subject: [PATCH 05/30] feat: remove 'Recent' filter option and update documentation accordingly --- _layouts/home-v2.html | 1 - assets/js/home-v2.js | 6 ------ docs/home-v2-layout.md | 4 ++-- docs/layouts.md | 2 +- 4 files changed, 3 insertions(+), 10 deletions(-) diff --git a/_layouts/home-v2.html b/_layouts/home-v2.html index bb626f5..6d73125 100644 --- a/_layouts/home-v2.html +++ b/_layouts/home-v2.html @@ -61,7 +61,6 @@
-
{% endif %} - - {% if post.image %} -
- - {{ post.title }} - -
- {% endif %}
diff --git a/_sass/components/_home-v2.scss b/_sass/components/_home-v2.scss index 37a4d41..723b474 100644 --- a/_sass/components/_home-v2.scss +++ b/_sass/components/_home-v2.scss @@ -233,6 +233,89 @@ html.dark-mode { flex-direction: column; gap: 2rem; + // Grid view styles + &.grid-view { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(350px, 1fr)); + gap: 1.5rem; + + .post-card { + margin-bottom: 0; + + .post-content { + .post-image { + margin: 1rem 0 0.75rem 0; + + img { + max-height: 200px; + } + } + + .post-excerpt { + font-size: 0.9rem; + line-height: 1.5; + } + + .post-tags { + margin-bottom: 0.75rem; + + .tag { + font-size: 0.8rem; + margin-right: 0.5rem; + } + } + } + + .post-actions { + padding: 0.75rem 1rem; + + .action-buttons { + display: flex; + flex-direction: row; + gap: 0.4rem; + justify-content: space-between; + + .action-btn { + font-size: 0.75rem; + padding: 0.4rem 0.6rem; + min-width: auto; + flex: 1; + justify-content: center; + + span { + display: none; + } + + svg { + width: 14px; + height: 14px; + margin: 0; + } + } + + .share-dropdown { + flex: 1; + + .action-btn { + width: 100%; + } + + .share-menu { + right: 0; + left: auto; + min-width: 100px; + } + } + } + + .post-meta-info { + font-size: 0.75rem; + gap: 0.5rem; + } + } + } + } + .post-card { background: var(--home-v2-card-bg); border: 1px solid var(--home-v2-border); @@ -359,7 +442,7 @@ html.dark-mode { } .post-image { - margin: 1rem 0; + margin: 1rem 0 0.75rem 0; border-radius: 12px; overflow: hidden; @@ -762,6 +845,37 @@ html.dark-mode { } .posts-feed { + &.grid-view { + grid-template-columns: 1fr; + gap: 1rem; + + .post-card { + .post-actions { + .action-buttons { + flex-direction: row; + justify-content: center; + flex-wrap: nowrap; + gap: 0.25rem; + + .action-btn { + flex: 1; + font-size: 0.7rem; + padding: 0.3rem 0.4rem; + + span { + display: none; + } + + svg { + width: 12px; + height: 12px; + } + } + } + } + } + } + .post-card { .post-header { padding: 0.75rem 0.75rem 0.5rem; diff --git a/assets/js/home-v2.js b/assets/js/home-v2.js index 499f1d0..73bd9e8 100644 --- a/assets/js/home-v2.js +++ b/assets/js/home-v2.js @@ -106,6 +106,7 @@ document.addEventListener('DOMContentLoaded', function() { // Apply view style if (view === 'grid') { + postsContainer.classList.add('grid-view'); postsContainer.style.display = 'grid'; postsContainer.style.gridTemplateColumns = 'repeat(auto-fit, minmax(350px, 1fr))'; postsContainer.style.gap = '1.5rem'; @@ -115,6 +116,7 @@ document.addEventListener('DOMContentLoaded', function() { card.style.marginBottom = '0'; }); } else { + postsContainer.classList.remove('grid-view'); postsContainer.style.display = 'flex'; postsContainer.style.flexDirection = 'column'; postsContainer.style.gap = '2rem'; From 15736583eeaa96b95fa862f5b43caa132e0d76fa Mon Sep 17 00:00:00 2001 From: awcodify Date: Thu, 29 May 2025 21:33:12 +0700 Subject: [PATCH 11/30] feat: update comment link to use consistent ID for comments wrapper --- _includes/giscus.html | 2 +- _layouts/home-v2.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_includes/giscus.html b/_includes/giscus.html index d9a5b12..1666c73 100644 --- a/_includes/giscus.html +++ b/_includes/giscus.html @@ -1,5 +1,5 @@ {% if site.giscus.enabled %} -
+

Comments