About this site
A minimal, fast, fully static site focused on readability, performance, and maintainability.
Goals
- Ship static HTML for instant loads and reliable hosting
- Keep JS to zero for robustness and accessibility
- Use components for reuse, consistency, and easy iteration
The journey
I started with handwritten HTML and a lightweight CSS framework. As content grew, copy‑pasting layouts and keeping design consistent became a tax on iteration.
Moving to a component model solved that: I could compose pages from small, reusable pieces and keep typography and spacing consistent without fighting the markup.
I work daily with .NET across apps, services, and websites, so building with a familiar stack made sense—as long as it could stay static.
Static generation
The site is pre-rendered to static HTML at build time. That delivers:
- Fast first paint and predictable SEO
- Simple, cache‑friendly hosting on a CDN
- No client bootstrapping or runtime dependencies
Build pipeline
Every commit triggers a build that generates the static site and publishes it to the host. The process is fast, reproducible, and easy to roll back.
Shiki failed: 122 | brackets: 0,
123 | doubleApostrophe: 0,
124 | singleApostrophe: 0
125 | };
126 | const name = this.scope.nodeType === NodeTypeEnum.documentNode ? 'Document' : 'Element';
127 | const error = new this.window.SyntaxError(`Failed to execute 'querySelectorAll' on '${name}': '${selector}' is not a valid selector.`);
^
TypeError: undefined is not a constructor (evaluating 'new this.window.SyntaxError(`Failed to execute 'querySelectorAll' on '${name}': '${selector}' is not a valid selector.`)')
at getSelectorGroups (/home/runner/work/personal-site/personal-site/node_modules/happy-dom/lib/query-selector/SelectorParser.js:127:23)
at querySelector (/home/runner/work/personal-site/personal-site/node_modules/happy-dom/lib/query-selector/QuerySelector.js:130:67)
at main (/home/runner/work/personal-site/personal-site/tools/shiki-render.ts:72:28)
Code presentation
Code snippets are rendered at build time for zero‑JS syntax highlighting and consistent theming. A small component runs a CLI highlighter during the build and inlines the result into the page.
Shiki failed: 122 | brackets: 0,
123 | doubleApostrophe: 0,
124 | singleApostrophe: 0
125 | };
126 | const name = this.scope.nodeType === NodeTypeEnum.documentNode ? 'Document' : 'Element';
127 | const error = new this.window.SyntaxError(`Failed to execute 'querySelectorAll' on '${name}': '${selector}' is not a valid selector.`);
^
TypeError: undefined is not a constructor (evaluating 'new this.window.SyntaxError(`Failed to execute 'querySelectorAll' on '${name}': '${selector}' is not a valid selector.`)')
at getSelectorGroups (/home/runner/work/personal-site/personal-site/node_modules/happy-dom/lib/query-selector/SelectorParser.js:127:23)
at querySelector (/home/runner/work/personal-site/personal-site/node_modules/happy-dom/lib/query-selector/QuerySelector.js:130:67)
at main (/home/runner/work/personal-site/personal-site/tools/shiki-render.ts:72:28)
What this enables
Performance
Minimal payloads, static HTML, and aggressive caching keep pages snappy on any connection.
Maintainability
Components centralize layout and styling so content stays the focus.