Skip to content

Commit 81f1bbd

Browse files
Merge pull request #84 from shariyaansari/ui-enhancement-theme-toggle
Enhance UI: add dark/light theme toggle, improve layout and responsive for Encryption and Decryption page
2 parents ccb57fb + 2b3c5fc commit 81f1bbd

3 files changed

Lines changed: 165 additions & 79 deletions

File tree

projects/text-encryption-decryption/index.html

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
<!DOCTYPE html>
22
<html lang="en">
33
<head>
4-
<meta charset="UTF-8">
5-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6-
<title>Text Encryption / Decryption Tool</title>
7-
<link rel="stylesheet" href="styles.css">
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Text Encryption Decryption Tool</title>
7+
<link rel="stylesheet" href="styles.css" />
88
</head>
99
<body>
10-
<h1>Text Encryption / Decryption Tool</h1>
11-
<div id="tool-container">
10+
<header class="header">
11+
<h1>Text Encryption Decryption Tool</h1>
12+
<button id="themeToggle" aria-label="Toggle theme">🌙</button>
13+
</header>
14+
15+
<main id="tool-container" class="tool-container">
1216
<div class="field-group">
1317
<label for="inputText">Input text</label>
1418
<textarea id="inputText" placeholder="Type or paste your text here..."></textarea>
@@ -21,7 +25,7 @@ <h1>Text Encryption / Decryption Tool</h1>
2125
<div class="option">
2226
<label for="algorithm">Algorithm</label>
2327
<select id="algorithm" aria-label="Encryption algorithm">
24-
<option value="caesar" selected>Caesar cipher</option>
28+
<option value="caesar" selected>Caesar Cipher</option>
2529
<option value="rot13">ROT13</option>
2630
<option value="atbash">Atbash</option>
2731
</select>
@@ -46,7 +50,8 @@ <h1>Text Encryption / Decryption Tool</h1>
4650
<small id="copyStatus" role="status" aria-live="polite"></small>
4751
</div>
4852
</div>
49-
</div>
53+
</main>
54+
5055
<script src="main.js"></script>
5156
</body>
52-
</html>
57+
</html>

projects/text-encryption-decryption/main.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
// Basic algorithms: Caesar, ROT13, Atbash
22

