Skip to content

Commit 436e793

Browse files
author
Vaibhaav
committed
feat: add dark/light mode toggle demo
1 parent 83091ce commit 436e793

1 file changed

Lines changed: 229 additions & 0 deletions

File tree

index.html

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Dark/Light Mode Toggle</title>
7+
<style>
8+
:root {
9+
--bg-primary: #ffffff;
10+
--bg-secondary: #f5f5f5;
11+
--bg-card: #ffffff;
12+
--text-primary: #1a1a1a;
13+
--text-secondary: #666666;
14+
--border-color: #e0e0e0;
15+
--shadow: rgba(0, 0, 0, 0.1);
16+
--toggle-bg: #e0e0e0;
17+
--toggle-active: #3b82f6;
18+
}
19+
20+
.dark {
21+
--bg-primary: #1a1a1a;
22+
--bg-secondary: #2d2d2d;
23+
--bg-card: #252525;
24+
--text-primary: #ffffff;
25+
--text-secondary: #a0a0a0;
26+
--border-color: #404040;
27+
--shadow: rgba(0, 0, 0, 0.3);
28+
--toggle-bg: #404040;
29+
--toggle-active: #60a5fa;
30+
}
31+
32+
* {
33+
margin: 0;
34+
padding: 0;
35+
box-sizing: border-box;
36+
}
37+
38+
body {
39+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
40+
background: var(--bg-primary);
41+
color: var(--text-primary);
42+
min-height: 100vh;
43+
display: flex;
44+
align-items: center;
45+
justify-content: center;
46+
transition: background-color 0.3s ease, color 0.3s ease;
47+
}
48+
49+
.card {
50+
background: var(--bg-card);
51+
border: 1px solid var(--border-color);
52+
border-radius: 16px;
53+
padding: 40px;
54+
max-width: 400px;
55+
width: 90%;
56+
box-shadow: 0 4px 20px var(--shadow);
57+
transition: background-color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
58+
}
59+
60+
.card-header {
61+
display: flex;
62+
align-items: center;
63+
justify-content: space-between;
64+
margin-bottom: 24px;
65+
}
66+
67+
h1 {
68+
font-size: 24px;
69+
font-weight: 600;
70+
color: var(--text-primary);
71+
transition: color 0.3s ease;
72+
}
73+
74+
p {
75+
color: var(--text-secondary);
76+
line-height: 1.6;
77+
margin-bottom: 20px;
78+
transition: color 0.3s ease;
79+
}
80+
81+
.toggle-container {
82+
display: flex;
83+
align-items: center;
84+
gap: 12px;
85+
}
86+
87+
.toggle-label {
88+
font-size: 14px;
89+
color: var(--text-secondary);
90+
transition: color 0.3s ease;
91+
}
92+
93+
.toggle {
94+
position: relative;
95+
width: 56px;
96+
height: 28px;
97+
background: var(--toggle-bg);
98+
border-radius: 28px;
99+
cursor: pointer;
100+
transition: background-color 0.3s ease;
101+
}
102+
103+
.toggle::after {
104+
content: '';
105+
position: absolute;
106+
top: 4px;
107+
left: 4px;
108+
width: 20px;
109+
height: 20px;
110+
background: #ffffff;
111+
border-radius: 50%;
112+
transition: transform 0.3s ease, box-shadow 0.3s ease;
113+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
114+
}
115+
116+
.toggle.active {
117+
background: var(--toggle-active);
118+
}
119+
120+
.toggle.active::after {
121+
transform: translateX(28px);
122+
}
123+
124+
.icon {
125+
width: 20px;
126+
height: 20px;
127+
color: var(--text-secondary);
128+
transition: color 0.3s ease;
129+
}
130+
131+
.demo-section {
132+
margin-top: 24px;
133+
padding-top: 24px;
134+
border-top: 1px solid var(--border-color);
135+
}
136+
137+
.demo-section h2 {
138+
font-size: 16px;
139+
font-weight: 600;
140+
color: var(--text-primary);
141+
margin-bottom: 12px;
142+
transition: color 0.3s ease;
143+
}
144+
145+
.demo-section p {
146+
font-size: 14px;
147+
margin-bottom: 8px;
148+
}
149+
150+
.badge {
151+
display: inline-block;
152+
padding: 4px 12px;
153+
background: var(--bg-secondary);
154+
color: var(--text-primary);
155+
border-radius: 12px;
156+
font-size: 12px;
157+
font-weight: 500;
158+
margin-top: 12px;
159+
transition: background-color 0.3s ease, color 0.3s ease;
160+
}
161+
</style>
162+
</head>
163+
<body>
164+
<div class="card">
165+
<div class="card-header">
166+
<h1>Theme Toggle</h1>
167+
<div class="toggle-container">
168+
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
169+
<circle cx="12" cy="12" r="5"></circle>
170+
<line x1="12" y1="1" x2="12" y2="3"></line>
171+
<line x1="12" y1="21" x2="12" y2="23"></line>
172+
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
173+
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
174+
<line x1="1" y1="12" x2="3" y2="12"></line>
175+
<line x1="21" y1="12" x2="23" y2="12"></line>
176+
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
177+
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
178+
</svg>
179+
<div class="toggle" id="themeToggle" role="button" aria-label="Toggle dark mode" tabindex="0"></div>
180+
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
181+
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
182+
</svg>
183+
</div>
184+
</div>
185+
<p>
186+
This is a demonstration of a dark/light mode toggle. Click the pill-shaped switch above to toggle between themes.
187+
</p>
188+
<div class="demo-section">
189+
<h2>Theme Demo Content</h2>
190+
<p>Notice how all colors smoothly transition when you switch themes. The preference is saved to localStorage.</p>
191+
<span class="badge" id="currentTheme">Light Mode</span>
192+
</div>
193+
</div>
194+
195+
<script>
196+
const toggle = document.getElementById('themeToggle');
197+
const themeLabel = document.getElementById('currentTheme');
198+
const STORAGE_KEY = 'theme-preference';
199+
200+
// Read from localStorage on load
201+
const savedTheme = localStorage.getItem(STORAGE_KEY);
202+
if (savedTheme === 'dark') {
203+
document.body.classList.add('dark');
204+
toggle.classList.add('active');
205+
themeLabel.textContent = 'Dark Mode';
206+
}
207+
208+
// Toggle theme on click
209+
toggle.addEventListener('click', () => {
210+
document.body.classList.toggle('dark');
211+
toggle.classList.toggle('active');
212+
213+
const isDark = document.body.classList.contains('dark');
214+
themeLabel.textContent = isDark ? 'Dark Mode' : 'Light Mode';
215+
216+
// Persist to localStorage
217+
localStorage.setItem(STORAGE_KEY, isDark ? 'dark' : 'light');
218+
});
219+
220+
// Support keyboard accessibility
221+
toggle.addEventListener('keydown', (e) => {
222+
if (e.key === 'Enter' || e.key === ' ') {
223+
e.preventDefault();
224+
toggle.click();
225+
}
226+
});
227+
</script>
228+
</body>
229+
</html>

0 commit comments

Comments
 (0)