Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
node_modules
_site
src/css/tokens.css
src/_tokens/
src/_data/tokens.d.ts
3 changes: 3 additions & 0 deletions eleventy.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ export default async function (eleventyConfig) {
eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
widths: [800],
htmlOptions: {
pictureAttributes: {
class: "o-media",
},
imgAttributes: {
loading: "lazy",
decoding: "async",
Expand Down
3,169 changes: 2,744 additions & 425 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"version": "1.0.0",
"description": "My personal blog",
"scripts": {
"start": "eleventy --serve",
"build": "eleventy",
"start": "tz build --watch & eleventy --serve",
"build": "tz build && eleventy",
"new:post": "node scripts/new-post.js"
},
"author": "Robert Rhoades",
Expand All @@ -13,7 +13,10 @@
"@11ty/eleventy": "^3.1.5",
"@11ty/eleventy-img": "^6.0.4",
"@11ty/eleventy-plugin-rss": "^3.0.0",
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.2"
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.2",
"@terrazzo/cli": "^2.1.0",
"@terrazzo/plugin-css": "^2.1.0",
"@terrazzo/plugin-js": "^2.1.0"
},
"devDependencies": {
"@shopify/prettier-plugin-liquid": "^1.10.2",
Expand Down
39 changes: 39 additions & 0 deletions spacing-migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Plan: Spacing Standardization & Token Migration

## Objective
Standardize the design token spacing scale to follow a consistent 1.5x T-shirt progression and migrate all hardcoded SCSS values to use Terrazzo tokens. This will improve maintainability and ensure visual consistency across the site.

## Proposed Spacing Scale
| Token | Value | Change |
| :--- | :--- | :--- |
| `spacing.xs` | `0.25rem` (4px) | **New** (For micro-spacing/internal padding) |
| `spacing.sm` | `0.5rem` (8px) | Unchanged |
| `spacing.md` | `1rem` (16px) | Unchanged |
| `spacing.lg` | `1.5rem` (24px) | Unchanged |
| `spacing.xl` | `2.25rem` (36px) | **New** (Matches current hardcoded content flow) |
| `spacing.xxl` | `3rem` (48px) | **Renamed** (Was `xl`) |

## Key Changes

### 1. Update Design Tokens (`src/tokens.json`)
- Add `xs` (0.25rem).
- Rename `xl` to `xxl`.
- Add `xl` (2.25rem).

### 2. SCSS Migration
- **Refactor `xl` usage:** Update all existing `var(--spacing-xl)` references to `var(--spacing-xxl)` to preserve the 3rem intent.
- **Replace Hardcoded Values:**
- `2.25rem` / `36px` -> `var(--spacing-xl)`.
- `0.625rem` (Header gap) -> `var(--spacing-sm)`.
- `0.1rem` / `0.2rem` (Code padding) -> `var(--spacing-xs)`.
- `1.875rem` (Mobile header margin) -> `var(--spacing-lg)`.
- `3.125rem` (Header margin) -> `var(--spacing-xxl)`.
- **Maintain Gutter Logic:** Ensure the `--article-gutter` variable in `component.article.scss` continues to use the `var(--size-gutter)` token.

## Verification & Testing
- **Visual Regression:** Check the main blog list and article pages to ensure vertical rhythm and gaps are preserved.
- **Token Build:** Run `npm run build` to ensure Terrazzo generates the new CSS variables correctly.

## Exceptions (Intentional Hardcoding)
- `12.5rem` green bar: Remains hardcoded as it is a unique presentational choice.
- `2px` / `1px` borders: Remain hardcoded as they relate to `border` width, not `spacing`.
27 changes: 27 additions & 0 deletions src/_data/tokens.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { resolver } from "../_tokens/index.js";

const tokenSet = resolver.apply({});

const tokens = {};

for (const [id, token] of Object.entries(tokenSet)) {
let value = token.$value;
if (token.$type === "color") {
value = `oklch(${token.$value.components.join(" ")})`;
}

// Split the dotted ID and build the nested object
const parts = id.split(".");
let current = tokens;
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
if (i === parts.length - 1) {
current[part] = value;
} else {
current[part] = current[part] || {};
current = current[part];
}
}
}

export default tokens;
3 changes: 2 additions & 1 deletion src/_includes/meta.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
<meta name="description" content="{{ site.description }}">
<meta property="og:description" content="{{ site.description }}">
{% endif %}
<meta name="theme-color" content="#359567">

<meta name="theme-color" content="{{ tokens.color.bg.accent }}">

<meta property="og:site_name" content="{{ site.title }}">
{% if title %}
Expand Down
9 changes: 8 additions & 1 deletion src/css/index.11ty.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as sass from "sass";
import path from "path";
import fs from "node:fs/promises";

export default class {
async data() {
Expand All @@ -21,7 +22,13 @@ export default class {

async render({ entryFile }) {
try {
return await this.compileSass(entryFile);
// Read the tokens.css
const tokensPath = path.join(import.meta.dirname, "tokens.css");
const tokensCss = await fs.readFile(tokensPath, "utf-8");

const sassCss = await this.compileSass(entryFile);

return tokensCss + "\n" + sassCss;
} catch (error) {
throw error;
}
Expand Down
19 changes: 10 additions & 9 deletions src/scss/base.body.scss
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
html {
// font-size: 112.5%;
font-size: 100%;
background: var(--color-bg-page);
}

body {
background: rgb(248, 246, 241);
// background: $colour-grey;
color: $colour-space-grey;
font-family: $font-family;
container-type: inline-size;

color: var(--color-text-primary);
font-family: var(--font-family);
font-optical-sizing: auto;
font-size: var(--step-0);
line-height: $line-height;
line-height: var(--font-line-height);
font-optical-sizing: auto;
// font-variation-settings: "wdth" 100;
margin: 0 auto;
max-width: $container-width;
max-width: var(--size-container);
text-rendering: optimizeLegibility;
word-wrap: break-word;

&::before {
background: $colour-green;
background: var(--color-bg-accent);
content: "";
height: 12.5rem;
left: 0;
Expand All @@ -31,7 +32,7 @@ body {
}

::selection {
background: $colour-grey;
color: $colour-space-grey-dark;
background: var(--color-bg-page);
color: var(--color-text-heading);
text-shadow: none;
}
4 changes: 2 additions & 2 deletions src/scss/base.heading.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ h4,
h5 {
text-wrap: balance;
line-height: 1.15;
margin-top: 3rem;
margin-bottom: 1rem;
margin-top: var(--spacing-xl);
margin-bottom: var(--spacing-md);
word-break: break-word;
hyphens: auto;
}
Expand Down
4 changes: 2 additions & 2 deletions src/scss/base.link.scss
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
a {
color: $colour-space-grey-dark;
color: var(--color-text-heading);
text-decoration: none;

&:hover,
&:focus {
color: $colour-space-grey-light;
color: var(--color-text-secondary);
}
}
6 changes: 3 additions & 3 deletions src/scss/base.quotation.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
blockquote {
border-left: 3px solid $colour-space-grey-light;
padding-left: 1rem;
border-left: 3px solid var(--color-border-subtle);
padding-left: var(--spacing-md);

cite {
color: $colour-space-grey-light;
color: var(--color-text-secondary);
}
}
8 changes: 4 additions & 4 deletions src/scss/base.table.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ td {
}

thead th {
background-color: $colour-grey;
color: $colour-space-grey;
background-color: var(--color-bg-page);
color: var(--color-text-primary);
font-weight: bold;
}

// Zebra-striping (alternating row colors) for readability
tbody tr:nth-child(even) {
background-color: lighten($colour-grey, 20%);
background-color: var(--color-bg-subtle);
}

// Highlight rows that are currently hovered
tbody tr:hover {
background-color: #eee;
background-color: var(--color-bg-subtle);
transition: background-color 0.3s ease;
}
6 changes: 3 additions & 3 deletions src/scss/component.article-list.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
.c-article-list__summary {
display: block;
font-style: italic;
color: $colour-space-grey-light;
color: var(--color-text-secondary);
margin-top: 0.25rem;
font-size: 0.9rem;
}
Expand All @@ -19,10 +19,10 @@
flex: 0 0 auto;
font-size: 0.8em;
margin: 0;
color: $colour-space-grey-light;
color: var(--color-text-secondary);
}

@media (max-width: 600px) {
@container (max-width: 500px) {
.c-article-list__date {
display: none;
}
Expand Down
32 changes: 16 additions & 16 deletions src/scss/component.article.scss
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
.c-article {
background: $colour-cream;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
padding: 3rem $article-gutter 1.5rem;
--article-gutter: calc(var(--size-gutter) / 2);

background: var(--color-bg-surface);
box-shadow: var(--shadow-card);
padding: var(--spacing-xl) var(--article-gutter) var(--spacing-lg);

h1 {
margin-top: 1rem;
margin-top: var(--spacing-md);
margin-bottom: 2.25rem;
}

&__footer {
text-align: right;
margin-top: 3rem;
margin-top: var(--spacing-xl);
}

a:not(.u-link-default) {
background: $colour-green-light;
color: $colour-green-dark;
background: var(--color-bg-accent-subtle);
color: var(--color-text-accent);
font-size: 0.8em;
font-weight: bold;
padding: 2px 4px;

&:hover,
&:focus {
box-shadow: 2px 2px 0 $colour-green;
color: $colour-green;
box-shadow: var(--shadow-accent);
color: var(--color-bg-accent);
}
}

picture {
@extend %o-media;
display: flex;
justify-content: center;
background: $colour-grey;
background: var(--color-bg-page);

img {
max-width: 100%;
Expand All @@ -41,9 +41,9 @@
}
}

@media screen and (max-width: $container-width) {
border-radius: 0;
padding-left: $article-gutter-mobile;
padding-right: $article-gutter-mobile;
@container (min-width: #{$container-width}) {
--article-gutter: var(--size-gutter);

border-radius: var(--radius-md);
}
}
4 changes: 2 additions & 2 deletions src/scss/component.footer.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
text-transform: uppercase;

&::before {
color: $colour-space-grey;
color: var(--color-text-primary);
content: attr(title);
position: absolute;
transition:
Expand All @@ -20,7 +20,7 @@

&:hover,
&:focus {
color: $colour-cream;
color: var(--color-text-inverse);

&::before {
opacity: 0;
Expand Down
8 changes: 4 additions & 4 deletions src/scss/component.header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
display: flex;
flex-flow: row wrap;
grid-gap: 0.625rem;
margin: 3.125rem;
margin: 1.875rem;
place-content: center space-between;

@media screen and (max-width: $container-width) {
margin: 1.875rem;
@container (min-width: #{$container-width}) {
margin: 3.125rem;
}

&__logo {
svg {
display: block;
fill: $colour-cream;
fill: var(--color-icon-inverse);
width: 2.1875rem;
}

Expand Down
8 changes: 4 additions & 4 deletions src/scss/component.media.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.c-media {
align-items: center;
background-color: $colour-green-light;
background-color: var(--color-bg-accent-subtle);
background-size: cover;
display: flex;
justify-content: center;
Expand All @@ -13,7 +13,7 @@
}

&__play {
fill: $colour-green;
fill: var(--color-icon-primary);
width: 3.125rem;

&--thumbnail {
Expand All @@ -23,10 +23,10 @@
}

&:hover .c-media__play {
fill: $colour-green-dark;
fill: var(--color-icon-secondary);

&--thumbnail {
fill: $colour-cream;
fill: var(--color-icon-inverse);
}
}

Expand Down
Loading