Frequently asked questions
Short answers to the questions people actually ask — philosophy, theming, integration, versioning, and how to get involved.
Why not just use Tailwind?
Tailwind and css-is-awesome optimise for different things. Tailwind ships atomic utilities you compose in markup; the tokens live in a config you recompile. cia ships tokens + mixins: the design language is a small set of CSS custom properties, and the primary API is SCSS mixins you compose in stylesheets. That means you get runtime re-skinning via one data-theme attribute and semantic class names instead of a utility stack.
The tradeoff: Tailwind's atomic classes don't re-skin at runtime, and the markup carries every design decision. cia's mixins keep markup semantic but require SCSS at author time. Neither is a knock on the other — pick based on whether your project wants its design system in HTML or in CSS. See /docs/migration-tailwind for a deeper comparison.
Why not just use Bootstrap?
Bootstrap is component-first: you get .btn, .card, .alert, and a Sass variable layer beneath them. css-is-awesome is token-first: components are assembled from the same token vocabulary, and theming is a single attribute swap instead of a Sass recompile.
If you already live in Bootstrap and just want a reskin, a Sass override works fine. If you want the design language to be the primitive and components to fall out of it, cia is the smaller, flatter system. See /docs/migration-bootstrap for side-by-side equivalents.
Why SCSS over Tailwind / plain CSS / CSS Modules?
SCSS gives us mixins, which are the primary API. Plain CSS custom properties alone aren't composable — you can't @include button(primary) in vanilla CSS. Tailwind is atomic — the composition unit is a class in markup, not a mixin in a stylesheet. CSS Modules scope styles per file but give you no vocabulary to compose across files.
SCSS plus tokens plus mixins is the durable combination: tokens are the runtime contract, mixins are the authoring contract. The React layer uses CSS Modules on top for component-scoped styles, so you get file-local scoping and a system-wide vocabulary at the same time.
What does "mixin-first" mean exactly?
It means the recommended way to style a thing is @include m.button(primary), not class="btn btn-primary" in markup. You compose styles semantically in SCSS instead of stacking utility classes in HTML.
/* mixin-first (recommended) — author your own class, variant is a mixin arg */ .save-btn { @include b.btn(primary); } <!-- utilities exist as escape hatches, not the default --> <button class="cia-btn-primary">Save</button>
The .cia-* utility classes exist as escape hatches for prototypes, one-offs, and projects that can't consume SCSS. They're not the recommended default.
How does the one-file theme swap actually work?
Every theme is a [data-theme="name"] { ... } block in one consolidated theme.css. Each block declares the same 123 CSS custom properties with theme-specific values. The data-theme attribute on the <html> element picks which block applies; flip it and the whole application reskins.
Persistence is a cookie read server-side before first paint, so the correct theme is baked into the initial HTML — no flash of unthemed content, no rebuild, no bundler step.
Can I make my own theme?
Yes. Every theme declares the same 123 tokens documented in the /docs/authoring/themes contract. Fork the contract, set values for every required slot, run the validator (node scripts/theme-validator.js), and drop the file in. If you skip a token the validator tells you which one.
How many themes ship?
Six in the box: Sketchbook (default warm paper), Press (editorial newsprint), Graphite (dark aluminium), Glass (visionOS-style frosted), Cupertino (macOS / Apple HIG), and Terminal (CRT phosphor). Preview all six in the Themes gallery.
How do I use my brand colors?
Override the relevant tokens in your own theme file. --ai drives primary actions (links, primary buttons, focus rings); --shu drives emphasis and danger; --ochre drives marginalia and accents. Replace those three and most of the visible brand moves with you.
If you want more than a colour swap, fork a shipped theme whose feel is closest to yours and change the palette. See /docs/tokens for the full vocabulary.
Does it work with SSR / Next.js / Remix?
Yes. The default pattern is a static export. The data-theme attribute is set server-side (or via an inline script that reads a cookie before first paint), which means the initial HTML already carries the right theme and there is no hydration mismatch.
For Next.js App Router specifically, see /docs/install#react-next.
What does it cost my bundle?
For the CSS-only consumer: one theme.css plus one base stylesheet. No runtime JavaScript. The consolidated theme.css that ships all six built-in themes is about 48 KB uncompressed — well under 10 KB gzipped — and the base stylesheet is smaller still.
If you only need one theme, use the per-theme files in public/themes/<name>/theme.css — each is roughly 10 KB uncompressed.
Is JavaScript required?
Not for styling. Plain HTML plus the two stylesheets renders a fully themed page with working buttons, cards, forms, tables, and the whole utility layer.
JavaScript is only required for the React components that manage focus or state — Dropdown, Modal, Tabs, and friends. A zero-JS page works great; you just skip the React library.
Does it have TypeScript types?
Yes. Every React component in the companion library ships with its prop types. Token names as a TypeScript union are on the roadmap — see the intro for status.
How do you handle breaking changes?
Pre-1.0 we reserve the right to make breaking changes in MINOR releases — the API surface is still settling. Every breaking change lands with a loud entry in CHANGELOG.md and, where we can, a codemod.
Post-1.0 we follow SemVer strictly. Breaking changes require a MAJOR bump, full stop. See VERSIONING.md at the repo root for the exact policy.
What's the license?
MIT. Use it, fork it, ship it in commercial work.
Is this production ready?
Not yet. We're pre-1.0 and the mixin API is still settling. The token contract is locked (123 slots, validated on every theme), but expect mixin signatures to move before 1.0.
That said, we eat our own dogfood: every pixel on this docs site — the buttons, cards, type scale, the theme picker — is built with cia. Once the mixin API is locked we tag 1.0. See ROADMAP.md at the repo root for current status.
Can I contribute?
Yes. See CONTRIBUTING.md at the repo root for setup, style, and the PR checklist. Themes, bug fixes, and docs improvements are especially welcome.
I found a bug. What now?
Open an issue using the Bug Report template at .github/ISSUE_TEMPLATE/bug_report.yml. Include a minimal reproduction, the theme you were on, and the browser — the template asks for those anyway.
For security issues, don't file a public issue. Email jhansenportfolio@gmail.com directly.