1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2025-04-26 03:05:24 -04:00

semantic color names

This commit is contained in:
Jake Jarvis 2025-04-24 11:20:02 -04:00
parent c9a8b3eaa5
commit 1010837e2f
Signed by: jake
SSH Key Fingerprint: SHA256:nCkvAjYA6XaSPUqc4TfbBQTpzr8Xj7ritg/sGInCdkc
24 changed files with 104 additions and 167 deletions

View File

@ -2,15 +2,15 @@
width: 100%;
padding: 0.8em;
margin: 0.6em 0;
border: 2px solid var(--colors-light);
border: 2px solid var(--color-gray-400);
border-radius: 0.6em;
color: var(--colors-text);
background-color: var(--colors-super-duper-light);
background-color: var(--color-gray-100);
}
.input:focus {
outline: none;
border-color: var(--colors-link);
border-color: var(--color-link);
}
.input.textarea {
@ -21,12 +21,12 @@
}
.input.invalid {
border-color: var(--colors-error);
border-color: var(--color-error);
}
.errorMessage {
font-size: 0.9em;
color: var(--colors-error);
color: var(--color-error);
}
.actionRow {
@ -48,13 +48,13 @@
user-select: none;
font-weight: 500;
color: var(--colors-text);
background-color: var(--colors-kinda-light);
background-color: var(--color-gray-300);
}
.submitButton:hover,
.submitButton:focus-visible {
color: var(--colors-super-duper-light);
background-color: var(--colors-link);
color: var(--color-gray-100);
background-color: var(--color-link);
}
.submitIcon {
@ -70,11 +70,11 @@
}
.result.success {
color: var(--colors-success);
color: var(--color-success);
}
.result.error {
color: var(--colors-error);
color: var(--color-error);
}
.resultIcon {

View File

@ -32,7 +32,7 @@ const Page = () => {
size="0.975em"
style={{
marginRight: "0.15em",
stroke: "var(--colors-warning)",
stroke: "var(--color-warning)",
verticalAlign: "middle",
}}
/>{" "}

View File

@ -9,92 +9,66 @@
--container-default: var(--container-4xl);
--color-*: initial;
--color-background-inner: #ffffff;
--color-background-outer: #fcfcfc;
--color-text: #202020;
--color-medium-dark: #515151;
--color-medium: #5e5e5e;
--color-medium-light: #757575;
--color-light: #d2d2d2;
--color-kinda-light: #e3e3e3;
--color-super-light: #f4f4f4;
--color-super-duper-light: #fbfbfb;
--color-link: #0e6dc2;
--color-success: #44a248;
--color-error: #ff1b1b;
--color-warning: #f78200;
--color-background-inner: oklch(1 0 0);
--color-background-outer: oklch(0.99 0 0);
--color-gray-900: oklch(0.27 0 0);
/* --color-gray-800: */
--color-gray-700: oklch(0.39 0 0);
--color-gray-600: oklch(0.44 0 0);
--color-gray-500: oklch(0.53 0 0);
--color-gray-400: oklch(0.85 0 0);
--color-gray-300: oklch(0.9 0 0);
--color-gray-200: oklch(0.96 0 0);
--color-gray-100: oklch(0.99 0 0);
--color-link: oklch(0.57 0.17 255);
--color-success: oklch(0.68 0.16 142);
--color-error: oklch(0.65 0.26 25);
--color-warning: oklch(0.75 0.17 75);
--animate-wave: wave 5s ease 1s infinite;
--animate-heartbeat: heartbeat 10s ease 7.5s infinite;
@keyframes wave {
0% {
transform: rotate(0deg);
}
5% {
transform: rotate(14deg);
}
10% {
transform: rotate(-8deg);
}
15% {
transform: rotate(14deg);
}
20% {
transform: rotate(-4deg);
}
25% {
transform: rotate(10deg);
}
30% {
transform: rotate(0deg);
}
0% { transform: rotate(0deg) }
5% { transform: rotate(14deg) }
10% { transform: rotate(-8deg) }
15% { transform: rotate(14deg) }
20% { transform: rotate(-4deg) }
25% { transform: rotate(10deg) }
30% { transform: rotate(0deg) }
/* pause for ~9 out of 10 seconds */
100% {
transform: rotate(0deg);
}
100% { transform: rotate(0deg) }
}
@keyframes heartbeat {
0% {
transform: scale(1);
}
2% {
transform: scale(1.25);
}
4% {
transform: scale(1);
}
6% {
transform: scale(1.2);
}
8% {
transform: scale(1);
}
0% { transform: scale(1) }
2% { transform: scale(1.25) }
4% { transform: scale(1) }
6% { transform: scale(1.2) }
8% { transform: scale(1) }
/* pause for ~9 out of 10 seconds */
100% {
transform: scale(1);
}
100% { transform: scale(1) }
}
}
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
[data-theme="dark"] {
--color-background-inner: #1e1e1e;
--color-background-outer: #252525;
--color-text: #f1f1f1;
--color-medium-dark: #d7d7d7;
--color-medium: #b1b1b1;
--color-medium-light: #959595;
--color-light: #646464;
--color-kinda-light: #535353;
--color-super-light: #272727;
--color-super-duper-light: #1f1f1f;
--color-link: #88c7ff;
--color-success: #78df55;
--color-error: #ff5151;
--color-warning: #f2b702;
--color-background-inner: oklch(0.2 0 0);
--color-background-outer: oklch(0.22 0 0);
--color-gray-900: oklch(0.95 0 0);
/* --color-gray-800: */
--color-gray-700: oklch(0.87 0 0);
--color-gray-600: oklch(0.74 0 0);
--color-gray-500: oklch(0.65 0 0);
--color-gray-400: oklch(0.46 0 0);
--color-gray-300: oklch(0.4 0 0);
--color-gray-200: oklch(0.23 0 0);
--color-gray-100: oklch(0.2 0 0);
--color-link: oklch(0.8 0.1 230);
--color-success: oklch(0.83 0.15 142);
--color-error: oklch(0.7 0.2 25);
--color-warning: oklch(0.85 0.15 85);
}

View File

@ -57,7 +57,7 @@ const Page = () => {
fontSize: "0.9em",
lineHeight: 1.8,
margin: "1.25em 1em 0 1em",
color: "var(--colors-medium-light)",
color: "var(--color-gray-500)",
}}
>
Video is property of{" "}

