CORE CONCEPT · COMPLETE
Custom variants
Teach the compiler a project-owned context once, then compose it with every utility, breakpoint, state, relationship, and important modifier already supported by Coordiation.
Variant names do not inherit the utility prefix. A definition named theme-midnight is always used as theme-midnight:co-…, even when the project changes co- to another prefix.
Register a selector context
Put the generated class at the explicit & position. This keeps ownership and selector behavior visible in the CSS entry.
@coordiation;
@co-variant theme-midnight (
&:where([data-theme="midnight"] *)
);
@co-variant data-active (&[data-active]);<section class="theme-midnight:co-bg-black data-active:co-ring-2">
...
</section>Register a conditional at-rule
Conditional shorthand accepts only media, feature-support, and container queries. A selector placeholder is unnecessary because the at-rule wraps the generated rule.
@co-variant pointer-accurate (@media (pointer: fine));
@co-variant grid-ready (@supports (display: grid));
@co-variant card-wide (@container (width >= 32rem));<div class="grid-ready:co-grid card-wide:co-grid-cols-2"></div>Compose wrappers around one slot
Use block form when one variant needs both a condition and selector. The wrapper chain must contain exactly one namespaced @co-slot;.
@co-variant any-hover {
@media (any-hover: hover) {
&:hover {
@co-slot;
}
}
}<a class="md:any-hover:!co-underline">Documentation</a>COMPOSITION CONTRACT
One variant, the whole compiler
Custom definitions use the same candidate pipeline as built-ins.
- 01
Stacking: combine custom variants with responsive, state, attribute, group, peer, and conditional variants.
- 02
Important: leading or trailing important syntax still applies to every declaration.
- 03
Override: an exact project variant name deliberately takes priority over the built-in registry.
- 04
Static output: directives disappear after compilation; no browser runtime is added.
Reject ambiguous definitions early
The compiler fails on malformed or duplicate names, nested top-level directives, unsafe conditions, unsupported at-rules, selector formats without &, unclosed wrappers, missing slots, and sibling wrapper chains.
Use @media, @supports, or @container. Other at-rules remain authored CSS until they have an explicit compiler contract.
Track project variants programmatically
Every compile reports custom variants separately from the global built-in registries, preserving wrapper order for deterministic tools and agents.
const result = compile(inputCss, candidates);
console.log(result.customVariants);
// [{
// name: "any-hover",
// kind: "compound",
// wrappers: [
// { type: "at-rule", value: "@media (any-hover: hover)" },
// { type: "selector", value: "&:hover" }
// ]
// }]AI GENERATION CONTRACT
Discover names before composing
Agents should treat the authored directives and compile manifest as the exact project-local variant API.
- Never infer a custom variant from its visual intent or another framework's name.
- Keep the full stacked candidate literal so the scanner can discover it.
- Preserve selector and conditional wrapper order from the manifest.
- Use
@co-slot;once in compound definitions and never invent unsupported at-rules. - Report a rejected candidate instead of silently falling back to a built-in variant.