3+
// Handle Theme Toggle
4+
const themeButton = document.getElementById("themeToggle");
5+
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
6+
7+
if (prefersDark) document.documentElement.setAttribute("data-theme", "dark");
8+
9+
themeButton.addEventListener("click", () => {
10+
const current = document.documentElement.getAttribute("data-theme");
11+
const next = current === "dark" ? "light" : "dark";
12+
document.documentElement.setAttribute("data-theme", next);
13+
themeButton.textContent = next === "dark" ? "🌙" : "☀️";
14+
});
15+
316
function normalizeShift(n) {
417
// Normalize to range [0, 25]
518
const mod = ((n % 26) + 26) % 26;
Lines changed: 138 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,144 +1,212 @@
11
:root {
2+
--bg: #f5f6fa;
3+
--card: #ffffff;
4+
--text: #1e1e1e;
5+
--muted: #555;
6+
--primary: #5b8cff;
7+
--primary-700: #3b6ff2;
8+
--border: #d0d0d0;
9+
}
10+
11+
/* Dark mode variables */
12+
[data-theme="dark"] {
213
--bg: #0b1020;
314
--card: #111933;
415
--text: #e6eaf3;
516
--muted: #9aa3b2;
6-
--primary: #5b8cff;
7-
--primary-700: #4878f2;
817
--border: #253153;
9-
--success: #22c55e;
1018
}
1119

12-
html, body {
13-
height: 100%;
20+
.field-group textarea,
21+
.field-group input,
22+
.field-group select,
23+
.options-row select,
24+
.options-row input[type="number"],
25+
.options-row textarea {
26+
width: 100%;
27+
box-sizing: border-box;
1428
}
1529

30+
html,
1631
body {
32+
height: 100%;
1733
margin: 0;
18-
font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji";
19-
background: radial-gradient(1200px 1200px at 80% -10%, #1a2452 0%, transparent 40%), var(--bg);
34+
font-family: "Segoe UI", Roboto, Arial, sans-serif;
35+
background: var(--bg);
2036
color: var(--text);
2137
display: flex;
2238
flex-direction: column;
2339
align-items: center;
24-
padding: 32px 16px 48px;
2540
}
2641

27-
h1 {
28-
font-size: 1.8rem;
29-
font-weight: 700;
30-
letter-spacing: 0.2px;
31-
margin: 8px 0 20px;
42+
.header {
43+
display: flex;
44+
justify-content: space-between;
45+
width: 100%;
46+
max-width: 860px;
47+
align-items: center;
48+
padding: 20px;
49+
}
50+
51+
#themeToggle {
52+
border: none;
53+
background: var(--card);
54+
color: var(--text);
55+
font-size: 1.2rem;
56+
border-radius: 50%;
57+
cursor: pointer;
58+
padding: 8px;
59+
transition: background 0.3s ease;
3260
}
3361

34-
#tool-container {
62+
#themeToggle:hover {
63+
background: var(--primary);
64+
color: #fff;
65+
}
66+
67+
.tool-container {
3568
width: 100%;
3669
max-width: 860px;
3770
background: var(--card);
3871
border: 1px solid var(--border);
3972
border-radius: 14px;
4073
padding: 20px;
41-
box-shadow: 0 8px 24px rgba(0,0,0,0.35);
74+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
75+
display: flex;
76+
flex-direction: column;
77+
gap: 20px;
78+
transition: background 0.3s ease;
4279
}
4380

44-
.field-group {
81+
.option {
4582
display: flex;
4683
flex-direction: column;
4784
gap: 8px;
48-
margin-bottom: 16px;
85+
min-width: 0px;
86+
flex: 1;
4987
}
5088

51-
label {
52-
font-size: 0.95rem;
89+
.option label {
90+
font-size: 1rem;
5391
color: var(--muted);
92+
font-weight: 500;
93+
margin-bottom: 2px;
5494
}
5595

56-
textarea {
57-
width: 100%;
58-
min-height: 120px;
59-
resize: vertical;
60-
background: #0e1630;
61-
color: var(--text);
62-
border: 1px solid var(--border);
63-
border-radius: 10px;
64-
padding: 12px 12px;
65-
line-height: 1.4;
66-
font-size: 0.98rem;
67-
}
68-
69-
.meta-row {
70-
display: flex;
71-
justify-content: space-between;
72-
align-items: center;
73-
}
7496

97+
.field-group,
98+
.actions,
7599
.options-row {
76100
display: flex;
77-
gap: 12px;
101+
gap: 10px;
78102
align-items: flex-end;
79103
flex-wrap: wrap;
80-
margin-bottom: 8px;
81-
}
82-
83-
.option {
84-
display: flex;
85-
flex-direction: column;
86-
gap: 6px;
104+
margin-bottom: 16px;
87105
}
88106

89-
select, input[type="number"] {
90-
background: #0e1630;
107+
textarea,
108+
select,
109+
input[type="number"] {
110+
width: 95%;
111+
background: var(--bg);
91112
color: var(--text);
92113
border: 1px solid var(--border);
93114
border-radius: 10px;
94-
padding: 10px 12px;
95-
font-size: 0.95rem;
115+
padding: 12px;
116+
font-size: 1rem;
96117
}
97118

98-
.actions {
99-
display: flex;
100-
gap: 10px;
101-
align-items: center;
102-
margin: 10px 0 18px;
119+
select:focus,
120+
input[type="number"]:focus {
121+
border-color: var(--primary);
122+
box-shadow: 0 0 0 2px rgba(91, 140, 255, 0.15);
123+
outline: none;
103124
}
104125

105-
.actions.compact {
106-
margin-top: 6px;
126+
select {
127+
appearance: none;
128+
background-image: url("data:image/svg+xml,%3Csvg fill='none' height='16' viewBox='0 0 20 20' width='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6 8l4 4 4-4' stroke='%239aa3b2' stroke-width='2'/%3E%3C/svg%3E");
129+
background-repeat: no-repeat;
130+
background-position: right 16px center;
131+
background-size: 18px 18px;
132+
padding-right: 38px;
133+
cursor: pointer;
107134
}
108135

136+
109137
.btn {
110-
appearance: none;
111138
border: 1px solid var(--border);
112-
background: #101a36;
113-
color: var(--text);
114-
padding: 10px 14px;
115139
border-radius: 10px;
140+
padding: 10px 16px;
116141
cursor: pointer;
117142
font-weight: 600;
118-
transition: transform 0.06s ease, background 0.2s ease, border-color 0.2s ease;
143+
background: var(--bg);
144+
color: var(--text);
145+
transition: transform 0.1s ease, background 0.3s ease;
119146
}
120147

121148
.btn:hover {
122-
transform: translateY(-1px);
123-
border-color: #31406f;
149+
transform: translateY(-2px);
124150
}
125151

126152
.btn.primary {
127-
background: linear-gradient(180deg, var(--primary) 0%, var(--primary-700) 100%);
153+
background: var(--primary);
128154
border: none;
155+
color: #fff;
129156
}
130157

131158
.btn.ghost {
132159
background: transparent;
133160
}
134161

135-
#copyStatus {
136-
color: var(--success);
137-
margin-left: 6px;
162+
input[type="number"]::-webkit-inner-spin-button,
163+
input[type="number"]::-webkit-outer-spin-button {
164+
opacity: 0.4;
138165
}
139166

167+
140168
@media (max-width: 600px) {
141-
h1 { font-size: 1.4rem; }
142-
#tool-container { padding: 14px; }
143-
textarea { min-height: 100px; }
169+
body {
170+
/* Reduced body padding for very small screens */
171+
padding: 0.5rem;
172+
}
173+
174+
.header {
175+
padding: 0.5rem;
176+
margin-bottom: 0.5rem;
177+
}
178+
179+
.tool-container {
180+
padding: 1rem;
181+
/* Further reduced padding */
182+
gap: 1rem;
183+
box-shadow: 0 4px 16px var(--shadow-color);
184+
}
185+
186+
.options-row,
187+
.actions {
188+
/* This was a good call: stack elements vertically on mobile */
189+
flex-direction: column;
190+
gap: 1rem;
191+
align-items: stretch;
192+
/* Make children fill the width */
193+
}
194+
195+
.actions {
196+
/* Ensure buttons are centered and have some space */
197+
margin-top: 1rem;
198+
}
199+
200+
.option {
201+
width: 100%;
202+
/* Ensure option takes full width */
203+
}
204+
205+
.btn {
206+
/* Make buttons full width for easier tapping */
207+
width: 100%;
208+
text-align: center;
209+
padding: 12px;
210+
/* Slightly larger padding for better touch target */
211+
}
144212
}

0 commit comments

Comments
 (0)