<!-- Auto-generated by `velinstyle docs generate`. Do not edit. Source: cli/scanner-rules-data.js -->

# Scanner rules

Run `velinstyle scan [path]` for security, a11y, CSS, and PII checks. `velinstyle perf audit` for performance.

```bash
velinstyle scan . --severity warning
velinstyle scan . --only pii --fix-dry-run
velinstyle perf audit samples/
```

## a11y
| Rule ID | Severity | Message | Fix hint |
| --- | --- | --- | --- |
| `a11y/autocomplete-auth` | warning | Auth field missing autocomplete (WCAG 2.2). | Add autocomplete="username" or "current-password". |
| `a11y/button-label` | warning | <button> without visible text or aria-label. | Add text or aria-label. |
| `a11y/heading-order` | warning | Heading levels skip (e.g. h2 → h4). | Use sequential heading levels. |
| `a11y/html-lang` | error | <html> missing lang attribute. | Add lang="de" or appropriate locale — --fix. |
| `a11y/iframe-title` | error | <iframe> without title. | Add descriptive title attribute. |
| `a11y/img-alt` | error | <img> without alt. | Add alt text or alt="" for decorative images. |
| `a11y/img-decorative` | warning | Decorative <img alt=""> without aria-hidden. | Add aria-hidden="true" when visible text carries the meaning. |
| `a11y/input-label` | warning | <input> without label association. | Use <label for> or aria-label. |
| `a11y/interactive-aria-hidden` | error | Interactive element with aria-hidden="true". | Remove aria-hidden or use inert. |
| `a11y/invalid-describedby` | warning | aria-invalid without aria-describedby. | Link to error message element id. |
| `a11y/landmark-main` | warning | No <main> landmark. | Wrap primary content in <main>. |
| `a11y/skeleton-text` | warning | velin-skeleton on non-empty element. | Use skeleton only on empty placeholders. |
| `a11y/skip-link` | warning | No skip link for keyboard users. | Add .velin-skip-link to #main — --fix when id="main" exists. |
| `a11y/sparkline-label` | warning | velin-sparkline without accessible name. | Add label attribute or wrap in <figure><figcaption>. |
| `a11y/velin-icon-label` | warning | velin-icon in icon-only button without label. | Add label="…" on <velin-icon>. |
## css
| Rule ID | Severity | Message | Fix hint |
| --- | --- | --- | --- |
| `css/no-important` | info | !important usage. | Prefer @layer and specificity. |
| `css/var-fallback` | info | CSS variable without fallback in var(). | Use var(--velin-*, fallback). |
| `css/vendor-prefix` | info | Unnecessary vendor prefix. | Lightning CSS handles autoprefixing. |
| `css/z-index-token` | warning | Raw z-index instead of --velin-z-* token. | Use tokens from z-index.css — --fix suggests token. |
## perf
| Rule ID | Severity | Message | Fix hint |
| --- | --- | --- | --- |
| `perf/font-display-swap` | info | @font-face without font-display: swap. | Add font-display: swap. |
| `perf/img-missing-dimensions` | warning | <img> without width/height causes CLS. | Add width and height attributes — perf fix. |
| `perf/img-no-lazy` | info | Consider loading="lazy" for below-fold images. | Add loading="lazy". |
| `perf/large-inline-style` | info | Large inline style block. | Move to external CSS. |
| `perf/script-no-defer` | warning | External script without defer/async. | Add defer or type="module". |
| `perf/unused-velin-import` | info | Full component bundle loaded. | Use @birdapi/velinstyle/runtime for tree-shaking. |
## pii
| Rule ID | Severity | Message | Fix hint |
| --- | --- | --- | --- |
| `pii/hardcoded-email` | warning | Hardcoded email in source. | Use env/config or <velin-email>. --fix masks to placeholder. |
| `pii/hardcoded-secret` | error | Possible API key or secret in source. | Use environment variables or secret manager. |
| `pii/localstorage-pii` | warning | Email-like data in Web Storage. | Avoid storing PII in localStorage. |
| `pii/mailto-in-source` | info | mailto: exposes email in HTML. | Consider <velin-email> obfuscation. |
## security
| Rule ID | Severity | Message | Fix hint |
| --- | --- | --- | --- |
| `security/csp-meta` | info | No CSP meta tag found. | Add Content-Security-Policy header or meta. |
| `security/dangerous-target` | warning | <form target="_blank"> is unusual. | Use same-tab navigation. |
| `security/integrity-missing` | info | External <script> without integrity (SRI). | Add integrity + crossorigin for CDN scripts. |
| `security/no-data-html-uri` | error | data:text/html URI can execute script. | Avoid data: HTML URIs in href/src. |
| `security/no-document-write` | error | document.write() is dangerous. | Use DOM APIs or template elements. |
| `security/no-eval` | error | eval() is a critical risk. | Never use eval in production code. |
| `security/no-function-constructor` | error | new Function() equals eval(). | Refactor to static functions. |
| `security/no-inline-handler` | warning | Inline event handler found. Use addEventListener() instead. | Move handler to JS module. |
| `security/no-inline-style` | warning | Inline style attribute increases XSS surface. | Use VelinStyle utility classes. |
| `security/no-javascript-url` | error | javascript: URL detected. XSS vector. | Use button + script or href to safe URL. |
| `security/no-meta-refresh` | error | <meta http-equiv="refresh"> can redirect without consent. | Use server redirect or JS with user action. |
| `security/no-raw-innerhtml` | warning | Direct innerHTML without sanitization. | Use escapeHTML() from @birdapi/velinstyle/sanitize. |
| `security/postmessage-wildcard` | warning | postMessage with targetOrigin "*". | Specify exact target origin. |
| `security/safe-external-link` | warning | target="_blank" without rel="noopener noreferrer". | Add rel="noopener noreferrer" — auto-fix with --fix. |
