11<!DOCTYPE html>
2- < html lang ="en ">
2+ < html lang ="en " data-theme =" light " >
33< head >
44 < meta charset ="UTF-8 ">
55 < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
6+ < title > Korean Learning Resources</ title >
7+
8+ < link rel ="preconnect " href ="https://fonts.googleapis.com ">
9+ < link rel ="preconnect " href ="https://fonts.gstatic.com " crossorigin >
10+ < link href ="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;700&family=Noto+Sans:wght@400;700&display=swap " rel ="stylesheet ">
611
7- < title > Haneul's Korean Learning Hub</ title >
8- < meta name ="description " content ="A collection of my personal notes and resources for learning the Korean language. ">
912 < style >
13+ /* --- CSS Variables for Theming --- */
1014 : root {
11- --primary-color : # 005BBB ; /* A calming blue */
12- --secondary-color : # FFD500 ; /* A vibrant yellow */
13- --text-color : # 333 ;
14- --bg-color : # f9f9f9 ;
15+ --bg-color : # f4f7f9 ;
1516 --card-bg : # ffffff ;
16- --shadow : 0 4px 8px rgba (0 , 0 , 0 , 0.1 );
17+ --text-primary : # 1a1a1a ;
18+ --text-secondary : # 5c6770 ;
19+ --accent-color : # 005BBB ;
20+ --shadow-color : rgba (0 , 0 , 0 , 0.06 );
21+ --shadow-hover-color : rgba (0 , 0 , 0 , 0.12 );
22+ --icon-bg : rgba (0 , 91 , 187 , 0.05 );
23+ --toggle-bg : # e0e5e9 ;
1724 }
18- body {
19- font-family : -apple-system, BlinkMacSystemFont, "Segoe UI" , Roboto, Helvetica, Arial, sans-serif;
25+
26+ [data-theme = "dark" ] {
27+ --bg-color : # 1a1d21 ;
28+ --card-bg : # 252a30 ;
29+ --text-primary : # e1e3e6 ;
30+ --text-secondary : # 9ea8b3 ;
31+ --shadow-color : rgba (0 , 0 , 0 , 0.2 );
32+ --shadow-hover-color : rgba (0 , 0 , 0 , 0.3 );
33+ --icon-bg : rgba (255 , 255 , 255 , 0.05 );
34+ --toggle-bg : # 3a4149 ;
35+ }
36+
37+ /* --- General Styles --- */
38+ * {
39+ box-sizing : border-box;
2040 margin : 0 ;
2141 padding : 0 ;
42+ }
43+
44+ html {
45+ scroll-behavior : smooth;
46+ }
47+
48+ body {
49+ font-family : 'Noto Sans' , 'Noto Sans KR' , sans-serif;
2250 background-color : var (--bg-color );
23- color : var (--text-color );
51+ color : var (--text-primary );
52+ transition : background-color 0.3s ease, color 0.3s ease;
2453 line-height : 1.6 ;
2554 }
55+
2656 .container {
27- max-width : 800 px ;
57+ max-width : 900 px ;
2858 margin : 0 auto;
29- padding : 2rem ;
30- }
31- header {
59+ padding : 4rem 2rem ;
3260 text-align : center;
33- margin-bottom : 3rem ;
34- border-bottom : 2px solid var (--primary-color );
35- padding-bottom : 1.5rem ;
3661 }
62+
63+ /* --- Header --- */
3764 header h1 {
3865 font-size : 2.8rem ;
39- color : var ( --primary-color ) ;
66+ font-weight : 700 ;
4067 margin-bottom : 0.5rem ;
4168 }
69+
4270 header p {
43- font-size : 1.1rem ;
44- color : # 666 ;
71+ font-size : 1.2rem ;
72+ color : var (--text-secondary );
73+ margin-bottom : 3rem ;
4574 }
46- main h2 {
47- font-size : 1.8rem ;
48- color : var (--text-color );
49- margin-bottom : 1.5rem ;
75+
76+ /* --- Theme Toggle Switch --- */
77+ .theme-switch {
78+ position : absolute;
79+ top : 20px ;
80+ right : 20px ;
81+ width : 50px ;
82+ height : 50px ;
83+ background-color : var (--card-bg );
84+ border : none;
85+ border-radius : 50% ;
86+ cursor : pointer;
87+ display : flex;
88+ align-items : center;
89+ justify-content : center;
90+ box-shadow : 0 4px 10px var (--shadow-color );
91+ transition : background-color 0.3s ease, transform 0.2s ease;
5092 }
51- # resource-list {
52- list-style : none;
53- padding : 0 ;
93+ .theme-switch : hover {
94+ transform : scale (1.1 );
95+ }
96+ .theme-switch .icon {
97+ font-size : 24px ;
5498 }
55- # resource-list li a {
56- display : block;
99+ [data-theme = "light" ] .moon-icon { display : none; }
100+ [data-theme = "dark" ] .sun-icon { display : none; }
101+
102+ /* --- Resource Grid --- */
103+ .resource-grid {
104+ display : grid;
105+ grid-template-columns : repeat (auto-fit, minmax (250px , 1fr ));
106+ gap : 1.5rem ;
107+ text-align : left;
108+ }
109+
110+ /* --- Resource Card Styles --- */
111+ .card {
57112 background-color : var (--card-bg );
58- color : var (--text-color );
59- padding : 1rem 1.5rem ;
60- margin-bottom : 1rem ;
61- border-radius : 8px ;
113+ border-radius : 12px ;
114+ padding : 1.5rem ;
62115 text-decoration : none;
116+ color : inherit;
117+ box-shadow : 0 5px 15px var (--shadow-color );
118+ display : flex;
119+ flex-direction : column;
120+ gap : 0.75rem ;
121+ transition : transform 0.3s ease, box-shadow 0.3s ease;
122+ }
123+
124+ .card : hover {
125+ transform : translateY (-6px );
126+ box-shadow : 0 12px 24px var (--shadow-hover-color );
127+ }
128+
129+ .card-icon {
130+ font-size : 2.5rem ;
131+ background-color : var (--icon-bg );
132+ width : 60px ;
133+ height : 60px ;
134+ border-radius : 50% ;
135+ display : flex;
136+ align-items : center;
137+ justify-content : center;
138+ color : var (--accent-color );
139+ }
140+
141+ .card h3 {
142+ font-size : 1.25rem ;
63143 font-weight : 500 ;
64- box-shadow : var (--shadow );
65- transition : transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
66- border-left : 5px solid var (--secondary-color );
144+ color : var (--text-primary );
67145 }
68- # resource-list li a : hover {
69- transform : translateY (-3px );
70- box-shadow : 0 6px 12px rgba (0 , 0 , 0 , 0.15 );
146+
147+ .card p {
148+ font-size : 0.95rem ;
149+ color : var (--text-secondary );
150+ flex-grow : 1 ;
71151 }
72- .loader {
73- text-align : center;
74- font-style : italic;
75- color : # 888 ;
152+
153+ .card-link {
154+ font-weight : 500 ;
155+ color : var (--accent-color );
156+ text-decoration : none;
157+ align-self : flex-start;
76158 }
77- footer {
78- text-align : center;
79- margin-top : 4rem ;
80- padding-top : 1rem ;
81- border-top : 1px solid # eee ;
82- color : # 999 ;
83- font-size : 0.9rem ;
159+
160+ /* ✨ Arrow animation for link ✨ */
161+ .card-link .arrow {
162+ display : inline-block;
163+ transition : transform 0.3s ease;
164+ }
165+ .card : hover .arrow {
166+ transform : translateX (5px );
167+ }
168+
169+ @media (max-width : 600px ) {
170+ .container { padding : 3rem 1rem ; }
171+ header h1 { font-size : 2.2rem ; }
172+ header p { font-size : 1rem ; }
84173 }
85174 </ style >
86175</ head >
87176< body >
88177
178+ < button class ="theme-switch " id ="theme-toggle " aria-label ="Toggle theme ">
179+ < span class ="icon sun-icon "> ☀️</ span >
180+ < span class ="icon moon-icon "> 🌙</ span >
181+ </ button >
182+
89183 < div class ="container ">
90184 < header >
91- < h1 > Korean Learning Hub 🇰🇷</ h1 >
92- < p > A personal collection of notes, guides, and resources on my journey to fluency. </ p >
93- </ header >
185+ < h1 > Korean Learning Resources 🇰🇷</ h1 >
186+ < p > 한국어 학습을 위한 자료 모음집을 제가 만들었습니다 </ p >
187+ </ header >
94188
95189 < main >
96- < h2 > My Resources</ h2 >
97- < ul id ="resource-list ">
98- < li class ="loader "> Loading resources...</ li >
99- </ ul >
100- </ main >
190+ < div class ="resource-grid ">
191+
192+ < a class ="card " href ="/content/particle-quiz.html ">
193+ < div class ="card-icon "> 📖</ div >
194+ < h3 > Basic Particle Quiz</ h3 >
195+ < p > A simple quiz to practice correct application of: 은/는, 이/가 and 을/를</ p >
196+ < span class ="card-link "> Open < span class ="arrow "> →</ span > </ span >
197+ </ a >
198+ <!--
199+ <a class="card" href="/content/common-verbs.html">
200+ <div class="card-icon">🗣️</div>
201+ <h3>Common Verbs</h3>
202+ <p>A list of the 100 most frequently used verbs with conjugation examples.</p>
203+ <span class="card-link">Read more <span class="arrow">→</span></span>
204+ </a>
205+
206+ <a class="card" href="/content/particles-guide.html">
207+ <div class="card-icon">🧩</div>
208+ <h3>Grammar Particles</h3>
209+ <p>Understanding the core sentence particles like 은/는, 이/가, and 을/를.</p>
210+ <span class="card-link">Read more <span class="arrow">→</span></span>
211+ </a>
101212
102- < footer >
103- < p > © 2025 Your Name Here</ p >
104- </ footer >
213+ <a class="card" href="/content/everyday-phrases.html">
214+ <div class="card-icon">💬</div>
215+ <h3>Everyday Phrases</h3>
216+ <p>Essential phrases for greetings, ordering food, and navigating everyday conversations.</p>
217+ <span class="card-link">Read more <span class="arrow">→</span></span>
218+ </a>
219+ -->
220+ </ div >
221+ </ main >
105222 </ div >
106223
107224 < script >
108225 document . addEventListener ( 'DOMContentLoaded' , ( ) => {
109- // This script automatically fetches the list of .html files from your /content/ directory.
226+ // --- Theme Toggler ---
227+ const themeToggle = document . getElementById ( 'theme-toggle' ) ;
228+ const htmlEl = document . documentElement ;
229+ const currentTheme = localStorage . getItem ( 'theme' ) || 'light' ;
110230
111- // --- Configuration ---
112- const contentPath = 'content' ; // The path to your content directory
231+ htmlEl . setAttribute ( 'data-theme' , currentTheme ) ;
113232
114- // --- No need to edit below this line ---
115-
116- // Derive the repository name from the URL
117- const pathParts = window . location . pathname . split ( '/' ) . filter ( part => part ) ;
118- const isProjectPage = pathParts . length > 0 ;
119- const repoName = isProjectPage ? pathParts [ 0 ] : `${ window . location . hostname . split ( '.' ) [ 0 ] } .github.io` ;
120- const userName = window . location . hostname . split ( '.' ) [ 0 ] ;
121-
122- const apiUrl = `https://api.github.com/repos/${ userName } /${ repoName } /contents/${ contentPath } ` ;
123- const resourceList = document . getElementById ( 'resource-list' ) ;
124-
125- fetch ( apiUrl )
126- . then ( response => {
127- if ( ! response . ok ) {
128- throw new Error ( `GitHub API error: ${ response . status } ` ) ;
129- }
130- return response . json ( ) ;
131- } )
132- . then ( files => {
133- resourceList . innerHTML = '' ; // Clear the "Loading..." message
134-
135- const htmlFiles = files . filter ( file => file . name . endsWith ( '.html' ) ) ;
136-
137- if ( htmlFiles . length === 0 ) {
138- resourceList . innerHTML = '<li>No resources found in the /content/ directory.</li>' ;
139- return ;
140- }
141-
142- htmlFiles . forEach ( file => {
143- const listItem = document . createElement ( 'li' ) ;
144- const link = document . createElement ( 'a' ) ;
145-
146- // Create a user-friendly name from the filename
147- const displayName = file . name
148- . replace ( / \. h t m l $ / , '' ) // Remove .html extension
149- . replace ( / [ - _ ] / g, ' ' ) // Replace hyphens and underscores with spaces
150- . replace ( / \b \w / g, l => l . toUpperCase ( ) ) ; // Capitalize first letter of each word
151-
152- link . href = `${ isProjectPage ? '/' + repoName : '' } /${ file . path } ` ;
153- link . textContent = displayName ;
154-
155- listItem . appendChild ( link ) ;
156- resourceList . appendChild ( listItem ) ;
157- } ) ;
158- } )
159- . catch ( error => {
160- console . error ( 'Error fetching resources:' , error ) ;
161- resourceList . innerHTML = '<li>Could not load resources. Check the browser console for more details.</li>' ;
162- } ) ;
233+ themeToggle . addEventListener ( 'click' , ( ) => {
234+ const newTheme = htmlEl . getAttribute ( 'data-theme' ) === 'dark' ? 'light' : 'dark' ;
235+ htmlEl . setAttribute ( 'data-theme' , newTheme ) ;
236+ localStorage . setItem ( 'theme' , newTheme ) ;
237+ } ) ;
163238 } ) ;
164239 </ script >
165-
166240</ body >
167- </ html >
241+ </ html >
0 commit comments