44< head >
55 < meta charset ="UTF-8 " />
66 < meta name ="viewport " content ="width=device-width, initial-scale=1.0 " />
7- <!-- TIÊU ĐỀ MỚI -->
8- < title > Trần Hữu Đạt - Full-stack Web Developer</ title >
9- <!-- THAY ICON MỚI (NẾU CÓ) -->
7+ < title > Trần Hữu Đạt - Happy Birthday!</ title >
108 < link rel ="icon " type ="image/png " href ="assets/favicon.png " />
119
12- <!-- THÊM FONT MỚI TỪ GOOGLE FONTS -->
1310 < link rel ="preconnect " href ="https://fonts.googleapis.com ">
1411 < link rel ="preconnect " href ="https://fonts.gstatic.com " crossorigin >
1512 < link href ="https://fonts.googleapis.com/css2?family=Sora:wght@400;500;600;700;800&display=swap " rel ="stylesheet ">
1613
17- <!-- LINK CSS VÀ FONT AWESOME -->
18- < link rel ="stylesheet " href ="css/components/base.css " />
14+ < link rel ="stylesheet " href ="css/components/base.css " />
1915 < link rel ="stylesheet " href ="css/components/header.css " />
2016 < link rel ="stylesheet " href ="css/components/hero.css " />
2117 < link rel ="stylesheet " href ="css/components/music-player.css " />
3531 < link rel ="stylesheet " href ="css/components/theme.css " />
3632 < link rel ="stylesheet " href ="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css ">
3733 < style >
38- .theme-switcher-dropdown {
39- position : relative;
40- display : inline-block;
41- margin-left : 1rem ;
34+ .party-container {
35+ position : fixed;
36+ top : 0 ;
37+ left : 0 ;
38+ width : 100% ;
39+ height : 100% ;
40+ pointer-events : none;
41+ z-index : 9999 ;
4242 }
43-
44- .dropdown-toggle {
45- background : rgba (255 , 255 , 255 , 0.1 );
46- border : 1px solid var (--border-color );
47- color : var (--text-primary );
48- padding : 0.5rem 1rem ;
49- border-radius : 9999px ;
50- cursor : pointer;
51- font-size : 0.875rem ;
52- font-weight : 600 ;
53- transition : background-color 0.3s , border-color 0.3s ;
54- display : flex;
55- align-items : center;
56- gap : 0.5rem ;
57- }
58-
59- .dropdown-toggle : hover {
60- background-color : rgba (255 , 255 , 255 , 0.15 );
61- }
62-
63- .dropdown-menu {
64- display : none;
43+ .confetti {
6544 position : absolute;
66- background-color : var (--bg-card );
67- min-width : 160px ;
68- box-shadow : 0px 8px 16px 0px rgba (0 , 0 , 0 , 0.2 );
69- z-index : 1 ;
70- border-radius : 0.5rem ;
71- border : 1px solid var (--border-color );
72- padding : 0.5rem 0 ;
73- right : 0 ;
74- top : 100% ;
75- margin-top : 0.5rem ;
45+ top : -20px ;
46+ animation : confetti-fall 5s linear infinite;
7647 }
77-
78- .dropdown-menu a {
79- color : var (--text-primary );
80- padding : 0.75rem 1rem ;
81- text-decoration : none;
82- display : block;
83- text-align : left;
84- transition : background-color 0.2s ;
85- }
86-
87- .dropdown-menu a : hover {
88- background-color : rgba (255 , 255 , 255 , 0.05 );
89- }
90-
91- .dropdown-menu .show {
92- display : block;
48+ .confetti .confetti-square { width : 10px ; height : 10px ; }
49+ .confetti .confetti-rectangle { width : 15px ; height : 8px ; }
50+ .confetti .confetti-circle { width : 12px ; height : 12px ; border-radius : 50% ; }
51+ @keyframes confetti-fall {
52+ 0% { transform : translateY (0 ) rotateZ (0 ) rotateY (0 ); opacity : 1 ; }
53+ 100% { transform : translateY (105vh ) rotateZ (720deg ) rotateY (360deg ); opacity : 0 ; }
9354 }
9455 </ style >
9556</ head >
9657
97- < body >
98- <!-- Thanh tiến trình cuộn giữ nguyên -- >
58+ < body class =" birthday-theme " >
59+ < div class =" party-container " > </ div >
9960 < div class ="scroll-progress-bar "> </ div >
10061
10162 < header class ="main-header ">
102- <!-- Nhóm 1: Logo -->
10363 < a class ="logo " href ="index.html "> < span > tranhuudat</ span > 2004</ a >
104-
105- <!-- Nhóm 2: Khối điều hướng -->
106- < div class ="header-navigation "> <!-- THÊM THẺ NÀY -->
64+ < div class ="header-navigation ">
10765 < nav class ="main-nav ">
10866 < a href ="#hero "> Home</ a >
10967 < a href ="#about "> About</ a >
11068 < a href ="#skills "> Skills</ a >
111- <!-- <a href="#coding-activity">Activity</a> -->
11269 < a href ="#projects "> Projects</ a >
11370 < a href ="#experience "> Experience</ a >
114- < a href ="#blog "> Blog</ a > <!-- << THÊM DÒNG NÀY VÀO -->
71+ < a href ="#blog "> Blog</ a >
11572 < a href ="#contact "> Contact</ a >
11673 < span class ="nav-indicator "> </ span >
11774 </ nav >
11875 < a href ="download-resume.html " class ="resume-button "> Resume</ a >
119-
12076 < button id ="theme-toggle " class ="theme-toggle-btn ">
12177 < i class ="fas fa-sun "> </ i >
12278 < i class ="fas fa-moon "> </ i >
12379 </ button >
124-
125- < div class ="theme-switcher-dropdown ">
126- < button class ="dropdown-toggle "> Themes < i class ="fas fa-chevron-down "> </ i > </ button >
127- < div class ="dropdown-menu ">
128- < a href ="index.html "> Default</ a >
129- < a href ="birthday.html "> Birthday</ a >
130- < a href ="noel.html "> Noel</ a >
131- < a href ="halloween.html "> Halloween</ a >
132- < a href ="tet.html "> Tết</ a >
133- </ div >
134- </ div >
135-
136- </ div > <!-- THÊM THẺ NÀY -->
137-
80+ </ div >
13881 </ header >
13982
14083 < main >
141- <!-- ====================================================== -->
142- <!-- Section 1: Hero (THAY ĐỔI LỚN) -->
143- <!-- ====================================================== -->
14484 < section id ="hero " class ="hero-section ">
14585 < div class ="hero-background "> </ div >
14686 < div class ="container hero-container ">
147- <!-- Profile Card (bên trái) -->
14887 < div class ="profile-card-container animate-on-scroll ">
14988 < div class ="profile-card glass-card ">
15089 < div class ="profile-header ">
@@ -159,63 +98,43 @@ <h2>Trần Hữu Đạt</h2>
15998 </ div >
16099 < div class ="profile-details ">
161100 < p > < i class ="fas fa-map-marker-alt "> </ i > Ho Chi Minh City, Vietnam</ p >
162- < p > < i class ="fas fa-calendar-alt "> </ i > Joined 2022 </ p >
101+ < p > < i class ="fas fa-birthday-cake "> </ i > < span id =" age " > </ span > years old </ p >
163102 < p > < i class ="fas fa-briefcase "> </ i > Ton Duc Thang University</ p >
164103 </ div >
165-
166104 </ div >
167105 </ div >
168-
169- <!-- Hero Text Content (ở giữa) -->
170106 < div class ="hero-text-content ">
171- < div class ="welcome-badge animate-on-scroll "> Welcome to my Portfolio </ div >
107+ < div class ="welcome-badge animate-on-scroll "> HAPPY BIRTHDAY TO ME! </ div >
172108 < h1 class ="animate-on-scroll ">
173- Building Digital < br >
174- < span class ="gradient-text "> Experiences </ span >
109+ Have a < br >
110+ < span class ="gradient-text "> wonderful birthday! </ span >
175111 </ h1 >
176- < p style ="color: white; " class ="animate-on-scroll "> A passionate Software Engineering student
177- specializing in creating
178- efficient, user-centric web applications.</ p >
179- < div class ="hero-buttons animate-on-scroll ">
180- < a href ="#projects " class ="btn btn-primary "> View my projects < i
181- class ="fas fa-arrow-right "> </ i > </ a >
182- < a href ="#contact " class ="btn btn-secondary "> Get in touch</ a >
183- </ div >
112+ < p style ="color: white; " class ="animate-on-scroll "> Thank you for being a part of my journey. Let's celebrate!</ p >
184113 < div class ="social-links animate-on-scroll ">
185- < a style ="color: white; " href ="https://linkedin.com/in/tranhuudat2004 " aria-label ="LinkedIn "> < i
186- class ="fab fa-linkedin-in "> </ i > </ a >
187- < a style ="color: white; " href ="https://github.com/TranHuuDat2004 " aria-label ="GitHub "> < i
188- class ="fab fa-github "> </ i > </ a >
189- < a style ="color: white; " href ="mailto:tranhuudat.cv@gmail.com " aria-label ="Email "> < i
190- class ="fas fa-envelope "> </ i > </ a >
114+ < a style ="color: white; " href ="https://linkedin.com/in/tranhuudat2004 " aria-label ="LinkedIn "> < i class ="fab fa-linkedin-in "> </ i > </ a >
115+ < a style ="color: white; " href ="https://github.com/TranHuuDat2004 " aria-label ="GitHub "> < i class ="fab fa-github "> </ i > </ a >
116+ < a style ="color: white; " href ="mailto:tranhuudat.cv@gmail.com " aria-label ="Email "> < i class ="fas fa-envelope "> </ i > </ a >
191117 < a style ="color: white; " href ="# " aria-label ="Twitter "> < i class ="fab fa-twitter "> </ i > </ a >
192118 </ div >
193119 </ div >
194120 </ div >
195121 < div class ="scroll-down-indicator "> </ div >
196122 </ section >
197123
198- <!-- ====================================================== -->
199- <!-- Music Player Widget -->
200- <!-- ====================================================== -->
201124 < div class ="music-player-widget ">
202125 < img src ="assets/song-cover.png " alt ="Song Cover " class ="song-cover " id ="song-cover ">
203126 < div class ="song-info ">
204- < h4 id ="song-title "> Điều chưa nói </ h4 >
205- < p id ="song-artist "> Tia ft. OMIXX </ p >
127+ < h4 id ="song-title "> Happy Birthday </ h4 >
128+ < p id ="song-artist "> Birthday Song </ p >
206129 </ div >
207130 < div class ="player-controls ">
208- <!-- Thêm ID cho các nút -->
209131 < i class ="fas fa-backward-step " id ="prev-btn "> </ i >
210- < i class ="fas fa-pause " id ="play-pause-btn "> </ i > <!-- Bắt đầu với icon pause -- >
132+ < i class ="fas fa-play " id ="play-pause-btn "> </ i >
211133 < i class ="fas fa-forward-step " id ="next-btn "> </ i >
212134 </ div >
213- < i class ="fas fa-volume-high "> </ i > <!-- Phần volume sẽ làm sau nếu bạn muốn -->
135+ < i class ="fas fa-volume-high "> </ i >
214136 </ div >
215137
216- <!-- ====================================================== -->
217- <!-- Section 2: About Me (CẬP NHẬT) -->
218- <!-- ====================================================== -->
219138 < section id ="about " class ="content-section ">
220139 < div class ="container ">
221140 < div class ="section-header animate-on-scroll ">
@@ -226,47 +145,26 @@ <h2 class="section-title">About Me</h2>
226145 < div class ="about-grid ">
227146 < div class ="about-image-wrapper animate-on-scroll ">
228147 < img src ="assets/my_image.jpg " alt ="A pensive anime character in a snowy city scene ">
229- < div class ="status-tag ">
230- < span class ="green-dot "> </ span > Available for work
231- </ div >
148+ < div class ="status-tag "> < span class ="green-dot "> </ span > Available for work</ div >
232149 </ div >
233150 < div class ="about-text-content animate-on-scroll ">
234- < p > I am a dedicated Software Engineering student at Ton Duc Thang University with a deep passion
235- for building efficient and user-friendly web solutions. My journey into programming started
236- with a curiosity to understand how things work, and it has grown into a drive to create
237- meaningful applications.</ p >
238- < p > I enjoy tackling challenging problems and continuously expanding my skill set in the
239- ever-evolving world of technology. From developing full-stack e-commerce platforms to
240- creating fun, interactive web apps, my goal is to leverage my technical abilities to build
241- impactful products.</ p >
151+ < p > I am a dedicated Software Engineering student at Ton Duc Thang University with a deep passion for building efficient and user-friendly web solutions. My journey into programming started with a curiosity to understand how things work, and it has grown into a drive to create meaningful applications.</ p >
152+ < p > I enjoy tackling challenging problems and continuously expanding my skill set in the ever-evolving world of technology. From developing full-stack e-commerce platforms to creating fun, interactive web apps, my goal is to leverage my technical abilities to build impactful products.</ p >
242153 < div class ="info-box-wrapper glass-card ">
243154 < div class ="info-box ">
244- < div >
245- < span class ="info-label "> Name</ span >
246- < p > Trần Hữu Đạt</ p >
247- </ div >
248- < div >
249- < span class ="info-label "> Email</ span >
250- < p > tranhuudat.cv@gmail.com</ p >
251- </ div >
252- < div >
253- < span class ="info-label "> Location</ span >
254- < p > Ho Chi Minh City, VN</ p >
255- </ div >
256- < div >
257- < span class ="info-label "> Availability</ span >
258- < p class ="available-status "> Open to Internship</ p >
259- </ div >
155+ < div > < span class ="info-label "> Name</ span > < p > Trần Hữu Đạt</ p > </ div >
156+ < div > < span class ="info-label "> Email</ span > < p > tranhuudat.cv@gmail.com</ p > </ div >
157+ < div > < span class ="info-label "> Location</ span > < p > Ho Chi Minh City, VN</ p > </ div >
158+ < div > < span class ="info-label "> Availability</ span > < p class ="available-status "> Open to Internship</ p > </ div >
260159 </ div >
261- < a href ="download-resume.html " download class ="btn-download-resume "> Download Resume < i
262- class ="fas fa-download "> </ i > </ a >
160+ < a href ="download-resume.html " download class ="btn-download-resume "> Download Resume < i class ="fas fa-download "> </ i > </ a >
263161 </ div >
264162 </ div >
265163 </ div >
266164 </ div >
267165 </ section >
268166
269- <!-- ====================================================== -->
167+ <!-- ====================================================== -->
270168 <!-- Section 3: Skills (CẬP NHẬT) -->
271169 <!-- ====================================================== -->
272170 < section id ="skills " class ="content-section ">
@@ -757,25 +655,59 @@ <h4 class="footer-title">Connect with Me</h4>
757655 < script src ="js/playlist.js "> </ script >
758656 < script src ="js/scripts.js "> </ script >
759657 < script >
658+ // Birthday specific scripts
760659 document . addEventListener ( 'DOMContentLoaded' , ( ) => {
761- const dropdownToggle = document . querySelector ( '.theme-switcher-dropdown .dropdown-toggle' ) ;
762- const dropdownMenu = document . querySelector ( '.theme-switcher-dropdown .dropdown-menu' ) ;
763-
764- if ( dropdownToggle && dropdownMenu ) {
765- dropdownToggle . addEventListener ( 'click' , ( ) => {
766- dropdownMenu . classList . toggle ( 'show' ) ;
767- } ) ;
768-
769- window . addEventListener ( 'click' , ( event ) => {
770- if ( ! event . target . matches ( '.dropdown-toggle' ) && ! event . target . matches ( '.dropdown-toggle i' ) ) {
771- if ( dropdownMenu . classList . contains ( 'show' ) ) {
772- dropdownMenu . classList . remove ( 'show' ) ;
773- }
660+ // Age Calculation
661+ const ageSpan = document . getElementById ( 'age' ) ;
662+ if ( ageSpan ) {
663+ const birthDate = new Date ( 2004 , 10 , 10 ) ; // Month is 0-indexed (November is 10)
664+ const today = new Date ( ) ;
665+ let age = today . getFullYear ( ) - birthDate . getFullYear ( ) ;
666+ const m = today . getMonth ( ) - birthDate . getMonth ( ) ;
667+ if ( m < 0 || ( m === 0 && today . getDate ( ) < birthDate . getDate ( ) ) ) {
668+ age -- ;
669+ }
670+ ageSpan . textContent = age ;
671+ }
672+
673+ // Confetti
674+ const partyContainer = document . querySelector ( '.party-container' ) ;
675+ if ( partyContainer ) {
676+ const confettiShapes = [ 'confetti-square' , 'confetti-rectangle' , 'confetti-circle' ] ;
677+ const confettiColors = [ '#f2d74e' , '#f2a64e' , '#4ef2d7' , '#4e72f2' , '#d74ef2' , '#f24e72' , '#4ef24e' ] ;
678+ for ( let i = 0 ; i < 150 ; i ++ ) {
679+ const confetti = document . createElement ( 'div' ) ;
680+ const shape = confettiShapes [ Math . floor ( Math . random ( ) * confettiShapes . length ) ] ;
681+ confetti . classList . add ( 'confetti' , shape ) ;
682+ const size = Math . random ( ) * 15 + 5 ;
683+ confetti . style . width = size + 'px' ;
684+ if ( shape === 'confetti-square' || shape === 'confetti-circle' ) {
685+ confetti . style . height = size + 'px' ;
686+ } else {
687+ confetti . style . height = size / 2 + 'px' ;
774688 }
775- } ) ;
689+ confetti . style . backgroundColor = confettiColors [ Math . floor ( Math . random ( ) * confettiColors . length ) ] ;
690+ confetti . style . left = Math . random ( ) * 100 + 'vw' ;
691+ confetti . style . animationDelay = Math . random ( ) * - 7 + 's' ;
692+ confetti . style . animationDuration = 3 + Math . random ( ) * 4 + 's' ;
693+ partyContainer . appendChild ( confetti ) ;
694+ }
776695 }
696+
697+ // Override music player for birthday song
698+ const audio = document . getElementById ( 'audio-source' ) ;
699+ const playPauseBtn = document . getElementById ( 'play-pause-btn' ) ;
700+ const nextBtn = document . getElementById ( 'next-btn' ) ;
701+ const prevBtn = document . getElementById ( 'prev-btn' ) ;
702+ const songTitle = document . getElementById ( 'song-title' ) ;
703+ const songArtist = document . getElementById ( 'song-artist' ) ;
704+
705+ if ( audio ) audio . src = 'assets/music/happy-birthday.mp3' ;
706+ if ( songTitle ) songTitle . textContent = 'Happy Birthday' ;
707+ if ( songArtist ) songArtist . textContent = 'Birthday Song' ;
708+ if ( nextBtn ) nextBtn . style . display = 'none' ;
709+ if ( prevBtn ) prevBtn . style . display = 'none' ;
777710 } ) ;
778711 </ script >
779712</ body >
780-
781713</ html >
0 commit comments