Introducing Ephemeral Pages Action v1
Ephemeral Pages Action publishes a self-contained HTML document from a pull-request workflow and posts the temporary link back as a pull-request comment. Version 1.0.0 is now available.
My thoughts, ideas, experiences, and ramblings about code, life, and the open web
Ephemeral Pages Action publishes a self-contained HTML document from a pull-request workflow and posts the temporary link back as a pull-request comment. Version 1.0.0 is now available.
A release is a product workflow. It has users, interfaces, failure states and recovery semantics. Automating eighteen packages onto trusted publishing took four prereleases to get right.
We do. We care about it differently. The attention that used to go into reading the code now goes into the specification, and into the deterministic checks that make non-deterministic tools dependable.
In 2012, EXIF orientation handling varied wildly across browsers and web services. The image orientation CSS specification has since standardized how browsers honor that data by default, but there are still edge cases that bite.
Throwing some confetti while exploring the CSS random() function through its specification and its current implementations, finding both the beauty and the pitfalls along the way.
Search the web-features catalog, preview the baseline-status component, and generate the CDN or bundler snippet, all from one small web app.
It's been a while since I have listened to a talk and found a real connection with the speaker and what they were sharing. This streak was broken a couple of days ago when I listened to a talk by Ryo Lu at Cursor's Compile 26 conference.
Node.js now ships with util.styleText(), a built-in alternative to chalk for terminal text styling. Here is what it can do, when it is enough, and when you might still reach for a dependency.
Unicode character class escapes turn regular expressions from English-only ASCII tools into something that understands the whole of human writing. A look at how `\p{L}`, `\p{N}`, `\p{Sc}`, and the `v` flag's properties of strings make this possible.
Project Calavera is a CLI tool that scaffolds linters, formatters, AI tooling, and common project infrastructure for web projects. Calavera ❤️ Vite. This post walks through the full contribution path for a new integration, using the Varlock PR as a concrete example.
A practical guide to thinking about what to test and why, using Vitest as my tool of choice. Covers the happy path, conditionals, purity, and the limits of code coverage as a measure of test quality.
css-expect enables you to write unit tests for your CSS @functions using the browser engine itself as the source of truth.
CSS now has user-defined functions. No preprocessor, no JavaScript, but native @function with typed parameters, local variables, and conditional logic built right into your CSS.
CSS @property has been Baseline for almost two years, but most existing projects still do not use it. A small experiment in the CSS Property Type Validator generates a reviewable first draft of @property registrations from the custom properties you already have.
The first beta of the Stylelint plugin for CSS Property Type Validator brings typed custom property validation directly into your existing CSS linting workflow.
How to use Supabase Realtime and Web Sockets to live-update page content in a single-page app.
A Playwright reporter paired with a dependency-free viewer that turns axe accessibility results into one report your team can actually read, share, and act on.
A walkthrough of the security vulnerabilities flagged by an AI agent skill review of Ephemeral Pages, and the mitigations put in place as a result.
A carousel overlay bug led me to a deep dive into fluid typography, container queries, and understanding clamp().
TypeScript's structural typing means two types with the same shape are interchangeable, but sometimes this is not what you want. Branded types fix that by adding a phantom property the compiler tracks, but that vanishes at runtime. 👻
A new editor extension that validates your CSS @property registrations and catches incompatible var() usage as you type.
I pointed the skills autoresearch harness at a real frontend security project. It cost roughly four dollars, failed before completing a full improvement loop, and taught me more than any of the earlier test runs combined.
A small local web app for reviewing AI-generated coding plans with inline comments, anchored feedback, and structured JSON output, bringing the pull request review experience to plan mode.
An update on the CSS Property Type Validator, focusing on recent improvements that make it better suited to practical, real-world CSS development workflows.
When you cannot inline an SVG or use it as a mask-image, a combination of the ends-with attribute selector and filter: invert() offers a clean, CSS-only solution for adapting icon colours across themes.
A deep dive into Blue Earth, an experiment that plots positive climate news stories on a rotating 3D globe using the HTML in Canvas API, Three.js, and a build-time pipeline powered by Claude and Geoapify.
A light-DOM custom element for CSS masonry layouts that uses display: grid-lanes when available and falls back to a spec-aligned JavaScript placement engine. Version 0.1.0 is ready for real projects.
The CSS property type validator now catches type mismatches at the point of assignment, not just at var() usage.
Learn how to configure Git to push your code to both GitHub and Codeberg with a single command, including SSH key setup and a handy shell alias for branch-specific control.
TypeScript 6.0 enables noUncheckedSideEffectImports by default, which causes a TS2882 error for CSS side-effect imports like import './style.css'. Here is what changed, why, and how to fix it.
What started as a question about a free macOS image viewer turned into a deep dive into pan and zoom math, pointer events, WheelEvent quirks, and a TypeScript web component. Here is everything we learned along the way.
The CSS Media Pseudo Classes Polyfill is now available on npm. This post covers what shipped, what I learned about the CSSOM and unsupported CSS, how you can try it, and what comes next.
CSS @property gives authors a type contract for custom properties, but no tooling enforces it at the consumption site. CSS Property Type Validator is an attempt to close this gap.
A layout that seems impossible; aligning titles and dividers across sibling cards regardless of content length. No JavaScript, no table layouts, just CSS subgrid.
A real-world exploration of how choosing the right HTML elements for interview transcripts solves both semantic and styling challenges in one cascading swoop.
What happens when you try to implement two seemingly straightforward CSS features as a JavaScript polyfill? You discover that specifications are simple because they made hard decisions, and the complexity does not disappear; it just moves.
How the new Set methods difference() and symmetricDifference() can replace verbose Set comparisons with clear, expressive code.
Timelapse is a progressive web app (PWA) with acollection of widgets that shows how much time has elapsed in the day, week, month, quarter, and year. Widgets and timezone are configurable.
How I built an eval-judge-improve loop to autonomously refine a semantic HTML agent skill, taking it from 2.46 to 2.89 out of 3.0 across four iterations and what I learned about the limits of automated improvement.
The CSS contrast-color() function lets the browser pick the most readable text colour for any background. Here is what it does, how it works, and why it matters for accessibility and the web.
How I structure prompts for AI coding agents to get considered implementation plans instead of premature code.
How combining JSDoc annotations with Object.freeze gives you literal type inference, runtime immutability, and better IDE support for JavaScript constant objects.
How I replaced my local .env file with Varlock and 1Password, gaining type safety, validation, secret scanning, and a single source of truth for environment variables.
Working with temporary directories in Node.js just became cleaner and more intentional with mkdtempDisposable and explicit resource management.
How to write a single hook script that works across Claude Code and Cursor, giving you deterministic control over agent behaviour when it matters most.
Working code isn't understood code. When AI-generated code feels hard to parse, that's a signal to ask questions, and sometimes, the answer leads to something better.
Take a fieldset, pour some radio buttons and visually hidden labels into it, wrap it in scroll-snap, and you have a clean, semantic horizontal scroller on mobile. What could go wrong? Well... there is nuance we need to talk about.
A practical walkthrough for when you realise your feature branch was created from the wrong base, covering git log, merge parents, cherry-pick, and bypassing commit hooks.
Manage anchor relationships with anchor-scope, leverage the Popover API's implicit anchors, and hide positioned elements gracefully with position-visibility.
A deep dive into the JavaScript concepts behind mocking HTMLImageElement behaviour in Vitest, including Object.defineProperty, Object.getOwnPropertyDescriptor, prototype manipulation, and WeakMap for per-instance state tracking.