Rohan Verma

Commit Diff


commit - 723318ed9909b19ede955398040d29373ea5a6ea
commit + 190cf253c5f3813c4e281a8b152f6d8366fe368e
blob - a0aa9fd9052bc994d41a4c54d2ec6c855e16b225
blob + 390f89a32c2ca81867a88aec9dfa31c26642f142
--- got/index.html
+++ got/index.html
@@ -4,7 +4,8 @@
 <title>Repositories - Rohan Verma</title>
 <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
-<link rel="stylesheet" href="/static/style.css?v=9">
+<link rel="stylesheet" href="/static/style.css?v=10">
+<script src="/static/theme.js?v=1"></script>
 <header class="topbar">
 	<div>
 		<a class="wordmark" href="/"><img class="signature" src="/static/signature.png" alt="" width="28" height="28">Rohan Verma</a>
@@ -13,6 +14,7 @@
 			<a href="/work">work</a>
 			<a href="/got">got</a>
 			<a href="/static/resume.pdf">résumé</a>
+			<button class="theme" type="button" aria-pressed="false">dark</button>
 		</nav>
 	</div>
 </header>
blob - 50003f96dd4fe811136fbe11a4e32a6a4ae7f2cf
blob + 64318ab3aa6e91d1de119142a93d5dc61dfbf2e8
--- index.html
+++ index.html
@@ -5,7 +5,8 @@
 <meta name="description" content="Rohan Verma (18), Computer Science student at Northeastern University. Systems, self-hosting, and Minecraft mods with over 1M downloads.">
 <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
-<link rel="stylesheet" href="/static/style.css?v=9">
+<link rel="stylesheet" href="/static/style.css?v=10">
+<script src="/static/theme.js?v=1"></script>
 
 <header class="topbar">
 	<div>
@@ -15,6 +16,7 @@
 			<a href="/work">work</a>
 			<a href="/got">got</a>
 			<a href="/static/resume.pdf">résumé</a>
+			<button class="theme" type="button" aria-pressed="false">dark</button>
 		</nav>
 	</div>
 </header>
@@ -45,12 +47,14 @@
 
 	<section>
 		<h2>Contributions</h2>
-		<picture>
-			<source srcset="/static/contrib-half-dark.svg?v=6" media="(max-width: 600px) and (prefers-color-scheme: dark)" width="334" height="112">
+		<picture class="light">
 			<source srcset="/static/contrib-half.svg?v=6" media="(max-width: 600px)" width="334" height="112">
-			<source srcset="/static/contrib-dark.svg?v=6" media="(prefers-color-scheme: dark)">
 			<img class="contrib" src="/static/contrib.svg?v=6" loading="lazy" alt="Contribution graph for the last year across Got, sourcehut and GitHub" width="658" height="112">
 		</picture>
+		<picture class="dark">
+			<source srcset="/static/contrib-half-dark.svg?v=6" media="(max-width: 600px)" width="334" height="112">
+			<img class="contrib" src="/static/contrib-dark.svg?v=6" loading="lazy" alt="Contribution graph for the last year across Got, sourcehut and GitHub" width="658" height="112">
+		</picture>
 	</section>
 
 	<footer>
blob - 4ae20127d9f89d0705a03b2512868ee78fbc848f
blob + 010f6cb04da28d660ab73484487e207c1bdc7d13
--- static/style.css
+++ static/style.css
@@ -9,19 +9,25 @@
 	--rule: #e3e0d8;
 	--accent: #c2510c;
 }
-@media (prefers-color-scheme: dark) {
-	:root {
-		--bg: #171614;
-		--text: #d6d3cb;
-		--strong: #f1eee6;
-		--muted: #8f8c84;
-		--rule: #2f2d29;
-		--accent: #ff9a5a;
-	}
-	.signature {
-		filter: invert(.9);
-	}
+/* light is the default; the nav button sets data-theme="dark" */
+:root[data-theme="dark"] {
+	--bg: #171614;
+	--text: #d6d3cb;
+	--strong: #f1eee6;
+	--muted: #8f8c84;
+	--rule: #2f2d29;
+	--accent: #ff9a5a;
 }
+[data-theme="dark"] .signature {
+	filter: invert(.9);
+}
+picture.dark,
+[data-theme="dark"] picture.light {
+	display: none;
+}
+[data-theme="dark"] picture.dark {
+	display: inline;
+}
 
 body {
 	margin: 0;
@@ -101,12 +107,29 @@ a:focus-visible {
 	height: 28px;
 	margin-right: .45em;
 }
-nav a {
+nav a, .theme {
 	margin-left: 1.1em;
 	color: var(--muted);
 	font-style: italic;
 	text-decoration: none;
 }
+/* theme toggle, dressed as a nav link */
+.theme {
+	padding: 0;
+	vertical-align: middle;
+	border: 0;
+	background: none;
+	font: inherit;
+	font-style: italic;
+	cursor: pointer;
+}
+.theme:hover {
+	color: var(--accent);
+}
+.theme:focus-visible {
+	outline: 1px solid var(--accent);
+	outline-offset: 2px;
+}
 
 main > section {
 	margin-bottom: 2.6em;
blob - /dev/null
blob + b01728be798c5cd0c051f93dfed44ae003e4c92d (mode 644)
--- /dev/null
+++ static/theme.js
@@ -0,0 +1,33 @@
+/* Light by default; the nav button switches to dark and remembers it.
+ * Loaded in <head> so the saved theme is set before the page paints. */
+(function () {
+	var root = document.documentElement;
+	try {
+		if (localStorage.getItem("theme") === "dark")
+			root.setAttribute("data-theme", "dark");
+	} catch (e) {}
+
+	function label(button) {
+		var dark = root.getAttribute("data-theme") === "dark";
+		button.textContent = dark ? "light" : "dark";
+		button.setAttribute("aria-pressed", dark);
+	}
+
+	document.addEventListener("DOMContentLoaded", function () {
+		var button = document.querySelector(".theme");
+		if (!button)
+			return;
+		label(button);
+		button.addEventListener("click", function () {
+			var dark = root.getAttribute("data-theme") !== "dark";
+			if (dark)
+				root.setAttribute("data-theme", "dark");
+			else
+				root.removeAttribute("data-theme");
+			try {
+				localStorage.setItem("theme", dark ? "dark" : "light");
+			} catch (e) {}
+			label(button);
+		});
+	});
+})();
blob - d91957d82a6bce8264cb40df6b573d82cd4ad867
blob + 9593972ac8f607be007e81c7e8b1582587fe13d3
--- work/index.html
+++ work/index.html
@@ -4,7 +4,8 @@
 <title>Work - Rohan Verma</title>
 <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
-<link rel="stylesheet" href="/static/style.css?v=9">
+<link rel="stylesheet" href="/static/style.css?v=10">
+<script src="/static/theme.js?v=1"></script>
 
 <header class="topbar">
 	<div>
@@ -14,6 +15,7 @@
 			<a href="/work">work</a>
 			<a href="/got">got</a>
 			<a href="/static/resume.pdf">résumé</a>
+			<button class="theme" type="button" aria-pressed="false">dark</button>
 		</nav>
 	</div>
 </header>