# Brams v1.1.0

Brams ist eine dependency-freie Vanilla-CSS/JavaScript-Library für sachliche, robuste Produktoberflächen. Der technische Light-Theme-Stil folgt einer digitalen Rams-Formensprache: Gebrauchswert, Ordnung, Verständlichkeit und Zurückhaltung stehen vor Dekoration.

**Live-Demo:** [Brams-Komponentenkatalog](https://ui.jodie-oesterling.de/Brams/)

[![Quality](https://github.com/TheAnonymous/Brams/actions/workflows/ci.yml/badge.svg)](https://github.com/TheAnonymous/Brams/actions/workflows/ci.yml)

Die Library ist kein offizielles Braun-Produkt und verwendet keine geschützten Braun-Gestaltungselemente.

## Einbindung

Es gibt keinen Build-Schritt und keine Runtime-Abhängigkeiten. CSS, JavaScript, Sprite und die lokalen Schriftdateien werden gemeinsam ausgeliefert:

```html
<link rel="stylesheet" href="brams.css" />
<script src="brams.js" defer></script>

<button class="brams-button brams-button--primary">Speichern</button>
```

`icons.svg` muss relativ zu `brams.js` beziehungsweise zum Markup unter `icons.svg#…` erreichbar sein. Der Ordner `fonts/` muss relativ zu `brams.css` erhalten bleiben. Es werden keine Schriften, Icons oder anderen Assets von externen Servern geladen.

## Bezug und Dateigrenzen

Brams wird bis auf Weiteres nicht über npm veröffentlicht. Lade ein versioniertes Archiv unter [GitHub Releases](https://github.com/TheAnonymous/Brams/releases) und übernimm für eine Produktoberfläche nur diese Dateien:

| Pfad | Verwendung |
| --- | --- |
| `brams.css` | Design Tokens und Komponentenstile |
| `brams.js` | Optionale Runtime für interaktive Komponenten |
| `icons.svg` | Lokaler SVG-Sprite |
| `fonts/` | Archivo-Schnitte und OFL-Lizenz |

`index.html`, `catalog.js` und `tests/` gehören zum Showcase beziehungsweise zur Entwicklung und sind keine Runtime-Abhängigkeiten. Insbesondere sind `catalog.js` und alle `data-brams-demo-*`-Hooks nicht Teil der stabilen Library-API.

## Komponentenindex

| Kategorie | Komponenten |
| --- | --- |
| Grundlagen & Aktionen | Card, Divider, Badge, Status, Avatar, Button, Icon Button, Button Group |
| Formulare | Form Field, Text Input, Search Field, Password Field, Textarea, Select, Checkbox, Radio Group, Switch, Segmented Control, Range, Number Stepper, File Upload / Dropzone |
| Navigation | Header, Side Navigation, Breadcrumbs, Tabs, Pagination, Prozess-Stepper |
| Feedback & Overlays | Alert, Toast, Tooltip, Popover, Dropdown Menu, Accordion, Progress Bar, Spinner, Skeleton, Modal Dialog, Drawer, Empty State |
| Daten & Inhalte | Data Table, KPI / Stat, List Group, Description List, Timeline |

Der vollständige Katalog in [index.html](index.html) zeigt alle 44 Komponenten mit realistischen Zuständen und bedienbarem Markup.

## Markup-Konventionen

Brams verwendet durchgehend BEM:

- Block: `.brams-card`
- Element: `.brams-card__header`
- Variante: `.brams-card--selected`
- Zustand: native Attribute wie `disabled`, `readonly`, `aria-invalid="true"`, `aria-selected="true"` oder `data-state="open"`

Alleinstehende Icon Buttons brauchen einen zugänglichen Namen. Dekorative Icons bleiben für Screenreader verborgen:

```html
<button class="brams-icon-button" aria-label="Einstellungen öffnen">
  <svg class="brams-icon" aria-hidden="true">
    <use href="icons.svg#settings"></use>
  </svg>
</button>
```

Interaktionen werden deklarativ gebunden. Styling-Klassen sind nicht gleichzeitig JavaScript-Hooks; dafür stehen `data-brams-*`-Attribute bereit:

```html
<button data-brams-open="#confirm-dialog">Dialog öffnen</button>

<div id="confirm-dialog" class="brams-overlay" hidden tabindex="-1">
  <section class="brams-dialog" role="dialog" aria-modal="true" aria-labelledby="dialog-title">
    <h2 id="dialog-title">Änderungen übernehmen?</h2>
    <button data-brams-close>Schließen</button>
  </section>
</div>
```

## Design Tokens

Die Tokens unter `:root` sind semantisch gruppiert: Farben, Typografie, Größen, Abstände, Fokus, technische Flächen, Signallichter, Schatten, Motion und Z-Index. Produkte können einzelne Werte überschreiben, ohne Komponenten zu kopieren:

```css
:root {
  --brams-color-accent: #11110f;
  --brams-signal-record: #b1261e;
  --brams-hairline: 1px solid var(--brams-color-border);
  --brams-motion-normal: 120ms;
}
```

Brams berücksichtigt `prefers-reduced-motion: reduce`. Der sichtbare Fokus ist über `--brams-focus-color` und `--brams-focus-ring` zentral steuerbar.

## Typografie

Brams bündelt [Archivo](https://github.com/Omnibus-Type/Archivo) lokal als offene, sachliche Grotesk mit historischen Bezügen zu Akzidenz-Grotesk, Helvetica und verwandten Schriften. Verwendet werden die statischen WOFF2-Schnitte Regular (400), Medium (500) und SemiBold (600) aus Commit `b5d63988ce19d044d3e10362de730af00526b672`; `font-display: swap` sorgt für robuste Darstellung ohne externe Font-Requests.

Die Gewichtssystematik bleibt bewusst ruhig: Fließtext und Eingaben nutzen 400, Überschriften, Navigation und Beschriftungen 500, Buttons, aktive Zustände und echte Hervorhebungen höchstens 600. Synthetisches Fett ist deaktiviert. Monospace bleibt Digitalanzeigen, Messwerten, Zeiten, Seriennummern und numerischen Modulindizes vorbehalten; dort werden tabellarische Ziffern verwendet.

Archivo steht unter der SIL Open Font License 1.1. Copyright und vollständiger Lizenztext werden separat unter [`fonts/OFL.txt`](fonts/OFL.txt) mitgeliefert. Die übrige Library bleibt unter der MIT-Lizenz dieses Repositories.

## Formensprache v1.1.0

- Warme Off-White-Flächen, technisches Grau und tiefes Schwarz bilden die Grundpalette. Rot ist Fehlern, Gefahr, Aufnahme und kleinen Betriebssignalen vorbehalten.
- Primäraktionen sind schwarz. Planare Komponenten bleiben bei 0 px; nur funktional runde Elemente wie Statuslampen, Dials, Avatare und Switch-Knöpfe sind kreisförmig.
- Standard-Cards bleiben schattenlos und werden durch Haarlinien, Flächenstufen und das zwölfspaltige Katalograster gegliedert. Nur räumliche Overlays erhalten Schatten.
- Archivo trägt die Oberfläche als lokal eingebundene Grotesk. Monospace ist funktionalen technischen Werten und Anzeigen vorbehalten.
- Success und Warning erscheinen auf neutralen Flächen mit grünen beziehungsweise bernsteinfarbenen Kontrollleuchten und zugänglichem Text.
- Hover, Fokus, Pressed, Selected und Disabled folgen einem gemeinsamen mechanischen Zustandsmodell. Interaktive Taster bewegen sich beim Drücken um genau einen Pixel; native Checkboxen und Radios behalten ihre Semantik und erhalten dieselbe ruhige Formensprache.
- Das zwölfspaltige Katalograster verwendet explizit kuratierte 5/7-, 7/5- und Vollbreitenpaare. Unterhalb von 56rem wechselt es bewusst in eine einspaltige Dokumentationsansicht.
- Hero, Systemübersicht und „Material & Service“ sind vollständig aus HTML und CSS konstruiert. Es gibt keine dekorativen Rasterbilder und keine externen Requests; die Formensprache wird durch Funktion, Maßstab und echte Zustände erklärt.
- Bei `prefers-reduced-motion: reduce` bleiben sämtliche Übergänge und Animationen vollständig ruhig.

## Katalogwerkzeuge

Der öffentliche Brams-Katalog lädt zusätzlich [`catalog.js`](catalog.js). Die Datei indexiert alle 44 Komponenten einschließlich ihrer `STATE`-, `INPUT`- und `API`-Metadaten, hält die schmale Katalognavigation beim Scrollen sichtbar und baut die unabhängigen Codepanels aus expliziten `<template>`-Beispielen auf. Diese Dokumentationslogik ist von der ausgelieferten Runtime in [`brams.js`](brams.js) getrennt.

`/` fokussiert den Komponentenfinder. Pfeiltasten wählen Treffer, Enter springt mit Hash und Fokus zur Komponente, Escape leert beziehungsweise schließt die Suche. Die Suche ignoriert Großschreibung und Diakritika. Jedes Beispiel bietet copy-ready HTML; imperative Beispiele ergänzen JavaScript. Falls die Clipboard API fehlt, erscheint ein markiertes Textfeld zum manuellen Kopieren.

Alle Hooks mit dem Präfix `data-brams-demo-*` sind ausschließlich katalogintern. Sie gehören nicht zur stabilen Library-API und dürfen in Produktoberflächen nicht als Brams-Schnittstelle verwendet werden.

## JavaScript-API

Interaktive Komponenten werden bei `DOMContentLoaded` automatisch initialisiert. Die globale API ist unter `window.Brams` verfügbar.

### `Brams.init(root = document)`

Initialisiert deklaratives Markup unterhalb von `root`. Wiederholte Aufrufe sind idempotent und registrieren keine doppelten Listener.

```js
const fragment = document.querySelector("#dynamic-content");
Brams.init(fragment);
```

### `Brams.open(target)` und `Brams.close(target)`

Öffnet beziehungsweise schließt Modal Dialog, Drawer, Popover oder Menü. `target` darf ein Element oder ein CSS-Selektor sein.

```js
Brams.open("#settings-drawer");
Brams.close(document.querySelector("#settings-drawer"));
```

Dialog und Drawer bieten Fokusfalle, Escape- und Backdrop-Schließen, Scroll-Lock, Fokuswiederherstellung und eine `inert`-Isolation des Hintergrunds für assistive Technologien. Bei gestapelten Overlays reagiert nur die oberste Ebene. Globale Live-Regionen bleiben erreichbar. Geöffnete und geschlossene Layer senden bubbling Events:

```js
document.addEventListener("brams:open", (event) => console.log(event.target));
document.addEventListener("brams:close", (event) => console.log(event.target));
```

### `Brams.toast(options)`

Erstellt einen zugänglichen Toast, hängt ihn an die Live-Region und gibt das erzeugte Element zurück.

```js
const notice = Brams.toast({
  title: "Gespeichert",
  message: "Control Unit 07 wurde aktualisiert.",
  tone: "success", // neutral | success | warning | danger
  duration: 5000,
});
```

Mit `duration: 0` bleibt ein Toast bis zum manuellen Schließen sichtbar.

## Deklarative Hooks

| Hook | Verhalten |
| --- | --- |
| `data-brams-open`, `data-brams-close` | Overlay öffnen oder schließen |
| `data-brams-popover`, `data-brams-tooltip`, `data-brams-menu` | Verknüpft Auslöser und Floating Layer |
| `data-brams-tabs`, `data-brams-segmented`, `data-brams-accordion` | Tastaturfähige Auswahl und Offenlegung |
| `data-brams-range`, `data-brams-number` | Live-Ausgabe und numerische Schritte |
| `data-brams-file` | Lokale Dateiauswahl und Dropzone; kein Upload |
| `data-brams-pagination`, `data-brams-process`, `data-brams-sortable` | Clientseitige Demo-Zustände |
| `data-brams-password-toggle`, `data-brams-search-clear` | Feldaktionen |
| `data-brams-toast-trigger`, `data-brams-alert-dismiss` | Feedback erzeugen oder entfernen |

### Pagination-Kompatibilität

Die korrekte BEM-Klasse für Seitentasten lautet `.brams-pagination__button`. Der versehentlich veröffentlichte Name `.brams-pagination__bramstton` bleibt als CSS-Kompatibilitätsalias bis zu einem späteren Major-Release erhalten.

Native Form Controls behalten ihre normalen `input`- und `change`-Events. Switch und Segmented Control senden zusätzlich ein bubbling `change`-Event, weil sie als Button-Patterns umgesetzt sind.

## Lokale Vorschau

```bash
python3 -m http.server 8080
```

Danach ist der Katalog unter <http://localhost:8080> erreichbar. Alternativ:

```bash
npm run preview
```

## Tests

Playwright und Axe sind reine Entwicklungsabhängigkeiten; die ausgelieferte Library bleibt dependency-frei.

```bash
npm ci
npx playwright install --with-deps chromium firefox webkit
npm test
```

Die Suite verwendet reproduzierbar zwei parallele Worker und der Testserver standardmäßig Port 4173. Beides kann ohne Konfigurationsänderung überschrieben werden:

```bash
BRAMS_TEST_WORKERS=4 BRAMS_TEST_PORT=4317 npm test
```

Die Suite prüft unter Chromium, Firefox und WebKit unter anderem:

- Laden ohne Konsolenfehler oder externe Requests, 44 vorhandene Katalogeinträge, drei lokale Schriftschnitte und keine dekorativen Bild-Assets
- idempotente Initialisierung, ARIA-Zustände und Tastaturmodelle
- Fokusfalle, Escape, Backdrop, Scroll-Lock und Fokuswiederherstellung
- Toast, Range, Number Stepper, Password, Dateiauswahl, Pagination und Tabellensortierung
- Desktop- und Mobile-Layouts ohne seitenweises horizontales Überlaufen
- Fokusdarstellung, WCAG-AA-Kontrast, Reduced Motion, Disabled-/Invalid-Zustände und visuelle Chromium-Snapshots
- genau eine vollständige `STATE`/`INPUT`/`API`-Spezifikationszeile je Komponente sowie Finder-Suche über diese Metadaten, Diakritika, Tastaturnavigation, Hash/Fokus und schmale Auto-Scrolling-Navigation
- vollständige Snippet-Abdeckung, unabhängige Codepanels, Clipboard- und sichtbarer manueller Fallback
- v1.1.0-Tokens, lokale Archivo-Schnitte, schwarze Primäraktionen, quadratische Geometrie, schattenlose Standard-Cards, native Checkboxen/Radios und beide Pagination-Klassen
- Zustandsmatrix für Buttons, Icon Buttons, Tabs, Segmente, Pagination, Checkbox, Radio, Switch und Eingaben unter Chromium, Firefox und WebKit
- Chromium-Gesamtkataloge bei 1440px, 1024px, 768px, 390px und 320px sowie Detailaufnahmen von Finder, Codepanel, Kontrollinstrument, Systemübersicht und Service-Abschluss

Chromium-Snapshots werden bewusst aktualisiert mit:

```bash
npm run test:update
```

Die automatisierten Accessibility-Prüfungen lassen sich separat ausführen:

```bash
npm run test:accessibility
```

Sie prüfen den statischen Katalog sowie geöffnete Finder-, Dialog-, Drawer-, Popover- und Menü-Zustände mit Axe gegen WCAG A/AA und relevante Best Practices. Diese Automatisierung ergänzt, ersetzt aber keine manuelle Prüfung mit Tastatur und Screenreader in einem konkreten Produkt.

`npm run test:release` prüft zusätzlich, dass Package-Manifest, Lockfile, Runtime, Katalog, README und Changelog dieselbe Versionsnummer tragen.

## Continuous Integration

GitHub Actions führt bei jedem Pull Request und jedem Push auf `main` einen sauberen `npm ci`-Install und die vollständige Suite in Chromium, Firefox und WebKit aus. Die CI verwendet Node 24.18.0 aus [`.nvmrc`](.nvmrc); die Action-Versionen sind auf geprüfte Commit-SHAs festgelegt.

## Versionierung und Releases

Ab v1.0.0 folgt Brams der semantischen Versionierung. Änderungen an der stabilen Library-API werden in [`CHANGELOG.md`](CHANGELOG.md) dokumentiert. Ein Release gilt erst als veröffentlicht, wenn Tag, GitHub Release und der öffentliche Katalog denselben geprüften Commit referenzieren.

## Browser

Unterstützt werden aktuelle Versionen von Chromium, Firefox und WebKit. v1.1.0 bewahrt die BEM-Klassen, `data-brams-*`-Hooks und die öffentliche JavaScript-API aus v0.3 bis v1.0. Neue Layout-, Spezifikations- und `data-brams-demo-*`-Hooks bleiben bewusst außerhalb dieser Kompatibilitätszusage.

<!-- github-cicd-policy -->
## Local validation policy

This repository does not use GitHub Actions or any other GitHub-hosted CI/CD. Run tests, linters, builds, and all other checks locally before merging. A documented successful local test run is sufficient for review and merge.
<!-- /github-cicd-policy -->
