@@ -215,6 +215,14 @@ Always eager to learn new techniques, share knowledge with the community, and he
215215
216216 if ( ! dot || ! ring || ! trail ) return ;
217217
218+ // Disable cursor effects on mobile devices
219+ if ( window . innerWidth <= 768 || 'ontouchstart' in window ) {
220+ dot . style . display = 'none' ;
221+ ring . style . display = 'none' ;
222+ trail . style . display = 'none' ;
223+ return ;
224+ }
225+
218226 let mx = 0 , my = 0 , rx = 0 , ry = 0 , tx = 0 , ty = 0 ;
219227 let trailHistory = [ ] ;
220228
@@ -492,6 +500,8 @@ Always eager to learn new techniques, share knowledge with the community, and he
492500 // Enhanced Radar Chart
493501 const ctx = qs ( '#skills-chart' ) ;
494502 if ( ctx ) {
503+ const isMobile = window . innerWidth <= 768 ;
504+
495505 new Chart ( ctx , {
496506 type : 'radar' ,
497507 data : {
@@ -505,13 +515,21 @@ Always eager to learn new techniques, share knowledge with the community, and he
505515 pointBackgroundColor : '#ff0051' ,
506516 pointBorderColor : '#ffffff' ,
507517 borderWidth : 3 ,
508- pointRadius : 6 ,
509- pointHoverRadius : 8
518+ pointRadius : isMobile ? 4 : 6 ,
519+ pointHoverRadius : isMobile ? 6 : 8
510520 } ]
511521 } ,
512522 options : {
513523 responsive : true ,
514524 maintainAspectRatio : false ,
525+ layout : {
526+ padding : {
527+ top : 20 ,
528+ bottom : 20 ,
529+ left : 20 ,
530+ right : 20
531+ }
532+ } ,
515533 animation : {
516534 duration : 2000 ,
517535 easing : 'easeOutQuart'
@@ -535,7 +553,7 @@ Always eager to learn new techniques, share knowledge with the community, and he
535553 color : '#b3b3b3' ,
536554 font : {
537555 family : 'JetBrains Mono' ,
538- size : 11 ,
556+ size : isMobile ? 9 : 11 ,
539557 weight : '500'
540558 }
541559 } ,
@@ -1011,7 +1029,7 @@ Always eager to learn new techniques, share knowledge with the community, and he
10111029 const section = qs ( targetId ) ;
10121030
10131031 if ( section ) {
1014- const offset = 100 ;
1032+ const offset = window . innerWidth <= 768 ? 80 : 100 ; // Adjust offset for mobile
10151033 const targetPosition = section . offsetTop - offset ;
10161034
10171035 window . scrollTo ( {
@@ -1020,13 +1038,26 @@ Always eager to learn new techniques, share knowledge with the community, and he
10201038 } ) ;
10211039 }
10221040 } ) ;
1041+
1042+ // Add touch feedback for mobile
1043+ if ( 'ontouchstart' in window ) {
1044+ link . addEventListener ( 'touchstart' , ( ) => {
1045+ link . style . backgroundColor = 'rgba(0, 212, 255, 0.2)' ;
1046+ } ) ;
1047+
1048+ link . addEventListener ( 'touchend' , ( ) => {
1049+ setTimeout ( ( ) => {
1050+ link . style . backgroundColor = '' ;
1051+ } , 150 ) ;
1052+ } ) ;
1053+ }
10231054 } ) ;
10241055
10251056 // Active link highlighting
10261057 const sections = qsa ( 'section[id]' ) ;
10271058
10281059 function updateActiveLink ( ) {
1029- const scrollPos = window . scrollY + 150 ;
1060+ const scrollPos = window . scrollY + ( window . innerWidth <= 768 ? 120 : 150 ) ;
10301061 let current = '' ;
10311062
10321063 sections . forEach ( section => {
@@ -1093,18 +1124,101 @@ Always eager to learn new techniques, share knowledge with the community, and he
10931124
10941125 window . addEventListener ( 'load' , ( ) => {
10951126 const loadTime = ( performance . now ( ) - startTime ) . toFixed ( 1 ) ;
1127+ const isMobile = window . innerWidth <= 768 || 'ontouchstart' in window ;
1128+
10961129 console . log ( `⚡ Enhanced Portfolio loaded in ${ loadTime } ms` ) ;
1097- console . log ( '🎨 Rich animations and multi-column layouts active' ) ;
1098- console . log ( '🖱️ Enhanced cursor with trailing effects enabled' ) ;
1130+ console . log ( `🎨 Rich animations and multi-column layouts active` ) ;
1131+ console . log ( `📱 Mobile optimized: ${ isMobile ? 'YES' : 'NO' } ` ) ;
1132+
1133+ if ( ! isMobile ) {
1134+ console . log ( '🖱️ Enhanced cursor with trailing effects enabled' ) ;
1135+ } else {
1136+ console . log ( '👆 Touch-optimized interface enabled' ) ;
1137+ }
10991138 } ) ;
11001139 }
11011140
1141+ /*****************************************
1142+ * MOBILE NAVIGATION DROPDOWN
1143+ *****************************************/
1144+ function initMobileNavigation ( ) {
1145+ const dropdownToggle = qs ( '.nav-dropdown-toggle' ) ;
1146+ const dropdownMenu = qs ( '.nav-dropdown-menu' ) ;
1147+ const navLinks = qsa ( '.nav-dropdown-menu .nav__link' ) ;
1148+
1149+ if ( ! dropdownToggle || ! dropdownMenu ) return ;
1150+
1151+ // Toggle dropdown
1152+ dropdownToggle . addEventListener ( 'click' , ( e ) => {
1153+ e . stopPropagation ( ) ;
1154+ const isExpanded = dropdownToggle . getAttribute ( 'aria-expanded' ) === 'true' ;
1155+
1156+ dropdownToggle . setAttribute ( 'aria-expanded' , ! isExpanded ) ;
1157+ dropdownMenu . classList . toggle ( 'active' ) ;
1158+ } ) ;
1159+
1160+ // Close dropdown when clicking outside
1161+ document . addEventListener ( 'click' , ( e ) => {
1162+ if ( ! dropdownToggle . contains ( e . target ) && ! dropdownMenu . contains ( e . target ) ) {
1163+ dropdownToggle . setAttribute ( 'aria-expanded' , 'false' ) ;
1164+ dropdownMenu . classList . remove ( 'active' ) ;
1165+ }
1166+ } ) ;
1167+
1168+ // Close dropdown when navigation link is clicked
1169+ navLinks . forEach ( link => {
1170+ link . addEventListener ( 'click' , ( ) => {
1171+ dropdownToggle . setAttribute ( 'aria-expanded' , 'false' ) ;
1172+ dropdownMenu . classList . remove ( 'active' ) ;
1173+ } ) ;
1174+ } ) ;
1175+
1176+ // Handle keyboard navigation
1177+ dropdownToggle . addEventListener ( 'keydown' , ( e ) => {
1178+ if ( e . key === 'Enter' || e . key === ' ' ) {
1179+ e . preventDefault ( ) ;
1180+ dropdownToggle . click ( ) ;
1181+ }
1182+ } ) ;
1183+ }
1184+
1185+ /*****************************************
1186+ * MOBILE VIEWPORT HANDLING
1187+ *****************************************/
1188+ function initMobileViewportHandling ( ) {
1189+ // Handle mobile viewport height changes (iOS Safari)
1190+ function setViewportHeight ( ) {
1191+ const vh = window . innerHeight * 0.01 ;
1192+ document . documentElement . style . setProperty ( '--vh' , `${ vh } px` ) ;
1193+ }
1194+
1195+ setViewportHeight ( ) ;
1196+ window . addEventListener ( 'resize' , setViewportHeight ) ;
1197+ window . addEventListener ( 'orientationchange' , ( ) => {
1198+ setTimeout ( setViewportHeight , 100 ) ;
1199+ } ) ;
1200+
1201+ // Prevent zoom on double tap for better mobile experience
1202+ let lastTouchEnd = 0 ;
1203+ document . addEventListener ( 'touchend' , ( event ) => {
1204+ const now = ( new Date ( ) ) . getTime ( ) ;
1205+ if ( now - lastTouchEnd <= 300 ) {
1206+ event . preventDefault ( ) ;
1207+ }
1208+ lastTouchEnd = now ;
1209+ } , false ) ;
1210+ }
1211+
11021212 /*****************************************
11031213 * INITIALIZATION SEQUENCE
11041214 *****************************************/
11051215 function init ( ) {
11061216 console . log ( '🚀 Initializing Enhanced Cybersecurity Portfolio...' ) ;
11071217
1218+ // Mobile optimizations first
1219+ initMobileViewportHandling ( ) ;
1220+ initMobileNavigation ( ) ;
1221+
11081222 // Core functionality
11091223 initEnhancedCursor ( ) ;
11101224 initEnhancedTyping ( ) ;
0 commit comments