A plugin is a module that exports the members of a scope() from cssints/plugin: scope("name", table).build(impl).export(). The table says what the plugin has (syntax names, kernels, a runtime, conflicts, token sets, other scopes, and its members); the members are typed from the table, with no second file of types. User code imports the plugin with the attribute, like cssints itself: import { ring } from "./ring.ts" with { type: "cssints" }. There is no registration in vite.config and no type augmentation; the engine finds the sites by the attribute, and learns kernels, runtimes and conflicts from the style each member returns. In user code a member returns a class string, so it goes into cn(), cx() and the conditions like any css.* value.
import { const cn: (...styles: Style[]) => Stylecn, const p: Prop<"padding">`<'padding-top'>{1,4}`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/padding)p } from "cssints" with { type: "cssints" };
import { function scope<const N extends string, const T extends Table>(name: N, table: T & Valid<N, T>): [CallKeys<T>] extends [never] ? Scope<N, T> : Pending<N, T>A plugin is a scope: `scope("name", table)`. The table holds, by shape: syntax aliases (a string), typed properties (a
`-vendor-prop` key with a grammar), kernels, static globals, layers, runtimes, conflicts, token sets and embedded scopes,
and the members (`chain`, `args` + `build`, `args` + `value`). A key starting `#` is private. Everything it declares is
namespaced by `name`, which is unique in the process (`cssints` and `derived` are reserved).scope } from "cssints/plugin";
export const { const ring: () => Chain<"ring", {
readonly width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [string, string][];
};
readonly color: {
readonly args: "<color>";
readonly emit: (v: string) => [string, string][];
};
}, Own<{
readonly width: "<length [0,∞]> | thin | thick";
readonly "#core": {
readonly css: "& { outline: var(--_w) solid var(--_c); outline-offset: 2px }";
readonly atProperty: "@property --_w { syntax: \"<length>\"; inherits: false; initial-value: 2px; }";
readonly requires: ["css.at-rules.property"];
};
readonly "#noOutline": {
readonly props: [...];
readonly message: "ring() sets the outline: use its methods";
};
readonly ring: {
...;
};
readonly "-webkit-font-smoothing": "auto | none | antialiased | subpixel-antialiased";
readonly dot: {
...;
};
}>>
ring, const dot: <const P extends readonly Part[]>(...parts: CheckIn<"dot", "small | large", false, P>) => Styledot, const webkitFontSmoothing: <const P extends readonly Part[]>(...parts: CheckIn<"-webkit-font-smoothing", "auto | none | antialiased | subpixel-antialiased", false, P>) => StylewebkitFontSmoothing } = scope<"ring", {
readonly width: "<length [0,∞]> | thin | thick";
readonly "#core": {
readonly css: "& { outline: var(--_w) solid var(--_c); outline-offset: 2px }";
readonly atProperty: "@property --_w { syntax: \"<length>\"; inherits: false; initial-value: 2px; }";
readonly requires: ["css.at-rules.property"];
};
readonly "#noOutline": {
readonly props: ["outline", RegExp];
readonly message: "ring() sets the outline: use its methods";
};
readonly ring: {
readonly uses: readonly ["core", "noOutline"];
readonly chain: {
readonly width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [...][];
};
readonly color: {
...;
};
};
};
readonly "-webkit-font-smoothing": "auto | none | antialiased | subpixel-antialiased";
readonly dot: {
...;
};
}>(name: "ring", table: {
readonly width: "<length [0,∞]> | thin | thick";
readonly "#core": {
readonly css: "& { outline: var(--_w) solid var(--_c); outline-offset: 2px }";
readonly atProperty: "@property --_w { syntax: \"<length>\"; inherits: false; initial-value: 2px; }";
readonly requires: ["css.at-rules.property"];
};
readonly "#noOutline": {
readonly props: ["outline", RegExp];
readonly message: "ring() sets the outline: use its methods";
};
readonly ring: {
readonly uses: readonly ["core", "noOutline"];
readonly chain: {
readonly width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [...][];
};
readonly color: {
...;
};
};
};
readonly "-webkit-font-smoothing": "auto | none | antialiased | subpixel-antialiased";
readonly dot: {
...;
};
} & Valid<...>): Pending<...>
A plugin is a scope: `scope("name", table)`. The table holds, by shape: syntax aliases (a string), typed properties (a
`-vendor-prop` key with a grammar), kernels, static globals, layers, runtimes, conflicts, token sets and embedded scopes,
and the members (`chain`, `args` + `build`, `args` + `value`). A key starting `#` is private. Everything it declares is
namespaced by `name`, which is unique in the process (`cssints` and `derived` are reserved).scope("ring", {
// a local syntax name: `<width>` in a grammar of this scope (it does not leak into mdn's names)
width: "<length [0,∞]> | thin | thick"width: "<length [0,∞]> | thin | thick",
// a kernel: global CSS, once. `&` is the class the engine mints for it, `--_w` is the custom property `--ring-w`
"#core": {
css: "& { outline: var(--_w) solid var(--_c); outline-offset: 2px }"css: "& { outline: var(--_w) solid var(--_c); outline-offset: 2px }",
atProperty: "@property --_w { syntax: \"<length>\"; inherits: false; initial-value: 2px; }"atProperty: '@property --_w { syntax: "<length>"; inherits: false; initial-value: 2px; }',
requires: ["css.at-rules.property"]requires: ["css.at-rules.property"],
},
"#noOutline": { props: ["outline", RegExp]props: ["outline", /^outline-/], message: "ring() sets the outline: use its methods"message: "ring() sets the outline: use its methods" },
// a chain member, like flex(): a call gives the marker and the kernel, each method emits custom properties
ring: {
readonly uses: readonly ["core", "noOutline"];
readonly chain: {
readonly width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [string, string][];
};
readonly color: {
readonly args: "<color>";
readonly emit: (v: string) => [string, string][];
};
};
}
ring: {
uses: readonly ["core", "noOutline"]uses: ["core", "noOutline"],
chain: {
readonly width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [string, string][];
};
readonly color: {
readonly args: "<color>";
readonly emit: (v: string) => [string, string][];
};
}
chain: {
width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [string, string][];
}
width: { args: "<width>"args: "<width>", spacing: truespacing: true, emit: (v: string) => [string, string][]emit: (v: stringv) => [["--_w", v: stringv]] },
color: {
readonly args: "<color>";
readonly emit: (v: string) => [string, string][];
}
color: { args: "<color>"args: "<color>", emit: (v: string) => [string, string][]emit: (v: stringv) => [["--_c", v: stringv]] },
},
},
// a property of your own, typed by its grammar (it is not in mdn-data); the key starts with `-`
"-webkit-font-smoothing": "auto | none | antialiased | subpixel-antialiased",
// a call member: its function is the entry of the same name in build()
dot: {
readonly args: "small | large";
}
dot: { args: "small | large"args: "small | large" },
})
.Pending<"ring", { readonly width: "<length [0,∞]> | thin | thick"; readonly "#core": { readonly css: "& { outline: var(--_w) solid var(--_c); outline-offset: 2px }"; readonly atProperty: "@property --_w { syntax: \"<length>\"; inherits: false; initial-value: 2px; }"; readonly requires: [...]; }; readonly "#noOutline": { ...; }; readonly ring: { ...; }; readonly "-webkit-font-smoothing": "auto | none | antialiased | subpixel-antialiased"; readonly dot: { ...; }; }>.build(impl: Impl<{
readonly width: "<length [0,∞]> | thin | thick";
readonly "#core": {
readonly css: "& { outline: var(--_w) solid var(--_c); outline-offset: 2px }";
readonly atProperty: "@property --_w { syntax: \"<length>\"; inherits: false; initial-value: 2px; }";
readonly requires: ["css.at-rules.property"];
};
readonly "#noOutline": {
readonly props: ["outline", RegExp];
readonly message: "ring() sets the outline: use its methods";
};
readonly ring: {
readonly uses: readonly ["core", "noOutline"];
readonly chain: {
readonly width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [...][];
};
readonly color: {
...;
};
};
};
readonly "-webkit-font-smoothing": "auto | none | antialiased | subpixel-antialiased";
readonly dot: {
...;
};
}>): Scope<...>
build({ dot: (value: string) => Madedot: (size: stringsize) => ({ Made.decls?: Decl[] | undefineddecls: [["--_size", size: stringsize === "small" ? "4px" : "8px"]] }) })
.Scope<"ring", { readonly width: "<length [0,∞]> | thin | thick"; readonly "#core": { readonly css: "& { outline: var(--_w) solid var(--_c); outline-offset: 2px }"; readonly atProperty: "@property --_w { syntax: \"<length>\"; inherits: false; initial-value: 2px; }"; readonly requires: [...]; }; readonly "#noOutline": { ...; }; readonly ring: { ...; }; readonly "-webkit-font-smoothing": "auto | none | antialiased | subpixel-antialiased"; readonly dot: { ...; }; }>.export(): Members<{
readonly width: "<length [0,∞]> | thin | thick";
readonly "#core": {
readonly css: "& { outline: var(--_w) solid var(--_c); outline-offset: 2px }";
readonly atProperty: "@property --_w { syntax: \"<length>\"; inherits: false; initial-value: 2px; }";
readonly requires: ["css.at-rules.property"];
};
readonly "#noOutline": {
readonly props: ["outline", RegExp];
readonly message: "ring() sets the outline: use its methods";
};
readonly ring: {
readonly uses: readonly ["core", "noOutline"];
readonly chain: {
readonly width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [...][];
};
readonly color: {
...;
};
};
};
readonly "-webkit-font-smoothing": "auto | none | antialiased | subpixel-antialiased";
readonly dot: {
...;
};
}>
The typed members of the table: `export const { ring } = scope("ring", { ... }).export()`.export();
export const const card: Stylecard = function cn(...styles: Style[]): Stylecn(p<readonly [2]>(parts_0: 2): Style`<'padding-top'>{1,4}`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/padding)p(2), const ring: () => Chain<"ring", {
readonly width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [...][];
};
readonly color: {
...;
};
}, Own<...>>
ring().width: <readonly ["thin"]>(parts_0: "thin") => Chain<"ring", Omit<{
readonly width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [string, string][];
};
readonly color: {
readonly args: "<color>";
readonly emit: (v: string) => [string, string][];
};
}, "width">, Own<{
readonly width: "<length [0,∞]> | thin | thick";
readonly "#core": {
readonly css: "& { outline: var(--_w) solid var(--_c); outline-offset: 2px }";
readonly atProperty: "@property --_w { syntax: \"<length>\"; inherits: false; initial-value: 2px; }";
readonly requires: ["css.at-rules.property"];
};
readonly "#noOutline": {
...;
};
readonly ring: {
...;
};
readonly "-webkit-font-smoothing": "auto | none | antialiased | subpixel-antialiased";
readonly dot: {
...;
};
}>>
width("thin").color: <readonly ["red"]>(parts_0: "red") => Chain<"ring", Omit<Omit<{
readonly width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [string, string][];
};
readonly color: {
readonly args: "<color>";
readonly emit: (v: string) => [string, string][];
};
}, "width">, "color">, Own<{
readonly width: "<length [0,∞]> | thin | thick";
readonly "#core": {
readonly css: "& { outline: var(--_w) solid var(--_c); outline-offset: 2px }";
readonly atProperty: "@property --_w { syntax: \"<length>\"; inherits: false; initial-value: 2px; }";
readonly requires: [...];
};
readonly "#noOutline": {
...;
};
readonly ring: {
...;
};
readonly "-webkit-font-smoothing": "auto | none | antialiased | subpixel-antialiased";
readonly dot: {
...;
};
}>>
color("red"), const webkitFontSmoothing: <readonly ["antialiased"]>(parts_0: "antialiased") => StylewebkitFontSmoothing("antialiased"), const dot: <readonly ["small"]>(parts_0: "small") => Styledot("small"));
export const const twice: anytwice = const ring: () => Chain<"ring", {
readonly width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [...][];
};
readonly color: {
...;
};
}, Own<...>>
ring().width: <readonly ["1px"]>(parts_0: "1px") => Chain<"ring", Omit<{
readonly width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [string, string][];
};
readonly color: {
readonly args: "<color>";
readonly emit: (v: string) => [string, string][];
};
}, "width">, Own<{
readonly width: "<length [0,∞]> | thin | thick";
readonly "#core": {
readonly css: "& { outline: var(--_w) solid var(--_c); outline-offset: 2px }";
readonly atProperty: "@property --_w { syntax: \"<length>\"; inherits: false; initial-value: 2px; }";
readonly requires: ["css.at-rules.property"];
};
readonly "#noOutline": {
...;
};
readonly ring: {
...;
};
readonly "-webkit-font-smoothing": "auto | none | antialiased | subpixel-antialiased";
readonly dot: {
...;
};
}>>
width("1px").width("2px"); // error: a method is used onceexport const const wrong: Chain<"ring", Omit<{
readonly width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [string, string][];
};
readonly color: {
readonly args: "<color>";
readonly emit: (v: string) => [string, string][];
};
}, "width">, Own<{
readonly width: "<length [0,∞]> | thin | thick";
readonly "#core": {
readonly css: "& { outline: var(--_w) solid var(--_c); outline-offset: 2px }";
readonly atProperty: "@property --_w { syntax: \"<length>\"; inherits: false; initial-value: 2px; }";
readonly requires: ["css.at-rules.property"];
};
readonly "#noOutline": {
readonly props: [...];
readonly message: "ring() sets the outline: use its methods";
};
readonly ring: {
...;
};
readonly "-webkit-font-smoothing": "auto | none | antialiased | subpixel-antialiased";
readonly dot: {
...;
};
}>>
wrong = const ring: () => Chain<"ring", {
readonly width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [...][];
};
readonly color: {
...;
};
}, Own<...>>
ring().width: <readonly ["red"]>(parts_0: "ring.width: unexpected \"red\" in \"red\", grammar [ <length [0,∞]> | thin | thick ]") => Chain<"ring", Omit<{
readonly width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [string, string][];
};
readonly color: {
readonly args: "<color>";
readonly emit: (v: string) => [string, string][];
};
}, "width">, Own<{
readonly width: "<length [0,∞]> | thin | thick";
readonly "#core": {
readonly css: "& { outline: var(--_w) solid var(--_c); outline-offset: 2px }";
readonly atProperty: "@property --_w { syntax: \"<length>\"; inherits: false; initial-value: 2px; }";
readonly requires: [...];
};
readonly "#noOutline": {
...;
};
readonly ring: {
...;
};
readonly "-webkit-font-smoothing": "auto | none | antialiased | subpixel-antialiased";
readonly dot: {
...;
};
}>>
width("red"); // error: not a widthexport const const bad: Stylebad = const webkitFontSmoothing: <readonly ["bold"]>(parts_0: "-webkit-font-smoothing: unexpected \"bold\" in \"bold\", grammar auto | none | antialiased | subpixel-antialiased") => StylewebkitFontSmoothing("bold"); // error: not in the grammarexport const const no: Styleno = const dot: <readonly ["medium"]>(parts_0: "dot: unexpected \"medium\" in \"medium\", grammar small | large") => Styledot("medium"); // error: not in the grammarexport const const hidden: anyhidden = const ring: () => Chain<"ring", {
readonly width: {
readonly args: "<width>";
readonly spacing: true;
readonly emit: (v: string) => [...][];
};
readonly color: {
...;
};
}, Own<...>>
ring().core; // error: no such methodwidth: "<length [0,∞]> | thin"), or, for a key that starts with -, a typed property (-webkit-font-smoothing, exported camel-cased as webkitFontSmoothing; a CSS property of mdn-data is an error, use css.<name>). { css, atProperty?, requires? } is a kernel, { rule, layer? } a global rule, { layers: [...], before? } a declaration of top-level layers (before: true prints them before the engine's), { polyfills, parentVars?, css? } a runtime, { props, message } conflicts, { tokens } a token set, a scope(...) another scope, { chain } a chain member, { args } a call member (a function in build()), { args, value, label? } a value member (fn({ args, value }) when args is a tuple or arg<T>(), see "Functions"). A key that starts with # is private: other entries use it, it is not exported, and an embedding scope does not see it. uses names it without the #, so #trim beside a public trim is a type error and a build error (cssints: x: #trim and trim share a name: rename one): a name is one key, private or not.<width> in a grammar of the table is the grammar written for width, in place, as a group ([ <length [0,∞]> | thin | thick ]); a name that is not in the table is left to mdn-data. The types and the build expand them with the same rule, so what the editor accepts is what the build accepts. A scope embedded as a module gives its public names as <mod.name>, a token set as <tokens.color.accent> (the type of that token), so a grammar can say "a colour or this token".emit and build return, --_x is the custom property --<scope>-x; in a kernel or a runtime & is the class the engine mints for the kernel (_<scope>-<entry>, _ring-core) and &(mod.key) that of the kernel key of an embedded scope. A runtime or conflicts entry takes the class of the first kernel in the uses of the member. Scope names are lowercase letters, digits and -; cssints and derived are the engine's.uses lists what a member needs, by key: kernels, globals, layers, runtimes and conflicts of the scope, or mod.key of an embedded one (the types reject a name that is none of these, or a private one). A call member may add more in what build returns.group: true on a chain or call member makes every style of the member carry the group marker _g-<scope>, after the markers of its kernels: sticky: { uses: ["core"], group: true, chain: {...} } in scope stuck gives _stuck-core _g-stuck _x, and within(attr("data-stuck", "top", "~="), "stuck")(...) reads that ancestor (2026-10-08, cssints-sbs8). The group's name is the scope's, unique in the process, so two plugins never share one; a user's group("stuck") is the same group, so do not name your own groups after a scope you use. It is a marker like a kernel's: a condition around the member with no declaration of its own is a build error (see "Conditions and layers").<scope>.<entry>) on first use: the CSS goes into layer _.k, below every class layer, and atProperty (the @property rules) at the top of the sheet. So a kernel cannot be conditional per site: a condition around a member that has only its marker is a build error (see "Conditions and layers"); give the member a method or arguments that set custom properties, which a condition can wrap. A kernel can also be written as styles, css: (css) => [css.outline("var(--_w)", "solid", "var(--_c)"), css.outlineOffset("2px")], which prints the declarations under the kernel's class: they are checked like a user's (grammar, prose rules), conditions, nest(), vars() and keyframes() names are allowed (see below), firstThatWorks() and a member's marker are not. Build errors, at the call site: two keys that declare one custom property, two keys that print one marker, and two kernels written as styles in one member's uses that set properties of the element that meet (the same property, a shorthand and its longhand, a logical and a physical side, as in cn()): cssints: x: kernels run and view both set animation, animation-timeline (they are one element's styles and print in no set order): write those in one kernel. Kernels are printed in _.k sorted by key (<scope>.<entry>), whatever the order of uses or of the modules, so two of one member never decide between themselves; in one kernel the sheet's order holds (a shorthand before its longhands). A raw kernel derives no properties and is not compared (2026-10-08, cssints-life). A kernel's requires (BCD keys) is a build warning for a target that lacks one, never an error. A key that is also in the polyfills of a runtime in the member's uses is covered: it warns only for the targets that runtime does not reach (a parentVars runtime below @property, see below), and a fallback of CSS or a script covers it everywhere. The support warning of a declaration in a kernel written as styles is covered by the same rule, by its BCD key (the one in parentheses at the end of the warning): core: { css: (css) => [css.borderRadius("var(--_r)"), css.cornerShape("squircle")] } beside mask: { polyfills: ["css.properties.corner-shape"], css: "..." } in uses warns for nobody, so a plugin keeps derived conflicts without a raw kernel (2026-10-08, cssints-rp0e); a warning or an error of such a declaration prints its value as the sheet does, var(--squircle-r), not var(--_r). As in every support warning, a BCD partial_implementation counts as support, because most partial entries are edge cases; an entry { key, exact: true } counts it as lacking, for a feature whose partial form gives other results (surface() asks for { key: "css.types.color.oklch.relative_syntax", exact: true }), and the warning says so: (a partial implementation counts as lacking).chain: { method: { args, spacing?, excludes?, emit } }) give () => chain. args is the grammar of the method's parts, checked in the types (the error is on the bad argument and says ring.width: unexpected "red" ...) and again at build time. spacing makes a lone number a step of the spacing scale (0.25rem), as in padding. emit returns declarations; a custom property is allowed and its value is not checked, any other property is checked like a css.* one. A method is used once: the chain leaves it out. excludes: ["darken"] leaves other methods out after this one too, and args: "" makes a method that takes no value (ink()). A grammar must be a literal type (a const variable is fine; if TypeScript has widened it to string, the method says so: write as const).{ args, uses? } and a function in build()) take their arguments by args: a grammar (the parts, joined by a space, as a property takes them: args: "small | large"), arg<T>() (one value of a TypeScript type, which TypeScript checks and build gets as it is: arg<"home" | "star">()), or a tuple of positional arguments, each a grammar (one part), "$tokens" (a token set from createTokens), "$overrides" (values by path for the tokens of the $tokens before it, checked in the types against that token set), "$selector" (a CSS selector list, checked in the types for brackets and quotes and at build time as a whole), arg<T>(), or at the end one object of named leaves ({ "size?": "<width>", on: "<color>" }, a key ending in ? is optional). build gets them as written, grammar parts as checked text. The positional form type-checks within the per-call budget; its cost is that an error lands on the call, with the position and the reason in the message, not on the argument. build returns { decls?, uses?, globals?, themes?, layers? }.globals are global rules that are not classes ({ rule, layer? } in the table, or { css, layer? }[] from build). A global is identified by its content, not by a name: the same rule from two styles is one, and editing a value replaces it. It is in the sheet of the modules whose styles carry it (as kernels are), and leaves it with them. layer sends a rule to a top-level layer of that name (@layer app); it must be declared by a layers entry (or layers from build: a list, or { layers: [...], before: true } for layers below the engine's), or by layers() in a module imported before. No layer puts it in _.k. Unlike a kernel, two globals may declare the same custom property; that is what lets a look set the same --color-* in several source layers.themes — themes: { tokens, overrides, selector, layer?, scope? }[] from build is createGlobalTheme(tokens, selector, overrides, { layer, scope }) made by a member, through the same path: the paths and values of overrides are checked against the types of tokens at build time, the aliases that depend on an override are declared again, and check.contrast reads the theme with the others. With args: ["$tokens", "$overrides", ...] the member takes the token set from its caller and the overrides are checked in the types as well.import { function scope<const N extends string, const T extends Table>(name: N, table: T & Valid<N, T>): [CallKeys<T>] extends [never] ? Scope<N, T> : Pending<N, T>A plugin is a scope: `scope("name", table)`. The table holds, by shape: syntax aliases (a string), typed properties (a
`-vendor-prop` key with a grammar), kernels, static globals, layers, runtimes, conflicts, token sets and embedded scopes,
and the members (`chain`, `args` + `build`, `args` + `value`). A key starting `#` is private. Everything it declares is
namespaced by `name`, which is unique in the process (`cssints` and `derived` are reserved).scope } from "cssints/plugin";
// A member that sets tokens in a look: `mode(t, "dark", { color: { bg: "#000" } })` is `[data-mode="dark"] { --color-bg: #000 }` in @layer viewer
export const { const mode: <const P extends readonly [unknown, unknown, unknown]>(...args: P & CheckAll<"mode", Own<{
readonly layers: {
readonly layers: readonly ["app", "viewer"];
};
readonly mode: {
readonly args: readonly ["$tokens", "<custom-ident>", "$overrides"];
readonly uses: readonly ["layers"];
};
}>, readonly ["$tokens", "<custom-ident>", "$overrides"], P>) => Style
mode } = scope<"mode", {
readonly layers: {
readonly layers: readonly ["app", "viewer"];
};
readonly mode: {
readonly args: readonly ["$tokens", "<custom-ident>", "$overrides"];
readonly uses: readonly ["layers"];
};
}>(name: "mode", table: {
readonly layers: {
readonly layers: readonly ["app", "viewer"];
};
readonly mode: {
readonly args: readonly ["$tokens", "<custom-ident>", "$overrides"];
readonly uses: readonly ["layers"];
};
} & Valid<"mode", {
readonly layers: {
readonly layers: readonly ["app", "viewer"];
};
readonly mode: {
readonly args: readonly ["$tokens", "<custom-ident>", "$overrides"];
readonly uses: readonly ["layers"];
};
}>): Pending<...>
A plugin is a scope: `scope("name", table)`. The table holds, by shape: syntax aliases (a string), typed properties (a
`-vendor-prop` key with a grammar), kernels, static globals, layers, runtimes, conflicts, token sets and embedded scopes,
and the members (`chain`, `args` + `build`, `args` + `value`). A key starting `#` is private. Everything it declares is
namespaced by `name`, which is unique in the process (`cssints` and `derived` are reserved).scope("mode", {
layers: {
readonly layers: readonly ["app", "viewer"];
}
layers: { layers: readonly ["app", "viewer"]layers: ["app", "viewer"] },
mode: {
readonly args: readonly ["$tokens", "<custom-ident>", "$overrides"];
readonly uses: readonly ["layers"];
}
mode: { args: readonly ["$tokens", "<custom-ident>", "$overrides"]args: ["$tokens", "<custom-ident>", "$overrides"], uses: readonly ["layers"]uses: ["layers"] },
})
.Pending<"mode", { readonly layers: { readonly layers: readonly ["app", "viewer"]; }; readonly mode: { readonly args: readonly ["$tokens", "<custom-ident>", "$overrides"]; readonly uses: readonly ["layers"]; }; }>.build(impl: Impl<{
readonly layers: {
readonly layers: readonly ["app", "viewer"];
};
readonly mode: {
readonly args: readonly ["$tokens", "<custom-ident>", "$overrides"];
readonly uses: readonly ["layers"];
};
}>): Scope<"mode", {
readonly layers: {
readonly layers: readonly ["app", "viewer"];
};
readonly mode: {
readonly args: readonly ["$tokens", "<custom-ident>", "$overrides"];
readonly uses: readonly ["layers"];
};
}>
build({
mode: (args_0: object, args_1: string, args_2: {
readonly [group: string]: unknown;
}) => Made
mode: (tokens: objecttokens, name: stringname, overrides: {
readonly [group: string]: unknown;
}
overrides) => ({
Made.themes?: {
tokens: object;
overrides: object;
selector: string;
layer?: string;
scope?: string;
}[] | undefined
As `createGlobalTheme(tokens, selector, overrides, { layer, scope })`: registered like any theme.themes: [{ tokens: objecttokens, overrides: objectoverrides, selector: stringselector: `[data-mode="${name: stringname}"]`, layer?: string | undefinedlayer: "viewer" }],
}),
})
.Scope<"mode", { readonly layers: { readonly layers: readonly ["app", "viewer"]; }; readonly mode: { readonly args: readonly ["$tokens", "<custom-ident>", "$overrides"]; readonly uses: readonly ["layers"]; }; }>.export(): Members<{
readonly layers: {
readonly layers: readonly ["app", "viewer"];
};
readonly mode: {
readonly args: readonly ["$tokens", "<custom-ident>", "$overrides"];
readonly uses: readonly ["layers"];
};
}>
The typed members of the table: `export const { ring } = scope("ring", { ... }).export()`.export();hover and the other pseudo-classes, attr(), within(), media(), container() and supports() wrap the kernel's styles as they wrap a user's: css.hover(css.opacity(0.8)), css.media("(width >= 40rem)")(css.padding("1rem")). The rules are printed under the kernel's class, in layer _.k, in the order of the sheet (fewer conditions first, then queries by width and pseudo-classes by place, a shorthand before its longhands), so the order the author writes them in does not matter; the declarations of one selector share a block. At most four conditions, as everywhere.import { const cn: (...styles: Style[]) => Stylecn, const paddingLeft: Prop<"padding-left">`<length-percentage [0,∞]>`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/padding-left)paddingLeft } from "cssints" with { type: "cssints" };
import { function scope<const N extends string, const T extends Table>(name: N, table: T & Valid<N, T>): [CallKeys<T>] extends [never] ? Scope<N, T> : Pending<N, T>A plugin is a scope: `scope("name", table)`. The table holds, by shape: syntax aliases (a string), typed properties (a
`-vendor-prop` key with a grammar), kernels, static globals, layers, runtimes, conflicts, token sets and embedded scopes,
and the members (`chain`, `args` + `build`, `args` + `value`). A key starting `#` is private. Everything it declares is
namespaced by `name`, which is unique in the process (`cssints` and `derived` are reserved).scope } from "cssints/plugin";
export const { const chip: () => Chain<"chip", {
readonly padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
}, Own<{
readonly core: {
readonly css: (css: Css) => Style[];
};
readonly chip: {
readonly uses: readonly ["core"];
readonly chain: {
readonly padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
};
}>>
chip } = scope<"chip", {
readonly core: {
readonly css: (css: Css) => Style[];
};
readonly chip: {
readonly uses: readonly ["core"];
readonly chain: {
readonly padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
};
}>(name: "chip", table: {
readonly core: {
readonly css: (css: Css) => Style[];
};
readonly chip: {
readonly uses: readonly ["core"];
readonly chain: {
readonly padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
};
} & Valid<"chip", {
readonly core: {
readonly css: (css: Css) => Style[];
};
readonly chip: {
readonly uses: readonly ["core"];
readonly chain: {
readonly padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
};
}>): Scope<...>
A plugin is a scope: `scope("name", table)`. The table holds, by shape: syntax aliases (a string), typed properties (a
`-vendor-prop` key with a grammar), kernels, static globals, layers, runtimes, conflicts, token sets and embedded scopes,
and the members (`chain`, `args` + `build`, `args` + `value`). A key starting `#` is private. Everything it declares is
namespaced by `name`, which is unique in the process (`cssints` and `derived` are reserved).scope("chip", {
core: {
readonly css: (css: Css) => Style[];
}
core: {
css: (css: Css) => Style[]css: (css: Csscss) => [
css: Csscss.const padding: <readonly ["var(--_p)"]>(parts_0: "var(--_p)") => Style`<'padding-top'>{1,4}`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/padding)padding("var(--_p)"),
css: Csscss.const border: <readonly ["1px solid"]>(parts_0: "1px solid") => Style`<line-width> || <line-style> || <color>`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/border)border("1px solid"),
css: Csscss.const hover: (...styles: Style[]) => StyleChrome 1, Edge 12, Firefox 1, Safari 2, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/:hover)hover(css: Csscss.const opacity: <readonly [0.8]>(parts_0: 0.8) => Style`<opacity-value>`. Chrome 1, Edge 12, Firefox 1, Safari 2, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/opacity)opacity(0.8)),
css: Csscss.const media: Condition
<"(width >= 40rem)">(query: "(width >= 40rem)") => QueryWrap (+2 overloads)
media("(width >= 40rem)")(css: Csscss.const padding: <readonly ["1rem"]>(parts_0: "1rem") => Style`<'padding-top'>{1,4}`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/padding)padding("1rem")),
],
},
chip: {
readonly uses: readonly ["core"];
readonly chain: {
readonly padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
}
chip: { uses: readonly ["core"]uses: ["core"], chain: {
readonly padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
}
chain: { padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
}
padding: { args: "<length>"args: "<length>", emit: (v: string) => [string, string][]emit: (v: stringv) => [["--_p", v: stringv]] } } },
}).Scope<"chip", { readonly core: { readonly css: (css: Css) => Style[]; }; readonly chip: { readonly uses: readonly ["core"]; readonly chain: { readonly padding: { readonly args: "<length>"; readonly emit: (v: string) => [string, string][]; }; }; }; }>.export(): Members<{
readonly core: {
readonly css: (css: Css) => Style[];
};
readonly chip: {
readonly uses: readonly ["core"];
readonly chain: {
readonly padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
};
}>
The typed members of the table: `export const { ring } = scope("ring", { ... }).export()`.export();
// layer _.k: ._chip-core{border:1px solid;padding:var(--chip-p)} ._chip-core:hover{opacity:0.8} @media (width >= 40rem){._chip-core{padding:1rem}}
export const const a: Chain<"chip", Omit<{
readonly padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
}, "padding">, Own<{
readonly core: {
readonly css: (css: Css) => Style[];
};
readonly chip: {
readonly uses: readonly ["core"];
readonly chain: {
readonly padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
};
}>>
a = const chip: () => Chain<"chip", {
readonly padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
}, Own<{
readonly core: {
readonly css: (css: Css) => Style[];
};
readonly chip: {
readonly uses: readonly ["core"];
readonly chain: {
readonly padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
};
}>>
chip().padding: <readonly ["4px"]>(parts_0: "4px") => Chain<"chip", Omit<{
readonly padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
}, "padding">, Own<{
readonly core: {
readonly css: (css: Css) => Style[];
};
readonly chip: {
readonly uses: readonly ["core"];
readonly chain: {
readonly padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
};
}>>
padding("4px");
// build error: cssints: chip: kernel core sets padding, border, opacity (this style also sets padding-left)
export const const b: Styleb = function cn(...styles: Style[]): Stylecn(const chip: () => Chain<"chip", {
readonly padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
}, Own<{
readonly core: {
readonly css: (css: Css) => Style[];
};
readonly chip: {
readonly uses: readonly ["core"];
readonly chain: {
readonly padding: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
};
}>>
chip(), paddingLeft<readonly ["1px"]>(parts_0: "1px"): Style`<length-percentage [0,∞]>`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/padding-left)paddingLeft("1px"));css a kernel is handed has two members user code has not. css.nest(selector) is a condition that puts the kernel's class in a selector: one complex selector with at least one & (the class), anywhere: "& > *", "& > * + *", "& p", ":root:has(&)", ".dark &" (2026-10-09, cssints-l8nq: & was first only at the start, before a combinator). It is checked at build time as a <complex-selector> with & as a class (a list, "& a, & b", is an error; the types check that there is an &). A condition inside it applies to the rule's subject, one around it to the kernel's element, which stands for &: css.nest("& > *")(css.hover(...)) is ._k > *:hover, css.hover(css.nest("& > *")(...)) is ._k:hover > *, css.hover(css.nest(":root:has(&)")(...)) is :root:has(._k:hover) and css.nest(":root:has(&)")(css.hover(...)) is :root:has(._k):hover. It counts as one condition and sorts after the element's own states. css.vars({ "--_gap": "1rem" }) sets custom properties on the element (--_x is --<scope>-x, as everywhere), values not checked, as in a chain's emit. A keyframes() or positionTry() name is a value of any declaration of the kernel, vars() included: its rule is a kernel of its own that goes wherever the kernel goes, so a member names keyframes without raw CSS. Made inside the kernel's css, its steps name --_x as the kernel does, --<scope>-x (css.keyframes({ from: css.vars({ "--_p": "100%" }) }) animates --skeleton-p in @cssints/skeleton), and such a rule's name ends with the scope's (kf-1a2b3c4d-skeleton), so two scopes with the same steps get two rules (2026-10-09, cssints-ge5k). Derived conflicts read the element's properties only: a custom property and what a nest() sets on another subject are left out, since a child's margin is not the element's, nor is the animation of :root:has(&). The subject is the element when & is in the last compound, outside parentheses (".dark &", "&.on"): those count, for derived conflicts and for two kernels of one member alike.import { const cn: (...styles: Style[]) => Stylecn, const flexGrow: Prop<"flex-grow">`<number [0,∞]>`. Chrome 29, Edge 12, Firefox 20, Safari 9, iOS 9, Android 29. [MDN](https://developer.mozilla.org/docs/Web/CSS/flex-grow)flexGrow, const keyframes: (steps: Steps) => Keyframes`keyframes({ from: opacity(0), to: opacity(1) })`: a `@keyframes` rule named by a hash of its content, in the sheet of
the modules that use the name. Each step is checked like a class; no conditions.keyframes, const margin: Prop<"margin">`<'margin-top'>{1,4}`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/margin)margin, const opacity: Prop<"opacity">`<opacity-value>`. Chrome 1, Edge 12, Firefox 1, Safari 2, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/opacity)opacity } from "cssints" with { type: "cssints" };
import { function scope<const N extends string, const T extends Table>(name: N, table: T & Valid<N, T>): [CallKeys<T>] extends [never] ? Scope<N, T> : Pending<N, T>A plugin is a scope: `scope("name", table)`. The table holds, by shape: syntax aliases (a string), typed properties (a
`-vendor-prop` key with a grammar), kernels, static globals, layers, runtimes, conflicts, token sets and embedded scopes,
and the members (`chain`, `args` + `build`, `args` + `value`). A key starting `#` is private. Everything it declares is
namespaced by `name`, which is unique in the process (`cssints` and `derived` are reserved).scope } from "cssints/plugin";
const const fade: Keyframesfade = function keyframes(steps: Steps): Keyframes`keyframes({ from: opacity(0), to: opacity(1) })`: a `@keyframes` rule named by a hash of its content, in the sheet of
the modules that use the name. Each step is checked like a class; no conditions.keyframes({ Steps.from?: Style | undefinedfrom: opacity<readonly [0]>(parts_0: 0): Style`<opacity-value>`. Chrome 1, Edge 12, Firefox 1, Safari 2, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/opacity)opacity(0) });
export const { const row: () => Chain<"row", {
readonly gap: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
}, Own<{
readonly core: {
readonly css: (css: Css) => Style[];
};
readonly row: {
readonly uses: readonly ["core"];
readonly chain: {
readonly gap: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
};
}>>
row } = scope<"row", {
readonly core: {
readonly css: (css: Css) => Style[];
};
readonly row: {
readonly uses: readonly ["core"];
readonly chain: {
readonly gap: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
};
}>(name: "row", table: {
readonly core: {
readonly css: (css: Css) => Style[];
};
readonly row: {
readonly uses: readonly ["core"];
readonly chain: {
readonly gap: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
};
} & Valid<"row", {
readonly core: {
readonly css: (css: Css) => Style[];
};
readonly row: {
readonly uses: readonly ["core"];
readonly chain: {
readonly gap: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
};
}>): Scope<...>
A plugin is a scope: `scope("name", table)`. The table holds, by shape: syntax aliases (a string), typed properties (a
`-vendor-prop` key with a grammar), kernels, static globals, layers, runtimes, conflicts, token sets and embedded scopes,
and the members (`chain`, `args` + `build`, `args` + `value`). A key starting `#` is private. Everything it declares is
namespaced by `name`, which is unique in the process (`cssints` and `derived` are reserved).scope("row", {
core: {
readonly css: (css: Css) => Style[];
}
core: {
css: (css: Css) => Style[]css: (css: Csscss) => [
css: Csscss.KernelCss.vars: (set: {
readonly [name: `--${string}`]: string | number | CSSStyleValue;
}) => Style
`vars({ "--_gap": "1rem" })`: custom properties on the element (`--_x` is `--<scope>-x`), values not checked. A
`keyframes()` or `positionTry()` name is a value too: its rule goes with the kernel. Not part of derived conflicts.vars({ "--_gap": "1rem", "--_fade": const fade: Keyframesfade }),
css: Csscss.const display: <readonly ["flex"]>(parts_0: "flex") => Style`[ <display-outside> || <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy> | grid-lanes | inline-grid-lanes | <display-outside> || [ <display-inside> | math ]`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/display)display("flex"),
css: Csscss.const animation: <readonly ["var(--_fade) 200ms"]>(parts_0: "var(--_fade) 200ms") => Style`<single-animation>#`. Chrome 43, Edge 12, Firefox 16, Safari 9, iOS 9, Android 43. [MDN](https://developer.mozilla.org/docs/Web/CSS/animation)animation("var(--_fade) 200ms"),
css: Csscss.KernelCss.nest: <"& > * + *">(selector: "& > * + *") => Wrap`nest("& > *")(flexGrow(1))`: styles under a selector around the kernel's class (`._k > *`, `:root:has(._k)`). A
condition inside applies to its subject (`& > *:hover`), one around it to the element (`._k:hover > *`,
`:root:has(._k:hover)`). One condition. When the subject is another element (`&` not in the last compound), what it
sets is not the element's, so a member's derived conflicts leave it out; `.x &` is the element's.nest("& > * + *")(css: Csscss.const marginInlineStart: <readonly ["var(--_gap)"]>(parts_0: "var(--_gap)") => Style`<'margin-top'>`. Chrome 69, Edge 79, Firefox 41, Safari 12.1, iOS 12.2, Android 69. [MDN](https://developer.mozilla.org/docs/Web/CSS/margin-inline-start)marginInlineStart("var(--_gap)")),
],
},
row: {
readonly uses: readonly ["core"];
readonly chain: {
readonly gap: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
}
row: { uses: readonly ["core"]uses: ["core"], chain: {
readonly gap: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
}
chain: { gap: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
}
gap: { args: "<length>"args: "<length>", emit: (v: string) => [string, string][]emit: (v: stringv) => [["--_gap", v: stringv]] } } },
}).Scope<"row", { readonly core: { readonly css: (css: Css) => Style[]; }; readonly row: { readonly uses: readonly ["core"]; readonly chain: { readonly gap: { readonly args: "<length>"; readonly emit: (v: string) => [string, string][]; }; }; }; }>.export(): Members<{
readonly core: {
readonly css: (css: Css) => Style[];
};
readonly row: {
readonly uses: readonly ["core"];
readonly chain: {
readonly gap: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
};
}>
The typed members of the table: `export const { ring } = scope("ring", { ... }).export()`.export();
// layer _.k: @keyframes kf-…{from{opacity:0}} ._row-core{animation:var(--row-fade) 200ms;--row-gap:1rem;--row-fade:kf-…;display:flex} ._row-core > * + *{margin-inline-start:var(--row-gap)}
export const const a: Stylea = function cn(...styles: Style[]): Stylecn(const row: () => Chain<"row", {
readonly gap: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
}, Own<{
readonly core: {
readonly css: (css: Css) => Style[];
};
readonly row: {
readonly uses: readonly ["core"];
readonly chain: {
readonly gap: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
};
}>>
row().gap: <readonly ["2rem"]>(parts_0: "2rem") => Chain<"row", Omit<{
readonly gap: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
}, "gap">, Own<{
readonly core: {
readonly css: (css: Css) => Style[];
};
readonly row: {
readonly uses: readonly ["core"];
readonly chain: {
readonly gap: {
readonly args: "<length>";
readonly emit: (v: string) => [string, string][];
};
};
};
}>>
gap("2rem"), margin<readonly [0]>(parts_0: 0): Style`<'margin-top'>{1,4}`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/margin)margin(0), flexGrow<readonly [1]>(parts_0: 1): Style`<number [0,∞]>`. Chrome 29, Edge 12, Firefox 20, Safari 9, iOS 9, Android 29. [MDN](https://developer.mozilla.org/docs/Web/CSS/flex-grow)flexGrow(1)); // fine: the margin is the children'sconflicts: { props, message }: one cn() that holds the marker and one of the listed properties (a name, or a RegExp) is a build error with the plugin's message and the call site: cssints: ring: ring() sets the outline: use its methods (this style also sets outline). Conditions count. The message is prefixed with the scope's name.
Derived conflicts. A kernel written as styles needs no conflicts entry: a member that uses it conflicts with every property that meets one the kernel sets, as cn() decides overlap: the property itself, its longhands, a shorthand over it, and a logical or physical sibling of the same side. core: { css: (css) => [css.outline(...), css.outlineOffset("2px")] } stops outline, outlineColor, outlineWidth and outlineOffset in the same cn(), under any condition, and lets color through: cssints: ring: kernel core sets outline, outline-offset (this style also sets outline-color). The message names the scope, the kernel and the property that was set. A conflicts entry among the member's uses replaces what its kernels derive (a list that allows outline-color while the kernel sets outline: { props: ["outline"], message }; props: [] allows everything), and so does a raw kernel, which has nothing to derive from (frame() and surface() are raw CSS with custom properties and @container rules, and frame() lets border-color through). The check reads every declaration of the style, those a member emits itself included: a member that emits a property its kernel sets lists its own conflicts.
runtime: { polyfills, parentVars?, css?, script? } is the part for browsers that lack a feature. polyfills are BCD keys. A client module that holds a site with the member imports virtual:cssints/runtime/<scope>.<entry>, and the module is empty (export {};, nothing ships) unless a browserslist target lacks one of the keys and the runtime reaches it. A runtime with parentVars is a script that stands on @property, so it reaches only the targets that have it; css and script stand on nothing and reach every target (@cssints/fonts' capsize trim in Firefox 120). When it is needed, parentVars ({ marker: "&", read, write, watch? }, custom properties written --_x) configure cssints/parent-vars, one shared script and one MutationObserver for all plugins, css (the fallback rules) is added to the sheet in layer _.k, only then, and the module imports script.
script (decided 2026-10-08, cssints-kuki) is the plugin's own browser code, a module specifier: "#io": { polyfills: ["css.properties.animation-timeline"], script: "@cssints/reveal/runtime", css: "..." }. It is a string the engine never evaluates (the script stays out of the build-time graph) and writes into the runtime module as import "@cssints/reveal/runtime";, which Vite resolves as the app's own imports are, in dev and in vite build. Write a subpath of the plugin's package, with a development condition for the source and a default for dist/ (exports: { "./runtime": { development: "./src/runtime.ts", default: "./dist/runtime.mjs" } }): the package's own tests resolve it by its name too. A script reaches every target, so it is not gated: it ships to every browser of a build whose targets lack a key, and probes the feature itself (CSS.supports) to stay off where it is native; with parentVars beside it the two are decided apart. A script is a module, so the browser runs it once, however many sites, files or runtime entries import it. The plugin's subpath stays public: an app can still import it by hand, which is harmless. Derived tokens are not members; the engine registers their runtime (cssints/derived) on this same delivery (see "Themes").
Identity. A scope name is unique in the process, and a scope is its content (the table, the source of its functions, the scopes it embeds), hashed. A module that runs again with the same content is nothing (every client module that uses a plugin runs it again). Another content under the same name replaces the old one, as an edit does in dev: the files that imported the edited module are forgotten when Vite reports it and run again. It is a build error, scope "x" is defined twice with different content, while a file that was not affected still uses the old one: two modules that define one name. icons() runs its scope once per collection, with the same table and the same code: one scope, and the collection is the closure of build, which the hash does not see.
Errors are MemberError values (Data.TaggedError) with pluginName (the scope) and the file, site and offset of the call, so the Vite overlay points at it. What build, value, a chain's emit or a kernel's styles throw is a MemberError at the call. A plain function the plugin exports (one that wraps styles, say) may throw an Error: while a site runs, anything thrown is located at that site, with its message (2026-10-08, cssints-rf3k).
lacking(...keys) gives the build's targets that lack one of the BCD keys, as browserslist names them, by the rules of the support warnings (partial_implementation lacks), and [] when every target has them all: a plugin emits fallback rules only when some target needs them (2026-10-08, cssints-rf3k). It runs at build time, in a member's functions or in the plugin's own:
import { const attr: {
<const N extends string>(name: Name<N>): StateWrap;
<const N extends string>(name: Name<N>, value: string, op?: AttrOp): StateWrap;
}
`attr("aria-current", "page")(color(...))` is `._x[aria-current="page"]`; no value is `[disabled]`. The value is
quoted for you. `op` is how the value is compared: `=` (default), `~=` (a word), `|=`, `^=`, `$=`, `*=`. One condition.attr, const cn: (...styles: Style[]) => Stylecn, const color: Prop<"color">`<color>`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/color)color, const container: Condition<"container", QueryWrap>container, type type Style = string & {
readonly __cssints: "style";
}
What every member returns: a class string. It is a string (`className`, `cx`), but only members make one.Style, const within: <const N extends string = never>(state: StateWrap, name?: Name<N>) => Wrap`within(hover)(color("red"))` is the style while a marked ancestor is hovered: `:where(._g:hover) ._x`, one class of
specificity, one condition. `within(hover, "row")` reads the `group("row")` ancestor.within } from "cssints" with { type: "cssints" };
import { const lacking: (...keys: BcdKey[]) => string[]The build's targets that lack one of the BCD keys, as browserslist names them (`["firefox 140"]`), by the rules of the
support warnings (`partial_implementation` lacks); empty when every target has them all. Build time, like `scope()`.lacking } from "cssints/plugin";
const const old: booleanold = function lacking(...keys: BcdKey[]): string[]The build's targets that lack one of the BCD keys, as browserslist names them (`["firefox 140"]`), by the rules of the
support warnings (`partial_implementation` lacks); empty when every target has them all. Build time, like `scope()`.lacking("css.at-rules.container.scroll-state_queries").Array<string>.length: numberGets or sets the length of the array. This is a number one higher than the highest index in the array.length > 0; // ["firefox 140"] or []
export const const stuck: (...styles: Style[]) => Stylestuck = (...styles: Style[]styles: type Style = string & {
readonly __cssints: "style";
}
What every member returns: a class string. It is a string (`className`, `cx`), but only members make one.Style[]) =>
function cn(...styles: Style[]): Stylecn(
container<"scroll-state(stuck: top)">(query: "scroll-state(stuck: top)"): QueryWrap (+2 overloads)container("scroll-state(stuck: top)")(...styles: Style[]styles),
...(const old: booleanold ? [within<"stuck">(state: StateWrap, name?: "stuck" | undefined): Wrap`within(hover)(color("red"))` is the style while a marked ancestor is hovered: `:where(._g:hover) ._x`, one class of
specificity, one condition. `within(hover, "row")` reads the `group("row")` ancestor.within(attr<"data-stuck">(name: "data-stuck", value: string, op?: AttrOp): StateWrap (+1 overload)`attr("aria-current", "page")(color(...))` is `._x[aria-current="page"]`; no value is `[disabled]`. The value is
quoted for you. `op` is how the value is compared: `=` (default), `~=` (a word), `|=`, `^=`, `$=`, `*=`. One condition.attr("data-stuck", "top", "~="), "stuck")(...styles: Style[]styles)] : []),
);
export const const title: Styletitle = const stuck: (...styles: Style[]) => Stylestuck(color<readonly ["red"]>(parts_0: "red"): Style`<color>`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/color)color("red"));dependsOn(path) tells the engine that the module being evaluated read a file (an image, an SVG, a font; path relative to the working directory) (2026-10-09, cssints-04u8). Call it where the file is read, in a member's functions or in the plugin's own, before or after the read. The file becomes a dependency of the client module whose evaluation ran the call, as a module it imports is: in dev, an edit of the file runs that module again and the sheet changes, the module untouched; the dev server's watcher watches the file, outside the root too. In vite build --watch the file is a watched file (addWatchFile), so an edit builds again. @cssints/placeholder, @cssints/icons (fs) and @cssints/fonts (fs) call it for every file they read.import { function readFileSync(path: PathOrFileDescriptor, options?: {
encoding?: null | undefined;
flag?: string | undefined;
} | null): NonSharedBuffer (+2 overloads)
Returns the contents of the `path`.
For detailed information, see the documentation of the asynchronous version of
this API:
{@link
readFile
}
.
If the `encoding` option is specified then this function returns a
string. Otherwise it returns a buffer.
Similar to
{@link
readFile
}
, when the path is a directory, the behavior of `fs.readFileSync()` is platform-specific.
```js
import { readFileSync } from 'node:fs';
// macOS, Linux, and Windows
readFileSync('<directory>');
// => [Error: EISDIR: illegal operation on a directory, read <directory>]
// FreeBSD
readFileSync('<directory>'); // => <data>
```readFileSync } from "node:fs";
import { const color: Prop<"color">`<color>`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/color)color } from "cssints" with { type: "cssints" };
import { const dependsOn: (path: string) => voidTells the engine that the module being evaluated read the file at `path` (relative to the working directory): in dev, an
edit of the file runs that module again, as an edit of a module it imports does; in `vite build --watch`, it is a watched
file. Build time, like `scope()`: in a member's functions or in the plugin's own.dependsOn } from "cssints/plugin";
export const const swatch: (file: string) => Styleswatch = (file: stringfile: string) => {
function dependsOn(path: string): voidTells the engine that the module being evaluated read the file at `path` (relative to the working directory): in dev, an
edit of the file runs that module again, as an edit of a module it imports does; in `vite build --watch`, it is a watched
file. Build time, like `scope()`: in a member's functions or in the plugin's own.dependsOn(file: stringfile);
return color<readonly [string]>(parts_0: string): Style`<color>`. Chrome 1, Edge 12, Firefox 1, Safari 1, iOS 1, Android 18. [MDN](https://developer.mozilla.org/docs/Web/CSS/color)color(function readFileSync(path: PathOrFileDescriptor, options: {
encoding: BufferEncoding;
flag?: string | undefined;
} | BufferEncoding): string (+2 overloads)
Synchronously reads the entire contents of a file.readFileSync(file: stringfile, "utf8").String.trim(): stringRemoves the leading and trailing white space and line terminator characters from a string.trim());
};A dependency is a file, not a directory: a file added to a directory is not seen. Vite's watcher skips node_modules, so a file there (a collection of @iconify-json, @fontsource) is not watched. An evaluation that fails records nothing: after a build error, edit the module or reload.
cssints/plugin points at author.ts and scope.ts: the signatures and the type-level code (Members, Chain, Expand, the call checks) and no code that runs, because a program that imports a plugin must not need Node's types or a newer lib. The engine is scope-engine.ts; macro.ts registers it when the library loads.keyword members, completions of keywords inside plugin grammar strings (the message still names the grammar), and a plugin that is a package of members you install other than @cssints/icons.