View File

@ -62,7 +62,7 @@ const RootLayout = ({ children }: Readonly<{ children: React.ReactNode }>) => {
/>
</head>
<body className="bg-background-outer text-text font-sans">
<body className="bg-background-outer font-sans text-gray-900">
<ThemeProvider>
<SkipNavLink />

View File

@ -56,7 +56,7 @@ const Page = () => {
fontSize: "0.9em",
lineHeight: 1.8,
margin: "1.25em 1em 0 1em",
color: "var(--colors-medium-light)",
color: "var(--color-gray-500)",
}}
>
Video is property of{" "}

View File

@ -41,7 +41,7 @@
.meta .metaTag::before {
content: "\0023"; /* cosmetically hashtagify tags */
padding-right: 0.125em;
color: var(--colors-light);
color: var(--color-gray-400);
}
.meta .metaTag:last-of-type {
@ -66,7 +66,7 @@
.comments {
margin-top: 2em;
padding-top: 2em;
border-top: 2px solid var(--colors-light);
border-top: 2px solid var(--color-gray-400);
min-height: 140px;
}

View File

@ -123,7 +123,7 @@ const Page = () => {
>
the Tooth Fairy
</Link>
. <span className="text-medium-light">I&rsquo;ve improved a bit since then, I think? 🤷</span>
. <span className="text-gray-500">I&rsquo;ve improved a bit since then, I think? 🤷</span>
</p>
<p className="my-3 text-base leading-7 md:text-[0.975rem]">

View File

@ -85,7 +85,7 @@ _Previously on the [Cringey Chronicles&trade;](https://web.archive.org/web/20010
<iframe
src="https://jakejarvis.github.io/my-first-website/"
title="My Terrible, Horrible, No Good, Very Bad First Website"
style={{ height: "500px", width: "100%", border: "1px solid var(--colors-kinda-light)", marginBottom: "-0.4em" }}
style={{ height: "500px", width: "100%", border: "1px solid var(--color-gray-300)", marginBottom: "-0.4em" }}
/>
_[November 2001](https://jakejarvis.github.io/my-first-website/) ([view
source](https://github.com/jakejarvis/my-first-website))_

View File

@ -31,7 +31,7 @@ const Page = async () => {
<>
<PageTitle canonical="/projects">Projects</PageTitle>
<h2 className="my-3.5 text-[1.4em] font-normal">
<h2 className="my-3.5 text-xl font-normal">
<Link
href={`https://github.com/${env.NEXT_PUBLIC_GITHUB_USERNAME}`}
className="text-inherit hover:no-underline"
@ -46,14 +46,14 @@ const Page = async () => {
"mx-auto mt-4 mb-8",
"[--activity-0:#ebedf0] [--activity-1:#9be9a8] [--activity-2:#40c463] [--activity-3:#30a14e] [--activity-4:#216e39]",
"dark:[--activity-0:#252525] dark:[--activity-1:#033a16] dark:[--activity-2:#196c2e] dark:[--activity-3:#2ea043] dark:[--activity-4:#56d364]",
String.raw`[&_.react-activity-calendar\_\_count]:text-medium [&_.react-activity-calendar\_\_legend-month]:text-medium [&_.react-activity-calendar\_\_legend-colors]:text-medium-light`
String.raw`[&_.react-activity-calendar\_\_count]:text-gray-600 [&_.react-activity-calendar\_\_legend-colors]:text-gray-500 [&_.react-activity-calendar\_\_legend-month]:text-gray-600`
)}
>
<Calendar data={contributions} />
</div>
</Suspense>
<h2 className="my-3.5 text-[1.4em] font-normal">
<h2 className="my-3.5 text-xl font-normal">
<Link
href={`https://github.com/${env.NEXT_PUBLIC_GITHUB_USERNAME}?tab=repositories&sort=stargazers`}
className="text-inherit hover:no-underline"
@ -62,21 +62,21 @@ const Page = async () => {
</Link>
</h2>
<div className="flex w-full flex-row flex-wrap items-start justify-between gap-[1em] leading-[1.1]">
<div className="row-auto grid w-full grid-cols-none gap-4 lg:grid-cols-2">
{repos?.map((repo) => (
<div
key={repo!.name}
className="border-kinda-light text-medium-dark w-[370px] grow rounded-[1em] border border-solid px-[1.2em] pt-[1.2em] pb-[0.8em] text-[0.9em]"
className="h-fit rounded-[1em] border border-solid border-gray-300 p-4 text-[0.9em] text-gray-700"
>
<Link href={repo!.url} className="mb-[0.4em] inline-block text-[1.2em] font-semibold">
<Link href={repo!.url} className="mb-1.5 inline-block text-base font-semibold">
{repo!.name}
</Link>
{repo!.description && <p className="m-0 leading-[1.7]">{repo!.description}</p>}
{repo!.description && <p className="m-0 text-[0.825rem] leading-relaxed">{repo!.description}</p>}
<div className="mt-[0.4em] flex flex-wrap">
<div className="mt-2 flex flex-wrap">
{repo!.primaryLanguage && (
<div className="text-medium my-[0.3em] mr-[1.5em] ml-0 whitespace-nowrap">
<div className="mt-1.5 mr-6 whitespace-nowrap text-gray-600">
{repo!.primaryLanguage.color && (
<span
className="mr-[0.5em] inline-block h-[1.25em] w-[1.25em] align-text-top"
@ -88,7 +88,7 @@ const Page = async () => {
)}
{repo!.stargazerCount > 0 && (
<div className="text-medium my-[0.3em] mr-[1.5em] ml-0 whitespace-nowrap">
<div className="mt-1.5 mr-6 whitespace-nowrap text-gray-600">
<Link
href={`${repo!.url}/stargazers`}
title={`${Intl.NumberFormat(env.NEXT_PUBLIC_SITE_LOCALE).format(repo!.stargazerCount)} ${repo!.stargazerCount === 1 ? "star" : "stars"}`}
@ -101,7 +101,7 @@ const Page = async () => {
)}
{repo!.forkCount > 0 && (
<div className="text-medium my-[0.3em] mr-[1.5em] ml-0 whitespace-nowrap">
<div className="mt-1.5 mr-6 whitespace-nowrap text-gray-600">
<Link
href={`${repo!.url}/network/members`}
title={`${Intl.NumberFormat(env.NEXT_PUBLIC_SITE_LOCALE).format(repo!.forkCount)} ${repo!.forkCount === 1 ? "fork" : "forks"}`}
@ -116,7 +116,7 @@ const Page = async () => {
</div>
)}
<div className="text-medium my-[0.3em] mr-[1.5em] ml-0 whitespace-nowrap">
<div className="mt-1.5 mr-6 whitespace-nowrap text-gray-600">
<span
// invisible icon hack to fix line height
className="mr-0 inline-block h-[1.25em] w-0 align-text-top"
@ -138,7 +138,7 @@ const Page = async () => {
viewBox="0 0 24 24"
width="1.2em"
height="1.2em"
className="fill-text mr-[0.1em] ml-[0.25em] inline h-[1.2em] w-[1.2em] align-text-top"
className="mr-[0.1em] ml-[0.25em] inline h-[1.2em] w-[1.2em] fill-gray-700 align-text-top"
>
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
</svg>{" "}

View File

@ -1,37 +0,0 @@
:root {
--colors-background-inner: #ffffff;
--colors-background-outer: #fcfcfc;
--colors-background-header: rgb(252 252 252 / 70%);
--colors-text: #202020;
--colors-medium-dark: #515151;
--colors-medium: #5e5e5e;
--colors-medium-light: #757575;
--colors-light: #d2d2d2;
--colors-kinda-light: #e3e3e3;
--colors-super-light: #f4f4f4;
--colors-super-duper-light: #fbfbfb;
--colors-link: #0e6dc2;
--colors-link-underline: #a6c5e7;
--colors-success: #44a248;
--colors-error: #ff1b1b;
--colors-warning: #f78200;
}
[data-theme="dark"] {
--colors-background-inner: #1e1e1e;
--colors-background-outer: #252525;
--colors-background-header: rgb(37 37 37 / 70%);
--colors-text: #f1f1f1;
--colors-medium-dark: #d7d7d7;
--colors-medium: #b1b1b1;
--colors-medium-light: #959595;
--colors-light: #646464;
--colors-kinda-light: #535353;
--colors-super-light: #272727;
--colors-super-duper-light: #1f1f1f;
--colors-link: #88c7ff;
--colors-link-underline: #496278;
--colors-success: #78df55;
--colors-error: #ff5151;
--colors-warning: #f2b702;
}

View File

@ -32,14 +32,14 @@ const Page = () => {
>
<code
style={{
backgroundColor: "var(--colors-background-header)",
backgroundColor: "var(--color-background-header)",
backdropFilter: "saturate(180%) blur(5px))",
display: "block",
overflowX: "auto",
padding: "1em",
fontSize: "0.9em",
tabSize: 2,
border: "1px solid var(--colors-kinda-light)",
border: "1px solid var(--color-gray-300)",
borderRadius: "0.6em",
}}
>

View File

@ -4,7 +4,7 @@ import type { ComponentPropsWithoutRef } from "react";
export type BlockquoteProps = ComponentPropsWithoutRef<"blockquote">;
const Blockquote = ({ className, ...rest }: BlockquoteProps) => (
<blockquote className={cn("border-l-link text-medium-dark ml-0 border-l-4 pl-5", className)} {...rest} />
<blockquote className={cn("border-l-link ml-0 border-l-4 pl-5 text-gray-700", className)} {...rest} />
);
export default Blockquote;

View File

@ -7,8 +7,8 @@
font-size: 0.925em;
tab-size: 2px;
page-break-inside: avoid;
background-color: var(--colors-background-header);
border: 1px solid var(--colors-kinda-light);
background-color: var(--color-background-header);
border: 1px solid var(--color-gray-300);
border-radius: 0.6em;
}
@ -55,7 +55,7 @@ figure .code[data-line-numbers] > [data-line]::before {
width: 1em;
margin-right: 1.5em;
text-align: right;
color: var(--colors-medium-light);
color: var(--color-gray-500);
user-select: none;
counter-increment: line;
content: counter(line);
@ -76,11 +76,11 @@ figure .code[data-line-numbers-max-digits="3"] > [data-line]::before {
height: 3em;
width: 3em;
padding: 0; /* iOS safari fix */
color: var(--colors-medium-dark);
border: 1px solid var(--colors-kinda-light);
color: var(--color-gray-700);
border: 1px solid var(--color-gray-300);
border-top-right-radius: 0.6em;
border-bottom-left-radius: 0.6em;
background-color: var(--colors-background-header);
background-color: var(--color-background-header);
backdrop-filter: saturate(180%) blur(5px);
}
@ -92,5 +92,5 @@ figure .code[data-line-numbers-max-digits="3"] > [data-line]::before {
.copyButton:hover,
.copyButton:focus-visible {
color: var(--colors-link);
color: var(--color-link);
}

View File

@ -52,7 +52,7 @@ const CopyButton = ({ source, timeout = 2000, style, ...rest }: CopyButtonProps,
{...rest}
>
{copied ? (
<CheckIcon size="1.25em" style={{ stroke: "var(--colors-success)" }} />
<CheckIcon size="1.25em" style={{ stroke: "var(--color-success)" }} />
) : (
<ClipboardIcon size="1.25em" />
)}

View File

@ -10,17 +10,17 @@ export type FooterProps = ComponentPropsWithoutRef<"footer">;
const Footer = ({ className, ...rest }: FooterProps) => {
return (
<footer
className={cn("border-t-kinda-light bg-background-outer text-medium-dark w-full border-t py-4", className)}
className={cn("bg-background-outer w-full border-t border-t-gray-300 py-4 text-gray-700", className)}
{...rest}
>
<div className="max-w-default mx-auto flex w-full flex-col justify-between px-5 text-[0.8rem] leading-9 md:flex-row">
<div>
Content{" "}
<Link href="/license" title={config.license} className="text-medium-dark hover:no-underline">
<Link href="/license" title={config.license} className="text-gray-700 hover:no-underline">
licensed under {config.licenseAbbr}
</Link>
,{" "}
<Link href="/previously" title="Previously on..." className="text-medium-dark hover:no-underline">
<Link href="/previously" title="Previously on..." className="text-gray-700 hover:no-underline">
{config.copyrightYearStart}
</Link>{" "}
{new Date().getUTCFullYear()}.
@ -38,7 +38,7 @@ const Footer = ({ className, ...rest }: FooterProps) => {
href="https://nextjs.org/"
title="Powered by Next.js"
aria-label="Next.js"
className="text-medium-dark hover:text-medium hover:no-underline"
className="text-gray-700 hover:text-gray-600 hover:no-underline"
>
<svg
xmlns="http://www.w3.org/2000/svg"
@ -57,7 +57,7 @@ const Footer = ({ className, ...rest }: FooterProps) => {
<Link
href={`https://github.com/${env.NEXT_PUBLIC_GITHUB_REPO}`}
title="View Source on GitHub"
className="border-b-light text-medium-dark hover:border-b-kinda-light border-b-2 pb-0.5 hover:no-underline"
className="border-b-2 border-b-gray-400 pb-0.5 text-gray-700 hover:border-b-gray-300 hover:no-underline"
>
View source.
</Link>

View File

@ -13,7 +13,7 @@ const Header = ({ className, ...rest }: HeaderProps) => {
return (
<header
className={cn(
"bg-background-outer/70 border-kinda-light sticky top-0 z-[1000] h-24 w-full border-b backdrop-blur-[5px] backdrop-saturate-[180%] md:h-18",
"bg-background-outer/70 sticky top-0 z-100 h-24 w-full border-b border-gray-300 backdrop-blur-xs backdrop-saturate-180 md:h-18",
className
)}
{...rest}
@ -24,12 +24,12 @@ const Header = ({ className, ...rest }: HeaderProps) => {
href="/"
rel="author"
aria-label={config.authorName}
className="text-medium-dark hover:text-link flex flex-shrink-0 items-center hover:no-underline"
className="hover:text-link flex flex-shrink-0 items-center text-gray-700 hover:no-underline"
>
<Image
src={avatarImg}
alt={`Photo of ${config.authorName}`}
className="border-light h-[70px] w-[70px] rounded-full border-2 md:h-[48px] md:w-[48px] md:border"
className="h-[70px] w-[70px] rounded-full border-2 border-gray-400 md:h-[48px] md:w-[48px] md:border"
width={70}
height={70}
quality={50}

View File

@ -12,7 +12,7 @@
.h.divider {
padding-bottom: 0.25em;
border-bottom: 1px solid var(--colors-kinda-light);
border-bottom: 1px solid var(--color-gray-300);
}
.anchor {
@ -27,7 +27,7 @@
/* show anchor link when hovering anywhere over the heading line, or on keyboard tab focus */
.anchor:hover,
.anchor:focus-visible {
color: var(--colors-link) !important;
color: var(--color-link) !important;
}
.h:hover .anchor,

View File

@ -3,5 +3,5 @@
max-width: calc(var(--max-width) - 1.5em);
height: 1px;
border: 0;
background-color: var(--colors-light);
background-color: var(--color-gray-400);
}

View File

@ -7,7 +7,7 @@
display: inline-block;
height: 100%;
animation: loading 1.5s infinite ease-in-out both;
background-color: var(--colors-medium-light);
background-color: var(--color-gray-500);
}
@keyframes loading {

View File

@ -29,7 +29,7 @@ const MenuItem = ({ text, href, icon, current, className, ...rest }: MenuItemPro
aria-label={text}
data-current={current || undefined}
className={cn(
"text-medium-dark hover:border-kinda-light -mb-[0.2em] inline-flex items-center p-2.5 hover:border-b-[0.2em] hover:no-underline",
"-mb-[0.2em] inline-flex items-center p-2.5 text-gray-700 hover:border-b-[0.2em] hover:border-gray-300 hover:no-underline",
current && "border-link/40 hover:border-link/40 border-b-[0.2em]",
className
)}

View File

@ -11,7 +11,7 @@ const PageTitle = ({ canonical, className, children, ...rest }: PageTitleProps)
<h1 className={cn("mt-1 mb-6 text-left text-3xl font-medium lowercase", className)} {...rest}>
<Link
href={canonical}
className="before:text-medium-light before:mr-[-0.1em] before:tracking-widest before:content-['\002E\002F']"
className="before:mr-[-0.1em] before:tracking-widest before:text-gray-500 before:content-['\002E\002F'] hover:no-underline"
>
{children}
</Link>

View File

@ -22,8 +22,8 @@
width: auto;
height: auto;
clip: auto;
background: var(--colors-super-duper-light);
color: var(--colors-link);
border: 2px solid var(--colors-kinda-light);
background: var(--color-gray-100);
color: var(--color-link);
border: 2px solid var(--color-gray-300);
text-decoration: underline;
}

View File

@ -34,7 +34,7 @@ I've written a simple implementation below, which...
<iframe
src="https://jakejarvis.github.io/dark-mode-example/"
title="Dark Mode Example"
style={{ height: "190px", width: "100%", border: "1px solid var(--colors-kinda-light)" }}
style={{ height: "190px", width: "100%", border: "1px solid var(--color-gray-300)" }}
></iframe>
A _very_ barebones example is embedded above ([view the source here](https://github.com/jakejarvis/dark-mode-example), or [open in a new window](https://jakejarvis.github.io/dark-mode-example/) if your browser is blocking the frame) and you can try it out on this site by clicking the 💡 lightbulb in the upper right corner of this page. You'll notice that the dark theme sticks when refreshing this page, navigating between other pages, or if you were to return to this example weeks from now.