Documentation v1.2.0
Brewwind is a zero-configuration, runtime utility-class engine for the
browser. Write chai-* classes directly in HTML and styles are applied instantly — no build
step, no CSS files, no config.
chai- class on the page is resolved and injected into a live <style>
tag. New DOM nodes are handled automatically via MutationObserver.
Installation
Via npm
Install the package into your project:
npm install brewwind
Then import once in your JavaScript entry point or directly in your HTML file:
<script type="module">
import "brewwind";
</script>
Or using an explicit path when developing locally:
<script type="module">
import "./node_modules/brewwind/dist/index.js";
</script>
Optional explicit init
Brewwind auto-initialises on DOMContentLoaded. If you need to trigger it manually, use the
named export:
import { initBrewWind } from "brewwind";
initBrewWind();
Module formats
| Format | File | Usage |
|---|---|---|
| ESM | dist/index.js |
import "brewwind" |
| CJS | dist/index.cjs |
require("brewwind") |
How it works
On initialisation, Brewwind performs two passes:
- Initial scan — queries
[class*="chai-"]on the entire document and resolves every matched utility class into inline styles. - MutationObserver — attaches a watcher to
document.bodylistening forchildListandclassattribute mutations. New nodes and class changes are batched inside arequestAnimationFramecallback for optimal performance.
Hover and focus states are injected as real CSS rules into dedicated <style> tags in
<head>, keyed by an escaped class name, so they are only written once per unique
class string.
Class Syntax
Every Brewwind utility follows the pattern:
chai-{property}-{value}
The chai- prefix is required. Examples:
| Class | CSS output |
|---|---|
| chai-bg-blue-500 | background-color: #3b82f6 |
| chai-text-gray-400 | color: #9ca3af |
| chai-p-4 | padding: 16px |
| chai-rounded-xl | border-radius: 0.75rem |
| chai-flex | display: flex |
| chai-items-center | align-items: center |
| chai-font-semibold | font-weight: 600 |
| chai-shadow-lg | box-shadow: 0 10px 15px … |
Arbitrary Values
Pass any custom CSS value using bracket notation:
<!-- Custom hex color -->
<div class="chai-bg-[#161616]"></div>
<!-- RGBA border -->
<div class="chai-border-[rgba(255,255,255,0.12)]"></div>
<!-- Exact pixel width -->
<div class="chai-w-[350px]"></div>
<!-- Custom box shadow (use _ for spaces) -->
<div class="chai-shadow-[0_4px_24px_rgba(0,0,0,0.4)]"></div>
_ in place of spaces inside bracket notation. Brewwind replaces them with
spaces before applying the value.
Arbitrary values work for: chai-bg-[…], chai-text-[…],
chai-border-[…], chai-w-[…], chai-h-[…],
chai-shadow-[…], chai-cursor-[…], chai-opacity-[…],
chai-z-[…].
Hover States
Prefix any valid class with hover: to apply it only on mouse hover:
<button class="chai-bg-white hover:chai-bg-gray-100">
Click me
</button>
<a class="chai-text-gray-500 hover:chai-text-white hover:chai-bg-gray-800
chai-px-3 chai-py-1 chai-rounded-md">
Link
</a>
Brewwind attaches mouseenter / mouseleave listeners that snapshot and restore
the element's base styles, so CSS transitions work as expected.
Focus States
Use the focus: prefix for keyboard-accessible focus styles. A real CSS :focus
rule is injected into <head>:
<input class="chai-border chai-border-gray-700
focus:chai-border-blue-500 chai-rounded-md chai-p-2">
Dynamic DOM Support
Any element added after page load is styled automatically:
const card = document.createElement("div");
card.className = "chai-bg-[#1a1a1a] chai-p-4 chai-rounded-xl chai-border chai-border-gray-800";
document.body.appendChild(card); // styled immediately
Class changes on existing elements are also tracked. Removing a chai- class reverts the
affected CSS property via group-based recomputation.
Colors
Brewwind ships a full Tailwind-compatible color palette. Use colors for background
(chai-bg-{color}-{shade}), text (chai-text-{color}-{shade}),
and border (chai-border-{color}-{shade}).
| Color family | Available shades | Example |
|---|---|---|
| gray | 50 · 100 · 200 · 300 · 400 · 500 · 600 · 700 · 800 · 900 | chai-bg-gray-800 |
| red | 50 – 900 | chai-text-red-500 |
| green | 50 – 900 | chai-bg-green-400 |
| blue | 50 – 900 | chai-border-blue-600 |
| yellow | 50 – 900 | chai-bg-yellow-300 |
| orange | 50 – 900 | chai-text-orange-400 |
| purple | 50 – 900 | chai-bg-purple-700 |
| pink | 50 – 900 | chai-text-pink-500 |
| sky | 50 – 900 | chai-bg-sky-400 |
| cyan | 50 – 900 | chai-text-cyan-300 |
| indigo | 50 – 900 | chai-bg-indigo-600 |
<!-- Named -->
<p class="chai-text-white">White text</p>
<div class="chai-bg-black chai-text-white">Black bg</div>
<!-- Arbitrary -->
<div class="chai-bg-[#5b8dee] chai-text-[rgba(255,255,255,0.8)]"></div>
Spacing & Sizing
Brewwind uses a 4px base unit: 1 = 4px, 4 = 16px,
8 = 32px.
Padding
| Class | CSS property |
|---|---|
| chai-p-{n} | padding (all sides) |
| chai-px-{n} | padding-left + padding-right |
| chai-py-{n} | padding-top + padding-bottom |
| chai-pt-{n} | padding-top |
| chai-pr-{n} | padding-right |
| chai-pb-{n} | padding-bottom |
| chai-pl-{n} | padding-left |
Margin
| Class | CSS property |
|---|---|
| chai-m-{n} | margin (all sides) |
| chai-mx-{n} | margin-left + margin-right |
| chai-my-{n} | margin-top + margin-bottom |
| chai-mt-{n} | margin-top |
| chai-mr-{n} | margin-right |
| chai-mb-{n} | margin-bottom |
| chai-ml-{n} | margin-left |
Spacing scale
| Token | Value | Token | Value |
|---|---|---|---|
| 0 | 0px | 8 | 32px |
| 1 | 4px | 9 | 36px |
| 2 | 8px | 10 | 40px |
| 3 | 12px | 12 | 48px |
| 4 | 16px | sm | 8px |
| 5 | 20px | md | 16px |
| 6 | 24px | lg | 24px |
| 7 | 28px | xl | 32px |
| 2xl | 48px | 3xl | 64px |
| 4xl | 96px | 5xl | 128px |
Gap
| Class | CSS property |
|---|---|
| chai-gap-{n} | gap |
| chai-gap-x-{n} | column-gap |
| chai-gap-y-{n} | row-gap |
Width & Height
| Class | Value |
|---|---|
| chai-w-{n} / chai-h-{n} | n × 4px (e.g. chai-w-12 → 48px) |
| chai-w-full / chai-h-full | 100% |
| chai-w-screen / chai-h-screen | 100vw / 100vh |
| chai-w-auto / chai-h-auto | auto |
| chai-w-min / chai-h-min | min-content |
| chai-w-max / chai-h-max | max-content |
| chai-w-fit / chai-h-fit | fit-content |
| chai-w-1/2 … chai-w-3/4 | 50% … 75% |
| chai-w-[350px] | arbitrary value |
Typography
Font size — chai-text-{size} or chai-font-{size}
| Token | Value | Token | Value |
|---|---|---|---|
| xs | 0.75rem (12px) | 5xl | 3rem (48px) |
| sm | 0.875rem (14px) | 6xl | 3.75rem (60px) |
| base | 1rem (16px) | 7xl | 4.5rem (72px) |
| lg | 1.125rem (18px) | 8xl | 6rem (96px) |
| xl | 1.25rem (20px) | 9xl | 8rem (128px) |
| 2xl | 1.5rem (24px) | ||
| 3xl | 1.875rem (30px) | ||
| 4xl | 2.25rem (36px) |
Font weight — chai-font-{weight}
| Class | font-weight |
|---|---|
| chai-font-thin | 100 |
| chai-font-extralight | 200 |
| chai-font-light | 300 |
| chai-font-normal | 400 |
| chai-font-medium | 500 |
| chai-font-semibold | 600 |
| chai-font-bold | 700 |
| chai-font-extrabold | 800 |
| chai-font-black | 900 |
Text alignment
chai-text-left | chai-text-center | chai-text-right | chai-text-justify
Layout & Flexbox
| Class | CSS |
|---|---|
| chai-flex | display: flex |
| chai-inline-flex | display: inline-flex |
| chai-flex-row | flex-direction: row |
| chai-flex-row-reverse | flex-direction: row-reverse |
| chai-flex-col | flex-direction: column |
| chai-flex-col-reverse | flex-direction: column-reverse |
| chai-items-start | align-items: flex-start |
| chai-items-center | align-items: center |
| chai-items-end | align-items: flex-end |
| chai-items-stretch | align-items: stretch |
| chai-justify-start | justify-content: flex-start |
| chai-justify-center | justify-content: center |
| chai-justify-end | justify-content: flex-end |
| chai-justify-between | justify-content: space-between |
| chai-justify-around | justify-content: space-around |
| chai-justify-evenly | justify-content: space-evenly |
Borders & Radius
Border width
| Class | Sides | Width tokens |
|---|---|---|
| chai-b-{n} | all | none/0=0 | 1/sm=1px | 2/md=2px | 4/lg=4px | 8/xl=8px |
| chai-bt-{n} | top | |
| chai-br-{n} | right | |
| chai-bb-{n} | bottom | |
| chai-bl-{n} | left | |
| chai-bx-{n} | left + right | |
| chai-by-{n} | top + bottom |
Border color
<div class="chai-border chai-border-gray-700">Named color</div>
<div class="chai-border chai-border-[rgba(255,255,255,0.12)]">Arbitrary</div>
Border radius
| Class | border-radius |
|---|---|
| chai-rounded-none | 0 |
| chai-rounded-sm | 0.125rem |
| chai-rounded-md | 0.375rem |
| chai-rounded-lg | 0.5rem |
| chai-rounded-xl | 0.75rem |
| chai-rounded-2xl | 1rem |
| chai-rounded-3xl | 1.5rem |
| chai-rounded-full | 9999px |
Directional radius: chai-rounded-t-{size} (top), chai-rounded-b-{size}
(bottom), chai-rounded-l-{size} (left), chai-rounded-r-{size} (right).
Shadows
| Class | box-shadow |
|---|---|
| chai-shadow-sm | 0 1px 2px rgba(0,0,0,0.05) |
| chai-shadow / chai-shadow-base | 0 1px 3px rgba(0,0,0,0.1) … |
| chai-shadow-md | 0 4px 6px -1px rgba(0,0,0,0.1) … |
| chai-shadow-lg | 0 10px 15px -3px rgba(0,0,0,0.1) … |
| chai-shadow-xl | 0 20px 25px -5px rgba(0,0,0,0.1) … |
| chai-shadow-2xl | 0 25px 50px -12px rgba(0,0,0,0.25) |
| chai-shadow-inner | inset 0 2px 4px rgba(0,0,0,0.06) |
| chai-shadow-none | none |
| chai-shadow-[…] | arbitrary (use _ for spaces) |
Positioning
chai-static | chai-relative | chai-absolute | chai-fixed | chai-sticky
Inset offsets: chai-top-{n}, chai-right-{n}, chai-bottom-{n},
chai-left-{n}. Value scale: n × 4px, plus auto, full, and
fractions (1/2, 1/3 … 3/4).
<div class="chai-absolute chai-top-4 chai-right-4"></div>
<div class="chai-sticky chai-top-0"></div>
<div class="chai-absolute chai-bottom-[24px] chai-left-1/2"></div>
Display
| Class | display |
|---|---|
| chai-block | block |
| chai-inline-block | inline-block |
| chai-inline | inline |
| chai-flex | flex |
| chai-inline-flex | inline-flex |
| chai-hidden | none |
Opacity & Z-Index
Opacity — chai-opacity-{n}
| Token | opacity | Token | opacity |
|---|---|---|---|
| 0 | 0 | 60 | 0.6 |
| 5 | 0.05 | 70 | 0.7 |
| 10 | 0.1 | 75 | 0.75 |
| 20 | 0.2 | 80 | 0.8 |
| 25 | 0.25 | 90 | 0.9 |
| 30 | 0.3 | 95 | 0.95 |
| 40 | 0.4 | 100 | 1 |
| 50 | 0.5 | […] | arbitrary |
Z-Index — chai-z-{n}
Tokens: 0, 10, 20, 30, 40,
50, auto, or arbitrary chai-z-[999].
Cursor
chai-cursor-auto chai-cursor-default chai-cursor-pointer
chai-cursor-wait chai-cursor-text chai-cursor-move
chai-cursor-help chai-cursor-not-allowed chai-cursor-none
chai-cursor-grab chai-cursor-grabbing chai-cursor-zoom-in
chai-cursor-zoom-out chai-cursor-copy chai-cursor-crosshair
chai-cursor-n-resize chai-cursor-ew-resize chai-cursor-nwse-resize
chai-cursor-[url(cursor.png)] <-- arbitrary
Brewwind v1.2.0 — Built for the craft.