Komponenten
Design language
An octagon with chamfered corners — never a radius, never a point.
Colours — the same shape, a different meaning
The shape is colour-independent. All values in oklch, unchanged from globals.css.
--goldPrimary, ring, accent--gold-dimSecondary voice--destructiveDestructive actions--warningAwaiting approval--cardCards, panels--bevelEdge of the chamfer — opaqueChamfer — two rows
One value cannot work: controls stay subtle (more was too harsh on a 32-px button), surfaces carry the slant clearly, otherwise it looks timid.
Design language
Formensprache
Die Tessera-Form: Kappung statt Rundung, Kante als evenodd-Ring, gemessene Bevel-Stufen. Grundlage aller weiteren Items.
The design language travels as a file, byte-identical — not as translated tokens. That leaves one source and nothing that can drift apart. Whoever pulls it also gets the repair rules, and those must stay unlayered: in Tailwind v4 the @layer rank beats specificity. Also worth knowing: hand-written @layer utilities classes get no responsive variants — sm:tsr-cut is never generated.
npx shadcn@latest add @tessera/formPrimitives
Button
Kappung an der Groessenvariante, nicht an der Aufrufstelle. Umriss-Variante traegt die Kante als Ring.
The chamfer hangs on the size variant, not on the call site. It used to sit in the className of every call — 19 places, some of which were always forgotten. The outline variant carries its edge as a ring, not as a border: on a chamfer a border only survives the straight edges, the slants stay empty.
npx shadcn@latest add @tessera/buttonPulls in: @tessera/form, utils
Card
Kappung 12px, Kante als Ring. Keine Rundung, kein ring-Utility — beide sind auf einer Kappung unsichtbar.
No ring-1. A ring lies outside the box and is removed completely by the chamfer — not half, entirely. The same goes for outline and box-shadow. Two ways remain: the evenodd ring in the pseudo-element or coloured padding on an identically shaped hull.
npx shadcn@latest add @tessera/cardPulls in: @tessera/form, utils
Dialog
Kappung 15px, mit Kopf, Fuss und Beschreibung. Traegt eine eigene Regel fuer den responsiven Fall, in dem der Dialog erst ab sm eine Kappung bekommt.
npx shadcn@latest add @tessera/dialogPulls in: @tessera/form, utils
Input
Traegt die Form, aber bewusst keine Huelle: die Kante kommt von FieldShell, weil sonst die className der Aufrufstellen mehrdeutig wird.
Carries the shape, but deliberately no hull. The edge would otherwise come from the className of twenty call sites and be ambiguous there — tailwind-merge lets, say, p-3.5 win against py-(--card-spacing). For fields with an edge: FieldShell.
npx shadcn@latest add @tessera/inputPulls in: @tessera/form, utils
Dropdown Menu
Kappung und Ring statt Schatten.
Chamfer and ring instead of shadow. Best seen open in the application itself.
npx shadcn@latest add @tessera/dropdown-menuPulls in: @tessera/form, utils
Tooltip
Kappung und Ring statt Schatten.
Chamfer and ring instead of shadow.
npx shadcn@latest add @tessera/tooltipPulls in: @tessera/form, utils
Sheet
Seitliches Panel auf Radix-Dialog. Kappung ueber die Rollen-Selektoren der Formensprache.
15px chamfer via the role selectors. An open sheet would cover the catalogue — best seen in the app-shell on narrow screens.
npx shadcn@latest add @tessera/sheetPulls in: @tessera/form, utils
Skeleton
Ladeplatzhalter. Traegt keine Kante — eine Flaeche, die noch niemand ist.
npx shadcn@latest add @tessera/skeletonPulls in: @tessera/form, utils
Separator
Trennlinie in Haarstaerke.
Above the line
Below the line
npx shadcn@latest add @tessera/separatorPulls in: @tessera/form, utils
Tabs
Base-UI-Tabs. Die Kappung der Ausloeser kommt zentral ueber [role=tab] aus der Formensprache.
[role=tab].npx shadcn@latest add @tessera/tabsPulls in: @tessera/form, utils
Breadcrumb
Brotkrumen-Pfad; lange Pfade klappen die Mitte in ein Dropdown (siehe page-shell).
npx shadcn@latest add @tessera/breadcrumbPulls in: @tessera/form, utils
ScrollArea
Scroll-Flaeche mit eigener, schmaler Leiste.
Row 1 — the bar belongs to the surface, not the window.
Row 2 — the bar belongs to the surface, not the window.
Row 3 — the bar belongs to the surface, not the window.
Row 4 — the bar belongs to the surface, not the window.
Row 5 — the bar belongs to the surface, not the window.
Row 6 — the bar belongs to the surface, not the window.
Row 7 — the bar belongs to the surface, not the window.
Row 8 — the bar belongs to the surface, not the window.
npx shadcn@latest add @tessera/scroll-areaPulls in: @tessera/form, utils
Collapsible
Auf- und zuklappender Ast, traegerlos — die Form kommt vom Inhalt.
npx shadcn@latest add @tessera/collapsiblePulls in: @tessera/form, utils
Table
Datentabelle mit Kopf, Fuss und Zeilenmarkierung. Grundlage jedes Gitters.
| Package | Release | Size |
|---|---|---|
| @dev0zzz.tessera.at/sdk | 0.4.1 | 184 kB |
| @dev0zzz.tessera.at/cli | 0.2.0 | 92 kB |
| @dev0zzz.tessera.at/ui | 0.1.3 | 311 kB |
| Total | 587 kB | |
npx shadcn@latest add @tessera/tablePulls in: @tessera/form, utils
Pagination
Seitenwechsel als nav mit Liste und aria-current. Bringt paginationRange mit — welche Zahlen sichtbar sind, entscheidet nicht die Aufrufstelle.
Page 7 of 42
npx shadcn@latest add @tessera/paginationPulls in: @tessera/form, @tessera/button, utils
ColumnResizer
Ziehgriff fuer Spaltenbreiten. Button mit role=separator statt div — mit Pfeiltasten bedienbar, Breite als aria-valuenow.
| Release | Channel |
|---|---|
| v0.5.2 — design language | Radicle |
| v0.5.1 — dialogs | Radicle |
180 px — arrow keys ±8, with Shift ±80, double-click resets
npx shadcn@latest add @tessera/column-resizerPulls in: @tessera/form, utils
DataGrid
Tabelle mit Sortierung, Auswahl und ziehbaren Spalten. Haelt keinen Zustand — sortiert wird bei jeder ernsthaften Menge auf dem Server.
| v0.0.0 | Radicle | withdrawn | 2026-01-01 | 120 | |
| v0.0.1 | GitHub | signed | 2026-02-02 | 157 | |
| v0.0.2 | npmjs | signed | 2026-03-03 | 194 | |
| v0.0.3 | Radicle | draft | 2026-04-04 | 231 | |
| v0.1.0 | GitHub | signed | 2026-05-05 | 268 | |
| v0.1.1 | npmjs | signed | 2026-06-06 | 305 | |
| v0.1.2 | Radicle | draft | 2026-07-07 | 342 | |
| v0.1.3 | GitHub | withdrawn | 2026-08-08 | 379 |
npx shadcn@latest add @tessera/data-gridPulls in: @tessera/form, @tessera/table, @tessera/checkbox, @tessera/column-resizer, @tessera/skeleton, utils
Checkbox
Kaestchen — benannte Ausnahme der Formensprache: es behaelt seine eigene Form.
npx shadcn@latest add @tessera/checkboxPulls in: @tessera/form, utils
Label
Beschriftung eines Feldes, verknuepft ueber htmlFor.
npx shadcn@latest add @tessera/labelPulls in: @tessera/form, utils
Textarea
Mehrzeiliges Feld. Ohne Ziehgriff — der sitzt in der Ecke, die die Kappung wegschneidet; die Hoehe kommt aus rows, das Mitwachsen schaltet die Aufrufstelle zu.
npx shadcn@latest add @tessera/textareaPulls in: @tessera/form, utils
InputGroup
Feld mit Beiwerk — Lupe davor, Knopf dahinter, Zaehler darunter. Die zweite Huelle neben FieldShell, weiterhin genau ein Feld pro Huelle.
npx shadcn@latest add @tessera/input-groupPulls in: @tessera/form, @tessera/input, @tessera/textarea, utils
Popover
Freie Flaeche an einem Ausloeser. Kein Menue — die Pfeiltasten bleiben unangetastet, damit ein Formular darin bedienbar ist.
npx shadcn@latest add @tessera/popoverPulls in: @tessera/form, utils
Calendar
Monatsraster auf react-day-picker. Der Balken einer Spanne bleibt ein Rechteck — gekappt wird der Tagesknopf darauf.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
npx shadcn@latest add @tessera/calendarPulls in: @tessera/form, @tessera/button, utils
DatePicker
Datum und Zeitraum aus einem Kalender im Popover. Der Ausloeser ist ein Feld, kein Knopf; getippt wird nicht.
npx shadcn@latest add @tessera/date-pickerPulls in: @tessera/form, @tessera/calendar, @tessera/popover, utils
Select
Auswahl aus einer festen Liste. Der Ausloeser ist ein Feld, keine Schaltflaeche — Hoehe und Kappung folgen dem Input.
npx shadcn@latest add @tessera/selectPulls in: @tessera/form, utils
Combobox
Auswahl mit Tippen, einfach und mehrfach. Die Mehrfachauswahl steckt mit drin — Chips als Huelle, ein Chip je gewaehltem Wert.
npx shadcn@latest add @tessera/comboboxPulls in: @tessera/form, utils
ToggleGroup
Segmentierte Auswahl. Die Gruppe traegt die Kappung des Kastens, jeder Knopf darin seine eigene.
npx shadcn@latest add @tessera/toggle-groupPulls in: @tessera/form, utils
Sidebar
Die shadcn-Sidebar-Primitive: Provider, Flaechen, Menue, Rail. Grundlage des app-shell.
npx shadcn@latest add @tessera/sidebarPulls in: @tessera/button, @tessera/input, @tessera/tooltip, @tessera/sheet, @tessera/skeleton, @tessera/separator, @tessera/form, utils
Atoms
Badge
Kappung 6px.
npx shadcn@latest add @tessera/badgePulls in: @tessera/form, utils
CodeBlock
Rendert code oder pre und ersetzt die sieben identischen Klassenketten, die vorher von Hand wiederholt wurden.
npx shadcn@latest add @tessera/buttonnpx shadcn@latest add @tessera/code-blockPulls in: @tessera/form, utils
FieldShell
Kappung und Ring fuer ein einzelnes Feld. Traegt die Kante, die das Input bewusst nicht selbst traegt.
npx shadcn@latest add @tessera/field-shellPulls in: @tessera/form, utils
Toggle
Zweiwertiger Umschalter, gekappt.
npx shadcn@latest add @tessera/togglePulls in: @tessera/form, utils
SearchInput
Suchfeld mit Lupe, gekappt und mit Kante.
npx shadcn@latest add @tessera/search-inputPulls in: @tessera/form, @tessera/input, utils
Logo
Der Achteck-Pfad. Ursprung der 25-Prozent-Kappung: 14 von 56 Einheiten in einer 64er-Box.
Origin of the chamfer. The path M18 4 H46 L60 18 … in a 64-unit box: the edge runs from 4 to 60, so 56 units, 14 of them cut —25 %. Not the 29.29 % of the regular octagon; those are geometrically correct and still wrong for this brand.
npx shadcn@latest add @tessera/logoTesseraStart
Der Marken-Knopf.
Filled, never outlined-with-a-hollow-core. The gold belongs to the primary action, and that is Create @handle — only signed-out visitors see these buttons, and they are usually new here. Three drafts lie behind this: gold border with a hollow core (over-engineered), gold for both (then the colour no longer says what is primary), emphasis swapped. Now the component derives the look from intent, so an app cannot pick it wrongly. Both fills are opaque, hence independent of the background.
npx shadcn@latest add @tessera/tessera-startPulls in: @tessera/form, @tessera/logo, utils
OrgCrest
Wappen einer Organisation, im Achteck.
npx shadcn@latest add @tessera/org-crestPulls in: @tessera/form, utils
ActorAvatar
Form nach Herkunft: Tessera-Konten im Achteck mit Goldrand, alle anderen rund. Der Rand ist Polsterung auf gleich geformter Huelle, weil ein ring auf einer Kappung verschwindet.
The shape states the origin: Tessera accounts in the octagon with a gold border, everyone else round. isTesseraActor checks with endsWith against .tessera.at — never with includes, or tessera.at.evil.example could pass itself off as native. Known limit: Tessera accounts on their own domain read as foreign and get the circle.
npx shadcn@latest add @tessera/actor-avatarPulls in: @tessera/form, @tessera/actor-origin, utils
ActorIdentity
Wie ein Konto in Tessera erscheint: Avatar, Anzeigename, darunter das Handle mit @. Eine Figur fuer jede Stelle, an der ein Konto auftaucht.
npx shadcn@latest add @tessera/actor-identityPulls in: @tessera/actor-avatar, @tessera/form, utils
PathCrumbs
Der Pfad zum aktuellen Ort, Segment fuer Segment klickbar. Mono, weil die Segmente Dateinamen sind; das letzte Segment traegt aria-current statt nur Farbe.
npx shadcn@latest add @tessera/path-crumbsPulls in: @tessera/form, utils
ContentSurface
Die Flaeche, auf der der Anwendungsinhalt sitzt: ein eigener Layer unter der Tab-Leiste, mit Tessera-Kante und optional mit vertikalen Reitern am Rand.
Description
The content stands on its own plate with the Tessera edge. The tabs at the rim subdivide within the tab and switch with the surface, not with the app.
npx shadcn@latest add @tessera/content-surfacePulls in: @tessera/form, utils
SearchSyntaxHint
Das Fragezeichen am Suchfeld: zeigt feld:wert, Phrase, Ausschluss und Groessenvergleich mit den echten Feldnamen der Suche. Eine Syntax, die niemand sieht, benutzt niemand.
npx shadcn@latest add @tessera/search-syntax-hintPulls in: @tessera/popover, @tessera/button, @tessera/form
Blocks
AppShell
Das Grundgeruest einer Tessera-App: Sidebar mit Navigationsbaum, Inhalt als Inset. Kopf, Fuss und Suche sind Slots — Business gehoert in die Page.
npx shadcn@latest add @tessera/app-shellPulls in: @tessera/sidebar, @tessera/collapsible, @tessera/dropdown-menu, @tessera/form, utils
PageShell
Das Geruest jeder Listen- und Werkzeugseite: Kopfzeile mit Brotkrumen und Navigation, Tabs mit URL-Sync und Werkzeugleisten-Registry, darunter die Inhaltsflaeche. Suche ist ein Slot.
The content surface belongs to the page — a grid would stand here.
Header, tabs and toolbar are scaffold, not content.
npx shadcn@latest add @tessera/page-shellPulls in: @tessera/content-surface, @tessera/tabs, @tessera/breadcrumb, @tessera/dropdown-menu, @tessera/button, @tessera/badge, @tessera/sidebar, @tessera/form, utils
DetailPage
Vorlage einer Detailseite: Kopfzeile mit Nachbar-Navigation, Brotkrumen-Slot und Tab-Leiste, dazu das L aus Identitaetsleiste und Kontext-Rail — beide Arme falten einzeln, der gefaltete Streifen uebernimmt die Identitaet.
skytess
rad:z3vhVW… — signed provenance
npx shadcn@latest add @tessera/detail-pagePulls in: @tessera/page-shell, @tessera/button, @tessera/card, @tessera/popover, @tessera/sidebar, @tessera/form, utils
CommandPalette
Eine Suche ueber alles, auf ⌘K: gruppierte Treffer aus mehreren Quellen, Tastaturnavigation, Hervorhebung und Verlauf. Eine tote Quelle nimmt die anderen nicht mit.
Nothing chosen.
npx shadcn@latest add @tessera/command-palettePulls in: @tessera/dialog, @tessera/search-sources, @tessera/form, utils
AccountFooter
Der angemeldete Sidebar-Fuss: Guthaben, Zap und das Konto als Menue. Ausgeklappt Wallet-Zeile und Identitaetszeile, in der Icon-Leiste Avatar, Zap und Abmelden als eigene Knoepfe. Der Zap-Popover waehlt Empfaenger und Betrag hier — das Fenster auf tessera.at bestaetigt nur.
wallet linked
no wallet
npx shadcn@latest add @tessera/account-footerPulls in: @tessera/actor-avatar, @tessera/actor-identity, @tessera/dropdown-menu, @tessera/popover, @tessera/form, utils
SmartGrid
Die vollstaendige Liste: Suche, Facetten, Sortierung, Auswahl, Spaltenbreiten, Seitenwechsel und CSV-Export. Die Suche steckt hinter dem unified-search-Adapter — angeschlossen ist nichts.
npx shadcn@latest add @tessera/smart-gridPulls in: @tessera/data-grid, @tessera/pagination, @tessera/select, @tessera/dropdown-menu, @tessera/toggle-group, @tessera/button, @tessera/badge, @tessera/search-input, @tessera/search-syntax-hint, @tessera/csv-export, @tessera/unified-search, @tessera/form, utils
Library
actor-origin
isTesseraActor prueft mit endsWith auf .tessera.at — nie mit includes, sonst kann sich tessera.at.evil.example als heimisch ausgeben.
npx shadcn@latest add @tessera/actor-origincsv-export
CSV und ausschliesslich CSV. Quotet nach RFC 4180, entschaerft fuehrende Formelzeichen und schreibt die Bytefolgenmarkierung, damit Excel Umlaute liest.
npx shadcn@latest add @tessera/csv-exportsearch-query
Die Abfragesprache des Suchfelds: feld:wert, "exakte Phrase", -ausschluss und datum>2026-01. Zerlegt nur — gefunden wird woanders.
npx shadcn@latest add @tessera/search-querysearch-sources
Mehrere Quellen, eine Frage: fragt sie nebeneinander, gruppiert nach Herkunft und laesst eine tote Quelle die anderen nicht mitnehmen. Dazu die Hervorhebung der Treffer.
npx shadcn@latest add @tessera/search-sourcesunified-search
Die eine Schnittstelle, hinter der jede Suche steckt — Speicher, SQL oder Meilisearch. Mitgeliefert ist der Adapter fuer Listen, die schon da sind; angeschlossen ist nichts.
npx shadcn@latest add @tessera/unified-searchPulls in: @tessera/search-query
Anmeldung mit Tessera
Der komplette OIDC-Login gegen id.tessera.at: Session als verschluesseltes Cookie (iron-session), Login-/Callback-/Logout-Routen mit PKCE-Transaktions-Cookie, einmaliger Selbstheilung und RP-initiiertem Logout. Kanonische Quelle ist start-simple.
npx shadcn@latest add @tessera/auth-oidcSlider — track and moving part
Not a registry item — the slider so far lives only in this app. Track and moving part carry the shape individually; the element itself stays unclipped, a clip on it would cut the thumb off at the ends. The gold fill needs the value and therefore comes from the Slider atom, not from the CSS.
The rules
- The shape is a token. One definition in
@dev0zzz.tessera.at/sdk/form.css, applied everywhere — not rebuilt per component. - The shape is colour-independent. Gold, red, amber: the same silhouette, a different meaning.
- Focus sits inside. Measured in the browser: everything outside the shape gets clipped — outline, ring, shadow.
- Exceptions are named. Checkboxes, radios, switches, avatars and floating layers (menu, tooltip) keep their shape and their shadows.
- The mark is not repeated. It stands large where it works — header, passkey screen. Not in every button: on the front page it otherwise appeared five times. Here the brand carries the shape.
ui/is never touched. The language hooks in via thedata-slotattributes that shadcn sets itself.