{"slug": "you-should-skill-it-solving-a-year-old-css-bottleneck-with-an-ai-skill", "title": "You Should Skill It: Solving a Year-Old CSS Bottleneck With an AI Skill", "summary": "Senior Product Engineer at epilot, an energy industry SaaS company, built an AI-powered Custom CSS assistant to solve a year-old bottleneck in the company's Journey product. The tool, initially shelved as a proof-of-concept, generates CSS snippets using the company's internal Generative AI engine and design token library, replacing the need for engineering time spent on one-off styling requests. The solution addresses a gap where customers struggled to use the existing Custom CSS documentation for styling multi-step forms.", "body_md": "There's a certain kind of problem that lives rent-free in your head for months. Not urgent enough to drop everything for, but annoying enough that you never quite let it go. This is the story of one of those, and how an AI skill finally gave me the right-sized solution.\n\nI'm a Senior Product Engineer at [epilot](https://www.epilot.cloud/en), a vertical SaaS company built for the energy industry, mostly utilities, municipal suppliers, and grid operators across the DACH region. The core of what we do is what we call an Energy XRM, a 360 platform that handles the relational side of running a utility: sales, service, products, partners, customer portals, regulatory workflows, all in one place. It's built specifically for the messy reality of the energy industry, where a single customer might be enrolling in a tariff, configuring a heat pump, and submitting paperwork to a grid operator in the same week.\n\nOne of our most-used products is called Journeys - a no-code, multi-step form that our users share with their end-customers or embed on their websites to onboard customers, qualify leads, and sell products. If you've ever signed up for an electricity tariff online in Germany, there's a decent chance you walked through an epilot Journey without knowing it. I work on the team that maintains the Journey product.\n\nA while back I led the redesign of the Journeys design system and component library as part of a much bigger migration away from Material UI. We called the new system Concorde. It's our internal React component library, built around CSS variables and design tokens instead of a tightly coupled JSON theming object, which gave us a lot more flexibility for theming, dark mode, and customer-specific styling. I wrote a bit about that migration last year ([Building a scalable React component library: lessons from Concorde Elements](https://dev.to/epilot/building-a-scalable-react-component-library-lessons-from-concorde-elements-kdi)).\n\nAs part of that work I shipped a feature called Custom CSS. The pitch was simple: let customers style their Journeys as far as their imagination goes. Pill-shaped CTAs on certain steps? Override the discount color on a product tile? Pair light and dark mode tokens to match a brand palette? Custom CSS lets you do all of that. Underneath it sits the full Concorde token library plus a catalog of maintained class names (things like `.Concorde-Button__Primary`\n\nor `.Concorde-SingleChoice-Image-Block`\n\n) that survive deploys.\n\nIt was powerful. And that's where the problem started.\n\nPowerful developer tools are only useful if you can actually use them. Custom CSS is, at the end of the day, just CSS. A lot of our customers would check our [Custom CSS documentation](https://docs.epilot.io/docs/journeys/custom-css/), which had a lot of examples, and figure it out themselves. However, others just skipped over it and reach out. The documentation has a lot of examples, but it couldn't cover all the possible use cases or questions that would come up.\n\nSo when someone wanted to change a hover state, soften a border, or restyle a specific block on step three of an onboarding flow, they did the natural thing: they asked Customer Success, Product Managers, Project teams etc. Whomever would then forward it to my team, mostly me, and a quietly growing slice of my engineering time was being spent on one-off CSS snippets.\n\nI saw this problem coming though. About a year ago I built a proof-of-concept: a standalone AI Custom CSS assistant. You'd type what you wanted, it would generate the CSS, referencing the right tokens and selectors, the right Concorde classes. It was built using our internal Generative AI engine and contained enough context for any Large Language Model (LLM) to generate the styles required.\n\nIt worked, but I shelved it anyway. It just felt disproportionate. Shipping a standalone AI assistant meant maintaining it, a UI, observability, model costs, the whole thing. For a problem that wasn't a pressing need, it felt like overkill. I parked it and went back to other priorities.\n\nFast forward to this year. If you've been near the AI space at all, you've probably noticed that skills (sometimes called tools or actions, depending on the ecosystem) have become real. Instead of a general-purpose chatbot reasoning from memory, a skill points the model at specific knowledge and specific instructions for a specific task. It loads only when the user's request actually matches the skill's description, which keeps the model's context lean and the answers focused. Think of it less as a chatbot and more like a specialist you've fully briefed before a meeting.\n\nThe magic isn't the model. It's the framing. A well-written skill knows what it knows, knows what it doesn't, and applies that scoped knowledge reliably every time.\n\nWith the adoption of Claude company-wide, there was also the creation of skills for different purposes.\n\nThe spark for the skill itself came from Wilian, a Product Designer on my team. He put together the first draft in response to a new Custom CSS snippet. Great starting point.\n\nTo make it bulletproof I needed to layer in the engineering context. I'd built the Concorde architecture from the ground up, so I knew where the edge cases lived: which selectors are safe to target, which HTML IDs are journey-specific and shouldn't be hard-coded, why `display: none`\n\nis blocked (we strip it to protect accessibility), why the mobile sticky CTA reads `--concorde-primary-color`\n\ndirectly instead of the button background token, how the light and dark mode tokens cascade through the component tree. I took the draft and grew it into something a non-engineer could actually rely on day-to-day.\n\nThe skill now does four things:\n\n`.Concorde-*`\n\nclass names (around 46 components and 50 blocks).There were a few technical wrinkles along the way (a browser-MCP integration that turned out to be flakier than we hoped, so we ended up using a headless-browser approach to inspect the live DOM), but those are a story for another post. The skill itself just works.\n\nThe skill was distributed to everyone's Claude account by the IT team.\n\nA customer asks Customer Success: \"*Can we make the buttons round on this journey, but not the toggle group?*\"\n\nCS drops it into Claude. The skill comes back with:\n\n```\n.Concorde-Button:not(.Concorde-ToggleButton) {\n  border-radius: 999px;\n}\n```\n\nPlus a one-line comment explaining why the toggle group is excluded (it has its own pill shape and would double-style). No engineering escalation, a production-ready snippet.\n\nThat round trip used to bounce between teams. Now it takes one paste.\n\nThe interesting shift isn't that AI tools got more useful. It's that they got more specific. A general AI assistant that vaguely knows CSS is not as valuable as a skill that deeply knows *your* CSS system, your tokens, your conventions, and your docs. The model is the same. The framing is what makes it useful.\n\nA year ago, the right answer to this problem looked like a separate product. This year, it's a Markdown file. That gap, same payload and two very different shipping costs, is the actual lesson in product thinking leading to time saved.\n\nIf you have documentation, an internal process, or a slice of engineering know-how that currently lives in a handful of people's heads, it might be worth asking the same question I asked: *could this just be a skill?*\n\nNot every problem needs an app. Sometimes it needs the right context, pointed at the right model, with the right guardrails. The result can quietly take hours of work off the team every week and free you up to work on the things only you can actually do.\n\nThat's what this build did for me. Honestly, one of the more satisfying things I've shipped this year.\n\nPhoto by [Julio Rionaldo](https://unsplash.com/@juliorionaldo?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash](https://unsplash.com/photos/person-playing-violin-xIoze9dH4WI?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)", "url": "https://wpnews.pro/news/you-should-skill-it-solving-a-year-old-css-bottleneck-with-an-ai-skill", "canonical_source": "https://dev.to/epilot/you-should-skill-it-solving-a-year-old-css-bottleneck-with-an-ai-skill-2ioa", "published_at": "2026-05-30 08:25:22+00:00", "updated_at": "2026-05-30 08:41:05.522345+00:00", "lang": "en", "topics": ["ai-products", "ai-tools"], "entities": ["epilot", "Journeys", "Material UI", "Concor"], "alternates": {"html": "https://wpnews.pro/news/you-should-skill-it-solving-a-year-old-css-bottleneck-with-an-ai-skill", "markdown": "https://wpnews.pro/news/you-should-skill-it-solving-a-year-old-css-bottleneck-with-an-ai-skill.md", "text": "https://wpnews.pro/news/you-should-skill-it-solving-a-year-old-css-bottleneck-with-an-ai-skill.txt", "jsonld": "https://wpnews.pro/news/you-should-skill-it-solving-a-year-old-css-bottleneck-with-an-ai-skill.jsonld"}}