2025 site updates
tjheffner
2025-07-05
tl;dr: I ripped out tailwind, updated to svelte 5 everywhere, pruned the dependency list, fixed some bugs, and gave the site a little facelift.
I originally chose to use tailwind because I had never used it at work and wanted to give it a fair shake. Three years later I think that I have. I don’t want to use it on this site any longer. It’s a perfectly fine framework, and probably has a lot of uses on professional teams that don’t have strong css skills… but seeing as how I don’t use it in my day job, having to regularly look up the classes every time made working on this site feel like more of a burden than anything else. And that’s against my entire goal! This site should be as frictionless as possible for me.
So, I ripped out probably 90% of my existing stylesheets and associated markup and redesigned the site from the ground up. New tokens, a new type scale, and modern css features. With ~60 lines of css, I have the foundations for my entire site.
Here is that foundation:
/* set up global css vars & fonts */
:root {
--c-accent: oklch(57.057% 0.21474 14.568);
--c-accent-brighter: oklch(from var(--c-accent) l c h / calc(alpha - 0.75));
--c-secondary: oklch(48.821% 0.21724 264.392);
--c-secondary-brighter: oklch(from var(--c-secondary) l c h / calc(alpha - 0.75));
--c-text: oklch(27.9% 0.041 260.031);
--c-background: oklch(96.8% 0.007 247.896);
--density: .4rem; /* ~10pt grid */
accent-color: var(--c-accent);
}
@font-face {
font-family: 'Merriweather';
font-style: normal;
font-weight: normal;
src: url('$lib/font/Merriweather-Bold.ttf') format('truetype');
}
@font-face {
font-family: 'Mulish';
font-style: normal;
font-weight: normal;
src: url('$lib/font/Mulish-Regular.ttf') format('truetype');
}
/* https://www.joshwcomeau.com/css/custom-css-reset/ */
*,
*::before,
*::after {
box-sizing: border-box;
}
* {
margin: 0;
}
@media (prefers-reduced-motion: no-preference) {
html {
interpolate-size: allow-keywords;
}
}
body {
line-height: 1.5;
-webkit-font-smoothing: antialiased;
background-color: var(--c-background);
font-family: 'Mulish', sans-serif;
}
img, picture, video, canvas, svg {
display: block;
max-width: 100%;
}
input, button, textarea, select {
font: inherit;
}
p, h1, h2, h3, h4, h5, h6 {
overflow-wrap: break-word;
color: var(--c-text);
}
p {
text-wrap: pretty;
}
h1, h2, h3, h4, h5, h6 {
text-wrap: balance;
font-family: 'Merriweather', serif;
}
#root, #__next {
isolation: isolate;
}
/* https://complementary.space/ */
body {
--space-near: calc(var(--density) * 5);
--space-away: calc(var(--density) * 10);
}
body [data-density-shift] {
--space-near: calc(var(--density) * 2);
--space-away: calc(var(--density) * 5);
}
body [data-density-shift] [data-density-shift] {
--space-near: calc(var(--density) * 1);
--space-away: calc(var(--density) * 2);
}
/* type scale */
h1, .h1 {
font-size: 2.75em;
line-height: 1.1;
margin-bottom: var(--space-away);
}
h2, .h2 {
font-size: 1.6583em;
}
h3, .h3 {
font-size: 1.401em;
}
small, .small {
font-size: 0.8448em;
display: block;
margin-bottom: var(--space-near);
}
html {
font-size: clamp(1em, 0.8333vw + 0.775em, 1.25em);
}
All of that boils down to:
- 9 total css variables (6 colors, using the modern oklch color space) and two self hosted fonts
- Josh Comeau’s modern CSS reset
- 3 levels of information density to control spacing between elements.
- A responsive type scale based on
em
I cannot recommend https://complementary.space enough, it’s a lovely paradigm to work with and very flexible. Juggling var(--space-near)
and var(--space-away)
for 99% of margins and paddings reduced so much mental overhead.
With the foundations in place, I could refactor any other individual components as needed. And boy, did they need it. A lot of cobwebs had crept into my codebase over three years, plus I had to clean all the tailwind class cruft out.
Svelte 5 runes are great. Svelte continues to be my favorite framework to work with, it’s just so intuitive. I moved the majority of files from .js
to .ts
, plus anything with .svelte
is now typescript as well. yay! Much of the refactor was moving syntax from Svelte 4 to 5.
I cleaned up my metatag strategy, updated my OG images, fixed my playwright tests, and tried to make things feel a bit smoother everywhere. I’ll make additional posts for those soon. Next tasks for the site will be refreshing the favicon and other image assets, but first I need to focus on some yard work. 😅
Refactor stats:
Repo Languages (Before):
Repo Languages (After):