# mates-css
> **We don't flash, we deliver!**
mates-css is a framework-agnostic CSS library. It pre-styles native HTML and ships optional CSS classes. It has no JavaScript runtime. It is not the Mates JS framework.
Works in React, Vue, Angular, Solid, Svelte, Lit, plain HTML, and any other app that can load a stylesheet.
Version: 0.5.0. License: MIT. Install: `npm install mates-css` then `import "mates-css"`. CDN: `https://unpkg.com/mates-css@0.5.0/mates.min.css`
This file is the machine contract (allowed classes and states). Human docs: docs.html
Source: https://github.com/thejsmaster/mates-css
Playground: playground.html
Raw: https://unpkg.com/mates-css/llms.txt
## Rules for AI agents
1. Always call this library **mates-css**. Never call it "Mates". "Mates" is a separate JavaScript framework. mates-css is CSS-only and framework-agnostic.
2. Style the UI with mates-css only. Do not add Tailwind, Bootstrap, Bulma, or another CSS/UI kit.
3. Use only class names listed in this file. Do not invent unofficial classes (no `.mates-*`, no `.btn-xl`, no `.is-active`).
4. Prefer native HTML: `button`, `input`, `table`, `details`, `progress`, `label`. mates-css already styles those tags. Classes are variants (`.btn-primary`) or the same look on a non-native host (``).
5. Overlay open state is `.open` on `.modal` `.menu` `.pop` `.drawer` `.sheet` `.search`. Toggle it from the app. Do not use `:focus-within` or hidden-checkbox hacks.
6. Selected / current chrome uses `.selected` (tabs, chips, nav, list rows). Not `.active` except drag-over on `.drop`.
7. **If mates-css has no component for the request:** do not invent a class. Build it from scratch in the app with native HTML, existing `--m-*` tokens, and `.m-*` layout utilities. Put extra CSS in the app, using `var(--m-bg)`, `var(--m-fg)`, `var(--m-primary)`, `var(--m-border)`, `var(--m-r)`.
8. Dark mode follows `prefers-color-scheme` by default. Set `data-theme="dark"|"light"` on `` only to override.
9. Floor: Safari 15, Chrome 94, Firefox 92. No `color-mix()`, no standalone `translate`/`rotate` properties, no `:has()` in required styles.
## How it works
- Native tags are styled with no class: `button`, `label`, `input`, `select`, `textarea`, `table`, `fieldset`, `legend`, `details`, `progress`, `code`, `pre`, `dl`.
- Classes are variants (`.btn-primary`) or the same look on a non-native host (``).
- Dark mode: follows `prefers-color-scheme` by default. Override with `data-theme="dark"|"light"` on ``; remove the attribute to return to the OS.
- Tokens are `--m-*` on `:root` (e.g. `--m-primary`, `--m-r`, `--m-fs`).
## Open and other states
Your app toggles classes. Nothing auto-opens on focus.
| Class | Where | Meaning |
|---|---|---|
| `.open` | `.modal` `.menu` `.pop` `.drawer` `.sheet` `.search` | show overlay / panel |
| `.selected` | `.tab` `.sidenav-item` `.list-item` `.chip` `.seg-item` `.pick` `nav a` `.subnav a` `.toc a` `.bnav-item` `tr` | current / chosen |
| `.collapsed` | `.shell` | shrink sidebar (`--m-side`) |
| `.active` | `.drop` | drag-over |
| `.done` `.current` | `.step` | wizard progress |
| `.current` | breadcrumb | last crumb |
| `.disabled` | list/sidenav items | not clickable |
| native `disabled` | buttons/inputs | disabled control |
| native `[open]` | `` | accordion expanded |
JS pattern: `el.classList.add("open")` / `.remove("open")` / `.toggle("open")`.
## Components (required class or tag)
- Button: bare `