CSS is Awesome

the sketchbook

Notes from the margins.

Three drawers: how the system gets built, the new CSS found along the way, and where AI meets stylesheets. New posts when there's something worth saying.

CSS Is Awesome

Post-mortems and build stories from the repo — published only after the fix ships.

engineering9 min

Seven changes, and two of them were bugs I had shipped

A research handoff proposed seven changes to cia. All seven claims were true, including two live bugs. Here is what changed, what it does to your CSS, and the one number I refused to copy.

  • css
  • anchor-positioning
  • accessibility
  • transitions
  • grid
  • api-design

engineering6 min

The MCP command that ran someone else's file

A dedicated zero-install MCP package, a same-named bin in two packages, and a test suite that stayed green while the real command ran the wrong file.

  • mcp
  • ai
  • tooling
  • npm
  • developer-experience

engineering6 min

A coverage sprint

Six epics landed in two days — RTL, form validation, an analyzer health report, token intelligence in the editor, and two more recipes. The interesting part isn't the count. It's the three real bugs each pass caught in something already shipped.

  • recipes
  • accessibility
  • forms
  • rtl
  • design-tokens
  • developer-tools

engineering4 min

Print is a theme now

cia's print colour was done three ways at once — a forced light scheme, a "legible" patch for dark themes, and a docs site that hardcoded black-on-white anyway. Collapsing them into four tokens turned print into just another themeable surface.

  • css
  • print
  • theming
  • design-tokens
  • design-systems

engineering5 min

Two new analyzer rules (and one we'd already shipped)

cia analyze grew a rule that suggests the nearest scale token for a hard-coded length, and a heuristic that flags interactive styling with no visible focus state. Writing the docs page for both turned up a third rule that had shipped months ago without anyone updating the roadmap to say so.

  • cli
  • developer-tools
  • accessibility
  • design-systems
  • design-tokens

engineering4 min

The print-hidden column that wasn't

Building a "print this invoice" example, I hid the sidebar for print and expected the invoice to take the page. It took a third of it. The sidebar was gone — its grid column wasn't. A short note on the print refinements that shook out of one example.

  • css
  • print
  • grid
  • layout
  • debugging

engineering6 min

Printing a design system

cia's pages turn into real printed documents — cover, table index, numbered sheets, followable links — with zero JavaScript and no PDF library. The generator was in the browser the whole time; we only had to ship the styling layer, and each honest-looking feature hid a smaller, sharper bug than we expected.

  • css
  • print
  • pdf
  • page-breaks
  • design-system

engineering4 min

The tabs that highlighted but never switched

A zero-JS tabs component shipped with a one-element off-by-one that CSS can't even express a fix for — and the only reason we found it was converting the docs to live demos. A post-mortem, plus everything else that changed in one very long day.

  • css
  • post-mortem
  • mobile
  • layout
  • design-system

engineering5 min

The import in our README did not work

Sass does not read package.json exports. Both documented imports failed on a clean install, and every check we had stayed green.

  • sass
  • packaging
  • npm
  • post-mortem
  • testing

architecture7 min

A barrel that emits nothing

Next.js CSS Modules reject a top-level :root, so cia's authoring entry point had to print zero bytes until a mixin is called. Here is how, and what it cost.

  • sass
  • scss
  • css-modules
  • nextjs
  • api-design

engineering8 min

An MCP server for a CSS library

Agents guess at mixin signatures because prose docs give them nothing to query. cia ships a stdio MCP server that reads the SCSS instead. What broke along the way.

  • mcp
  • ai
  • tooling
  • developer-experience

engineering8 min

From 0.8 to 1.0

We cut 1.0 on 2026-08-17 with 24 of 42 planned stories done and an entire epic unstarted. Here is the reasoning, and what actually changed.

  • release
  • semver
  • versioning

technique8 min

Print to PDF with zero JavaScript

The browser already ships a PDF generator. cia's print layer is four mixins, three CSS variables, and no JavaScript at all.

  • print
  • pdf
  • css
  • zero-js

architecture6 min

Recipes, not components

cia ships markdown patterns instead of a component library. Here is what that buys you, and the bug fix you give up to get it.

  • recipes
  • accessibility
  • architecture
  • zero-js

engineering7 min

The validator that wasn't looking

Seven themes scored 0 of 17 contrast pairs and the validator still printed a green check. A post-mortem on 119 silent skips and the parser that caused them.

  • accessibility
  • testing
  • post-mortem
  • css

technique6 min

Your brand comes with you

npx cia migrate reads your Tailwind config or Bootstrap variables and writes a cia theme.scss, with a confidence rating on every token it maps.

  • migration
  • tailwind
  • bootstrap
  • cli

CSS

New and cool CSS from the platform's edge — the discovery is the star; cia is the sponsor.

discovery4 min

CSS anchor positioning is a dropdown engine

anchor-name, three inset lines, and position-try-fallbacks replace the positioning half of a dropdown library — trigger-width menus that flip above the trigger when the viewport would clip them, re-evaluated by the browser on every open.

  • css
  • anchor-positioning
  • popover
  • layout
  • progressive-enhancement

discovery4 min

The popover attribute's invisible UA stylesheet

Half of what makes [popover] work is user-agent CSS you can silently destroy with one innocent declaration. Three ways we broke it — a permanently open menu, a menu that refused to be full-width, and the inset trick that un-centers the overlay.

  • css
  • popover
  • cascade
  • ua-styles
  • debugging

discovery4 min

There is no :nth-of-class, and it will bite you

nth-of-type counts element types, not classes — and the selector everyone assumes exists, :nth-of-class, never has. How one same-type sibling shifts every index by one, why the bug looks wired while being broken, and the modern selector that finally fixes it.

  • css
  • selectors
  • nth-of-type
  • nth-child
  • debugging

AI

Where AI meets CSS — agents, MCP, and what machines do with stylesheets.

ai7 min

What the AI got wrong, and what I built to catch it

Four times AI-assisted work on this design system produced something confidently wrong, how each one was caught, and the checks that now exist because of them. Not a productivity post.

  • ai
  • verification
  • ci
  • process
  • code-review
Theme