@@ -89,14 +89,104 @@ <h1>Mit Patel's Blog</h1>
8989 < div class ="container ">
9090 < main >
9191 < section >
92- < h2 class ="section-heading ">
93- < span style ="display: inline-flex; align-items: baseline; gap: 0.5rem; ">
94- Recent Posts
95- < span
96- style ="font-size: 0.65em; font-weight: 500; opacity: 0.6; text-transform: uppercase; font-style: italic; letter-spacing: 0.5px; "> Total
97- Posts: 12</ span >
98- </ span >
99- </ h2 >
92+ < div class ="blog-heading-row ">
93+ < h2 class ="section-heading ">
94+ < span style ="display: inline-flex; align-items: baseline; gap: 0.5rem; ">
95+ Recent Posts
96+ < span
97+ style ="font-size: 0.65em; font-weight: 500; opacity: 0.6; text-transform: uppercase; font-style: italic; letter-spacing: 0.5px; "> Total
98+ Posts: 12</ span >
99+ </ span >
100+ </ h2 >
101+ <!-- Mobile filter toggle button (hidden on desktop) -->
102+ < button id ="mobile-filter-toggle " class ="mobile-filter-toggle "
103+ aria-label ="Filter by technology ">
104+ < i class ="fas fa-filter "> </ i >
105+ < span class ="mobile-filter-label "> Filter</ span >
106+ </ button >
107+ </ div >
108+
109+ <!-- Mobile filter dropdown (hidden by default, shown on toggle) -->
110+ < div id ="mobile-filter-panel " class ="mobile-filter-panel ">
111+ < div id ="mobile-tag-filter-container " class ="mobile-tag-container ">
112+ < button class ="tag filter-tag active " data-tag ="all "> Show All</ button >
113+
114+ < button class ="tag filter-tag " data-tag ="aws "> AWS</ button >
115+
116+ < button class ="tag filter-tag " data-tag ="aws ec2 "> AWS EC2</ button >
117+
118+ < button class ="tag filter-tag " data-tag ="aws ecr "> AWS ECR</ button >
119+
120+ < button class ="tag filter-tag " data-tag ="aws elastic beanstalk "> AWS Elastic Beanstalk</ button >
121+
122+ < button class ="tag filter-tag " data-tag ="aws s3 "> AWS S3</ button >
123+
124+ < button class ="tag filter-tag " data-tag ="aws sagemaker "> AWS SageMaker</ button >
125+
126+ < button class ="tag filter-tag " data-tag ="agentic ai "> Agentic AI</ button >
127+
128+ < button class ="tag filter-tag " data-tag ="agno "> Agno</ button >
129+
130+ < button class ="tag filter-tag " data-tag ="cloudwatch "> CloudWatch</ button >
131+
132+ < button class ="tag filter-tag " data-tag ="dagshub "> Dagshub</ button >
133+
134+ < button class ="tag filter-tag " data-tag ="docker "> Docker</ button >
135+
136+ < button class ="tag filter-tag " data-tag ="duckduckgo api "> DuckDuckGo API</ button >
137+
138+ < button class ="tag filter-tag " data-tag ="duckduckgotools "> DuckDuckGoTools</ button >
139+
140+ < button class ="tag filter-tag " data-tag ="fastapi "> FastAPI</ button >
141+
142+ < button class ="tag filter-tag " data-tag ="flask "> Flask</ button >
143+
144+ < button class ="tag filter-tag " data-tag ="github actions "> GitHub Actions</ button >
145+
146+ < button class ="tag filter-tag " data-tag ="google api "> Google API</ button >
147+
148+ < button class ="tag filter-tag " data-tag ="google gemini "> Google Gemini</ button >
149+
150+ < button class ="tag filter-tag " data-tag ="groq "> Groq</ button >
151+
152+ < button class ="tag filter-tag " data-tag ="huggingface transformers "> HuggingFace Transformers</ button >
153+
154+ < button class ="tag filter-tag " data-tag ="mlops "> MLOps</ button >
155+
156+ < button class ="tag filter-tag " data-tag ="mlflow "> MLflow</ button >
157+
158+ < button class ="tag filter-tag " data-tag ="mongodb "> MongoDB</ button >
159+
160+ < button class ="tag filter-tag " data-tag ="multi-agent systems "> Multi-Agent Systems</ button >
161+
162+ < button class ="tag filter-tag " data-tag ="nlp "> NLP</ button >
163+
164+ < button class ="tag filter-tag " data-tag ="numpy "> NumPy</ button >
165+
166+ < button class ="tag filter-tag " data-tag ="pandas "> Pandas</ button >
167+
168+ < button class ="tag filter-tag " data-tag ="pytorch "> PyTorch</ button >
169+
170+ < button class ="tag filter-tag " data-tag ="python "> Python</ button >
171+
172+ < button class ="tag filter-tag " data-tag ="scikit-learn "> Scikit-learn</ button >
173+
174+ < button class ="tag filter-tag " data-tag ="streamlit "> Streamlit</ button >
175+
176+ < button class ="tag filter-tag " data-tag ="tensorboard "> TensorBoard</ button >
177+
178+ < button class ="tag filter-tag " data-tag ="weights & biases "> Weights & Biases</ button >
179+
180+ < button class ="tag filter-tag " data-tag ="yfinancetools "> YFinanceTools</ button >
181+
182+ < button class ="tag filter-tag " data-tag ="google-generativeai "> google-generativeai</ button >
183+
184+ < button class ="tag filter-tag " data-tag ="python-dotenv "> python-dotenv</ button >
185+
186+ < button class ="tag filter-tag " data-tag ="torchvision "> torchvision</ button >
187+
188+ </ div >
189+ </ div >
100190
101191 <!-- blogs -->
102192 < div id ="blog-posts-container ">
@@ -397,8 +487,11 @@ <h2 class="section-heading">Filter by Technology</h2>
397487 < script >
398488 document . addEventListener ( 'DOMContentLoaded' , function ( ) {
399489 const tagContainer = document . getElementById ( 'tag-filter-container' ) ;
490+ const mobileTagContainer = document . getElementById ( 'mobile-tag-filter-container' ) ;
400491 const blogPosts = Array . from ( document . querySelectorAll ( '.blog-post' ) ) ;
401492 const loadMoreBtn = document . getElementById ( 'load-more-btn' ) ;
493+ const mobileFilterToggle = document . getElementById ( 'mobile-filter-toggle' ) ;
494+ const mobileFilterPanel = document . getElementById ( 'mobile-filter-panel' ) ;
402495
403496 let currentMax = 5 ;
404497 const POSTS_PER_PAGE = 5 ;
@@ -432,20 +525,51 @@ <h2 class="section-heading">Filter by Technology</h2>
432525 }
433526 }
434527
528+ // Sync active state across both filter containers
529+ function syncFilterState ( clickedTag , sourceContainer ) {
530+ const allContainers = [ tagContainer , mobileTagContainer ] . filter ( Boolean ) ;
531+ const selectedTag = clickedTag . getAttribute ( 'data-tag' ) . toLowerCase ( ) ;
532+
533+ allContainers . forEach ( container => {
534+ container . querySelectorAll ( '.filter-tag' ) . forEach ( btn => {
535+ btn . classList . remove ( 'active' ) ;
536+ if ( btn . getAttribute ( 'data-tag' ) . toLowerCase ( ) === selectedTag ) {
537+ btn . classList . add ( 'active' ) ;
538+ }
539+ } ) ;
540+ } ) ;
541+
542+ currentFilter = selectedTag ;
543+ currentMax = POSTS_PER_PAGE ;
544+ updatePostsDisplay ( ) ;
545+ }
546+
547+ // Desktop sidebar filter
435548 if ( tagContainer ) {
436549 tagContainer . addEventListener ( 'click' , function ( e ) {
437550 if ( e . target . matches ( '.filter-tag' ) ) {
438- // Update the active button style
439- tagContainer . querySelectorAll ( '.filter-tag' ) . forEach ( btn => btn . classList . remove ( 'active' ) ) ;
440- e . target . classList . add ( 'active' ) ;
551+ syncFilterState ( e . target , tagContainer ) ;
552+ }
553+ } ) ;
554+ }
441555
442- currentFilter = e . target . getAttribute ( 'data-tag' ) . toLowerCase ( ) ;
443- currentMax = POSTS_PER_PAGE ; // Reset max matches when filter changes
444- updatePostsDisplay ( ) ;
556+ // Mobile filter dropdown
557+ if ( mobileTagContainer ) {
558+ mobileTagContainer . addEventListener ( 'click' , function ( e ) {
559+ if ( e . target . matches ( '.filter-tag' ) ) {
560+ syncFilterState ( e . target , mobileTagContainer ) ;
445561 }
446562 } ) ;
447563 }
448564
565+ // Mobile filter toggle button
566+ if ( mobileFilterToggle && mobileFilterPanel ) {
567+ mobileFilterToggle . addEventListener ( 'click' , function ( ) {
568+ const isOpen = mobileFilterPanel . classList . toggle ( 'open' ) ;
569+ mobileFilterToggle . classList . toggle ( 'active' , isOpen ) ;
570+ } ) ;
571+ }
572+
449573 if ( loadMoreBtn ) {
450574 loadMoreBtn . addEventListener ( 'click' , function ( ) {
451575 currentMax += POSTS_PER_PAGE ;
@@ -458,7 +582,7 @@ <h2 class="section-heading">Filter by Technology</h2>
458582 } ) ;
459583 </ script >
460584 < style >
461- /* Add some basic styling for the active button */
585+ /* ===== Filter Tag Base Styles ===== */
462586 .filter-tag {
463587 cursor : pointer;
464588 border : 1px solid transparent;
@@ -467,27 +591,20 @@ <h2 class="section-heading">Filter by Technology</h2>
467591 .filter-tag .active {
468592 border-color : var (--link-color , # 0077cc );
469593 background-color : # cceeff ;
470- /* A light blue to indicate selection */
471594 color : # 000 ;
472595 }
473596
474- /* Add these new rules to the <style> block at the bottom */
475-
476- /* Target the container to stack the buttons vertically */
597+ /* Desktop sidebar filter layout */
477598 # tag-filter-container {
478599 display : flex;
479600 flex-direction : column;
480- /* This is the key change */
481601 gap : 0.5rem ;
482- /* Adds space between the stacked buttons */
483602 }
484603
485- /* Make the buttons full-width and aligned left */
486604 # tag-filter-container .filter-tag {
487605 width : 100% ;
488606 text-align : left;
489607 margin-right : 0 ;
490- /* Remove the old horizontal margin */
491608 }
492609
493610 /* Load more button styles */
@@ -507,6 +624,109 @@ <h2 class="section-heading">Filter by Technology</h2>
507624 background-color : var (--link-color , # 0077cc );
508625 color : # fff ;
509626 }
627+
628+ /* ===== Blog Heading Row ===== */
629+ .blog-heading-row {
630+ display : flex;
631+ align-items : center;
632+ justify-content : space-between;
633+ gap : 1rem ;
634+ }
635+
636+ .blog-heading-row .section-heading {
637+ flex : 1 ;
638+ margin-bottom : 0 ;
639+ }
640+
641+ /* ===== Mobile Filter Toggle Button ===== */
642+ .mobile-filter-toggle {
643+ display : none;
644+ /* Hidden by default on desktop */
645+ }
646+
647+ /* ===== Mobile Filter Panel ===== */
648+ .mobile-filter-panel {
649+ display : none;
650+ /* Hidden by default */
651+ }
652+
653+ /* ===== Mobile / Tablet: show filter button, hide sidebar ===== */
654+ @media (max-width : 48rem ) {
655+
656+ /* Hide the desktop sidebar completely on mobile */
657+ aside {
658+ display : none !important ;
659+ }
660+
661+ /* Show the mobile filter toggle button */
662+ .mobile-filter-toggle {
663+ display : inline-flex;
664+ align-items : center;
665+ gap : 0.4rem ;
666+ padding : 8px 14px ;
667+ border : 1px solid var (--border-color );
668+ border-radius : 6px ;
669+ background-color : var (--card-bg-color );
670+ color : var (--text-color );
671+ font-size : 0.9rem ;
672+ font-weight : 600 ;
673+ cursor : pointer;
674+ transition : all 0.2s ease;
675+ flex-shrink : 0 ;
676+ font-family : inherit;
677+ }
678+
679+ .mobile-filter-toggle i {
680+ font-size : 0.85rem ;
681+ color : var (--link-color );
682+ }
683+
684+ .mobile-filter-toggle : hover ,
685+ .mobile-filter-toggle .active {
686+ border-color : var (--link-color );
687+ color : var (--link-color );
688+ }
689+
690+ /* Mobile filter panel (dropdown) */
691+ .mobile-filter-panel {
692+ display : none;
693+ /* Still hidden until .open is added */
694+ }
695+
696+ .mobile-filter-panel .open {
697+ display : block;
698+ margin-bottom : 1.5rem ;
699+ padding : 1rem ;
700+ background-color : var (--card-bg-color );
701+ border : 1px solid var (--border-color );
702+ border-radius : 8px ;
703+ animation : filterSlideDown 0.25s ease-out;
704+ }
705+
706+ @keyframes filterSlideDown {
707+ from {
708+ opacity : 0 ;
709+ transform : translateY (-8px );
710+ }
711+
712+ to {
713+ opacity : 1 ;
714+ transform : translateY (0 );
715+ }
716+ }
717+
718+ /* Mobile tag container: horizontal wrap layout */
719+ .mobile-tag-container {
720+ display : flex;
721+ flex-wrap : wrap;
722+ gap : 0.5rem ;
723+ }
724+
725+ .mobile-tag-container .filter-tag {
726+ font-size : 0.85rem ;
727+ padding : 4px 10px ;
728+ }
729+ }
510730 </ style >
511731
512732 </ footer >
0 commit comments