# Known gaps and rules

> Plainkit 0.28.0. Generated by scripts/build-skills.mjs from CHANGELOG.md, core/README.md, core/STANDARDS.md and the element sources. Do not edit: change the source and run the generator.

Plainkit 0.28.0 is a pre-release. Things an agent should not assume:

- Class-based components are gone. The old `.btn`, `.card`, `.modal-*`, `.notice`, `.dg-*` and similar CSS classes no longer exist; every component is a `pk-*` element (the page layer, `plainkit.css`, holds tokens, base styles, spacing, typography, table content and utilities).
- No inline `style` attributes, `<style>` elements, inline event handlers or inline scripts: the toolkit is built for `script-src 'self'; style-src 'self'`. Use props, `::part()` and CSS custom properties from a stylesheet, and scripts from files.
- Use only elements that exist (see `elements-index.md`). If a component you need is missing, say so instead of building a one-off; the missing-components list is tracked as an issue in the repository.
- The Guides (the Guides module of the site app, from Markdown in core/site/guides/content) are a first set of eight: getting started with the SDK and with Blazor, choosing what to build with, building an app (`mountApp`, modules and the page types), theming and tokens, responsive design and breakpoints, logging, migrating from the compat classes. The Guides have a search box (title and full-text, from a build-time word index), but no versions and no HTML/Blazor tabs yet, so the references in this skill remain the full documentation.
- The planned reactive layers (templates with expressions, `defineElement`, app islands, single-file components) are not built. Behaviour is plain: props are attributes or properties, events are `addEventListener`, forms and `data-theme` work natively.
- The layout builder (`mountLayoutBuilder`, `dist/modules/layout-builder/`) has pointer/touch drag-and-drop for the top-level page order and for a palette element dropped onto the canvas (slot-aware when it lands on a container); reordering inside a container, and moving a node into or out of one, stays keyboard/menu-only (Alt+arrows, Edit > Move out/in). Its chrome is a `pk-dock`; at phone width that becomes one tab strip with the File and Edit menus still in its toolbar, so Save stays reachable by touch alone. The dock opens on the Palette tab on a phone (no way yet to open on the canvas). The iframe device preview, reusable blocks and the Blazor `PkLayoutBuilder` wrapper are not built yet.
- Sample layouts are markup only. A sample pattern or template that needs behaviour ships a script of its own (a pattern's is shown in `patterns.md`, a template's in `templates.md`). Their data is placeholder text.
- `PkDialog` (`confirm`, `alert`, `prompt`) becomes a global when a `pk-dialog` has connected, and `PkToast` (`show`) when a `pk-toast-stack` has, so the page must contain one before you call them.
- Loading `dist/plainkit.js` as a script does not define any element by itself: the page has to call `initPlainkit()` (see `loading.md`).

## Rules from the standards

The whole site runs under `script-src 'self'; style-src 'self'`.

- No inline scripts, inline `style` attributes, `<style>` elements or inline event handlers. Setting styles through CSSOM (`el.style.x = ...`) is fine.
- No `eval`, no runtime requests to another origin.

- Tokens only: no literal colours in component or element CSS, and sizes come from the space and text scales. Two themes (`data-theme="dark|light"`) and three densities (`data-density`: compact, the default, spacious) are token sets, never separate stylesheets.
- **Use the named breakpoints, never a literal.** The widths are `tokens/breakpoints.json` (`phone` 640, `tablet` 1024, `wide` 1280; desktop-first, so a rule applies at that width and below). Element CSS writes `@media (--phone)` (or `(--above-phone)`); the build resolves it. CSS the site serves unbuilt (tokens, base, site, modules, samples) cannot use names and writes the named width literally. Scripts use `js/breakpoints.js` (`mediaBelow('phone')`), never `matchMedia('(max-width: 640px)')`. `tests/breakpoints.test.mjs` fails on a literal in element CSS, an unnamed width elsewhere and a literal in a `matchMedia`. A new width is a new name in the json file, not a new number in a rule.
- Use only components that exist in core. If something is missing, list it as a gap rather than building a one-off.
