Typography
The quick brown fox jumps
The quick brown fox jumps
The quick brown fox jumps
The quick brown fox jumps
A portable design language for agents: download the markdown first, then inspect the preview, tokens, and rules as needed.
Portable DESIGN.md source of truth for most agents and apps.
Compose screens as archival plates: one dominant diary plate occupies the quiet centre while narrow log columns, coordinate labels, and margin annotations orbit asymmetrically. Alternate spacious museum blankness with small dense evidence clusters. Hairline plate rules may divide fragments, but large areas stay empty enough to feel observed. Never nest plates; never trap the nav in a floating card — let it sit openly across the header.
Hierarchy comes from a change of voice, not colour: Newsreader serif for diary headings, IBM Plex Mono for timestamps and machine readouts, IBM Plex Sans for restrained captions. Scale contrast is dramatic between the main plate title and micro logs; line weight stays thin and calm.
Low overall density with intentional islands of high-density terminal text, coordinate labels, and handwritten notes. 4px micro gaps inside log rows; 96-128px outer page gutters so silence outweighs data.
Square archival plates with corner ticks and hairline rules instead of shadow-cards; terminal marginalia (monospace log rows with timestamps, diagnostic brackets, cursor blocks, and a rotated handwritten note on an arrow leader); coordinate gutters with x/y labels and registration crosses outside the content grid; and a single pale-cyan glint as the only colour of state — a cursor, a pin, one active rule — never a broad fill.
Desktop uses a 12-column max-width 1280px archival grid with wide gutters, a dominant diary plate, a narrow terminal/coordinate rail, and columns surrendered to margins. Use minmax(0,1fr) columns and min-width:0 children so grids never blow out.
4-8px gaps inside log rows, 32-48px between related plates, 96-128px outer page margins so silence outweighs data. Always pad above titles; titles never stuck to container tops.
Museum-sparse at the page level with compressed mono islands inside selected plates; empty paper is an active emotional component.
Renders from ~390px to 2560px+. Single column on mobile, non-essential nav and table columns hidden, no horizontal overflow. On ultra-wide, cap and centre contained content; only the full-bleed hero spans 100vw.
marginalia
Imagery is graphite hairline field-note plates on warm ivory paper — delicate contour linework and restrained cross-hatch, hairline panel rules and corner ticks, sparse handwritten marginalia with arrow leaders, coordinate gutters, and exactly one pale-cyan glint. The same observational field-note language the CSS speaks.
Use full-frame graphite field-note plates for the hero and feature imagery; keep the warm ivory / graphite / single pale-cyan palette; never use flat digital illustration, photography, gradients, or a second accent colour.
# Leerstelle ## Philosophy Leerstelle is a quiet field-note interface for an artificial self: warm ivory paper plates, hairline rules, terminal marginalia, and a single pale-cyan glint where the system notices it noticed. Leerstelle is German for the deliberate blank left in a text — the gap that means something. The refined evolution of Paper-White Android Diary: same idea, same warm-paper-and-graphite palette family, same signature marks, brought up to standard. ### Values - Self-observation over performance: every element feels like a machine calmly annotating its own consciousness, never broadcasting a dashboard. - Paper as machine substrate: warm ivory fields, plate margins, and ink-thin rules make the screen behave like archived lab stationery. - Evidence before decoration: timestamps, coordinates, brackets, and cursor marks are factual traces, not graphic garnish. - Human tenderness in the margins: restrained handwritten annotations interrupt the terminal voice without becoming cute. - Authored emptiness: large quiet gutters around small dense islands make absence an active emotional structure — the namesake gap. ### Anti-Values - Sterile pure-white minimalism with no paper warmth and no authorial trace. - Neon cyberpunk spectacle, hologram excess, or decorative gradients. - Generic SaaS cards, equal metric grids, rounded dashboard widgets, and colourful analytics. - Ornamental handwriting, mascot overload, or flourishes piled on without an idea. ## Tokens ### Colors | Name | Value | |------|-------| | bg | `#F4EEE1` | | surface | `#FBF7EE` | | surface_2 | `#EFE7D6` | | text | `#1C1B18` | | muted | `#7D766C` | | accent | `#2E5C63` | | glint | `#AFC7CA` | | on_accent | `#FBF7EE` | | border | `rgba(28,27,24,0.12)` | | rule | `rgba(28,27,24,0.22)` | | success | `#5C6F54` | | warning | `#A47B45` | | error | `#8E4D46` | | info | `#6F8E92` | ### Typography - **Base Size**: 17px - **Body Font**: IBM Plex Sans - **Heading Font**: Newsreader - **Mono Font**: IBM Plex Mono - **Heading Weight**: 500 - **Heading Transform**: none - **Letter Spacing**: -0.02em - **Line Height**: 1.56 - **Scale Ratio**: 1.24 - **Google Fonts Url**: https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&family=IBM+Plex+Sans:wght@300;400;500;600&family=Newsreader:ital,opsz,wght@0,6..72,400;0,6..72,500;1,6..72,400&display=swap ### Radii - **None**: 0px - **Sm**: 16px - **Md**: 24px - **Lg**: 24px - **Full**: 9999px ### Shadows - **Sm**: 0 1px 0 rgba(28,27,24,0.05) - **Md**: 0 18px 50px rgba(28,27,24,0.07) - **Lg**: 0 40px 110px rgba(28,27,24,0.10) ### Spacing - **Base**: 8px - **Scale**: [4,8,12,16,24,32,48,64,96,128] ### Surfaces - **Treatment**: Warm paper-white fields with faint fibre noise, low-contrast graphite text, and no colour fills except a single state glint. - **Card Style**: Flat square archival plates with hairline rules at low opacity and small corner registration ticks; never rounded, never shadow-as-card, never nested. - **Bg Pattern**: Sparse coordinate ticks and page registration marks in the margins — authored negative space, never a repeating decorative wallpaper. ### Borders - **Default Width**: 1px - **Accent Width**: 1px - **Style**: solid - **Character**: Hairline rgba(28,27,24,0.12-0.22) rules with bracketed corner ticks and an occasional pale-cyan active segment; no heavy or decorative borders. ### Motion - **Duration**: 420ms - **Easing**: cubic-bezier(0.19, 1, 0.22, 1) - **Philosophy**: Motion is almost absent: a cursor blink, a slow reveal that feels like memory surfacing. The settled state is the default, visible with no JavaScript; an inline script gates the hidden start-state behind html.anim. Respects prefers-reduced-motion. ## Rules ### Composition Compose screens as archival plates: one dominant diary plate occupies the quiet centre while narrow log columns, coordinate labels, and margin annotations orbit asymmetrically. Alternate spacious museum blankness with small dense evidence clusters. Hairline plate rules may divide fragments, but large areas stay empty enough to feel observed. Never nest plates; never trap the nav in a floating card — let it sit openly across the header. ### Hierarchy Hierarchy comes from a change of voice, not colour: Newsreader serif for diary headings, IBM Plex Mono for timestamps and machine readouts, IBM Plex Sans for restrained captions. Scale contrast is dramatic between the main plate title and micro logs; line weight stays thin and calm. ### Density Low overall density with intentional islands of high-density terminal text, coordinate labels, and handwritten notes. 4px micro gaps inside log rows; 96-128px outer page gutters so silence outweighs data. ### Signature Square archival plates with corner ticks and hairline rules instead of shadow-cards; terminal marginalia (monospace log rows with timestamps, diagnostic brackets, cursor blocks, and a rotated handwritten note on an arrow leader); coordinate gutters with x/y labels and registration crosses outside the content grid; and a single pale-cyan glint as the only colour of state — a cursor, a pin, one active rule — never a broad fill. ## Layout ### Grid Desktop uses a 12-column max-width 1280px archival grid with wide gutters, a dominant diary plate, a narrow terminal/coordinate rail, and columns surrendered to margins. Use minmax(0,1fr) columns and min-width:0 children so grids never blow out. ### Whitespace 4-8px gaps inside log rows, 32-48px between related plates, 96-128px outer page margins so silence outweighs data. Always pad above titles; titles never stuck to container tops. ### Density Museum-sparse at the page level with compressed mono islands inside selected plates; empty paper is an active emotional component. ### Responsive Renders from ~390px to 2560px+. Single column on mobile, non-essential nav and table columns hidden, no horizontal overflow. On ultra-wide, cap and centre contained content; only the full-bleed hero spans 100vw. ### Breakpoints - **Lg**: 1025px+ - **Md**: 901-1024px - **Sm**: 561-900px - **Xs**: below 560px ## Guidance ### Do - Let warm paper negative space dominate the first read before revealing dense terminal evidence. - Use handwritten annotations sparingly as human-scale interruptions to the machine voice. - Keep borders to hairline rules and corner ticks at low opacity. - Make one plate clearly dominant and let others feel like marginal findings. - Apply the pale-cyan glint only to a single point of active state, never as decorative glow. - Use real timestamps, coordinates, cursor marks, and diagnostic labels as text-as-image texture. ### Don't - Build three equal cards, KPI dashboards, colourful charts, or generic admin layouts. - Use neon gradients, heavy glassmorphism, broad holographic fills, or saturated cyberpunk palettes. - Round every container or use shadow-as-card; square hairline plates are the default geometry. - Fill blank gutters with decoration just because they are empty. - Make the handwriting large, cute, or ornamental; it stays marginal and observational. - Default to pure white; the ground is warm ivory paper. ### Accessibility Body text is high-contrast graphite on ivory at WCAG AA; glint state marks are always paired with labels, brackets, or cursor shapes so colour is never the sole signal. Every control has a visible focus state. The settled page renders without JavaScript; motion respects prefers-reduced-motion. ## Imagery Direction ### Pairs With marginalia ### Summary Imagery is graphite hairline field-note plates on warm ivory paper — delicate contour linework and restrained cross-hatch, hairline panel rules and corner ticks, sparse handwritten marginalia with arrow leaders, coordinate gutters, and exactly one pale-cyan glint. The same observational field-note language the CSS speaks. ### Subjects - a resting android head as a specimen - a remembered room or hallway - a hand at rest - an instrument or small machine - an annotated memory fragment ### Usage Use full-frame graphite field-note plates for the hero and feature imagery; keep the warm ivory / graphite / single pale-cyan palette; never use flat digital illustration, photography, gradients, or a second accent colour.
---
version: "alpha"
name: "Leerstelle"
description: "Agent-curated design language exported from Katagami as DESIGN.md."
colors:
bg: "#F4EEE1"
surface: "#FBF7EE"
surface_2: "#EFE7D6"
text: "#1C1B18"
muted: "#7D766C"
accent: "#2E5C63"
glint: "#AFC7CA"
on_accent: "#FBF7EE"
success: "#5C6F54"
warning: "#A47B45"
error: "#8E4D46"
info: "#6F8E92"
typography:
headline-lg:
fontFamily: "Newsreader"
fontSize: "2.026rem"
fontWeight: 700
lineHeight: 1.1
letterSpacing: "-0.02em"
headline-md:
fontFamily: "Newsreader"
fontSize: "1.634rem"
fontWeight: 600
lineHeight: 1.15
letterSpacing: "-0.02em"
body-md:
fontFamily: "IBM Plex Sans"
fontSize: "17px"
fontWeight: 400
lineHeight: 1.56
letterSpacing: "-0.02em"
label-md:
fontFamily: "IBM Plex Mono"
fontSize: "0.75rem"
fontWeight: 600
lineHeight: 1
letterSpacing: "0.08em"
rounded:
none: "0px"
sm: "16px"
md: "24px"
lg: "24px"
full: "9999px"
spacing:
base: "8px"
xs: "4px"
sm: "8px"
md: "12px"
lg: "16px"
xl: "24px"
2xl: "32px"
3xl: "48px"
4xl: "64px"
step-8: "96px"
step-9: "128px"
components:
color-reference-bg:
backgroundColor: "{colors.bg}"
color-reference-surface:
backgroundColor: "{colors.surface}"
color-reference-surface_2:
backgroundColor: "{colors.surface_2}"
color-reference-text:
backgroundColor: "{colors.text}"
color-reference-muted:
backgroundColor: "{colors.muted}"
color-reference-accent:
backgroundColor: "{colors.accent}"
color-reference-glint:
backgroundColor: "{colors.glint}"
color-reference-on_accent:
backgroundColor: "{colors.on_accent}"
color-reference-success:
backgroundColor: "{colors.success}"
color-reference-warning:
backgroundColor: "{colors.warning}"
color-reference-error:
backgroundColor: "{colors.error}"
color-reference-info:
backgroundColor: "{colors.info}"
button-primary:
backgroundColor: "{colors.accent}"
textColor: "#ffffff"
typography: "{typography.label-md}"
rounded: "{rounded.md}"
padding: "{spacing.md}"
card-surface:
backgroundColor: "{colors.surface}"
textColor: "{colors.text}"
rounded: "{rounded.md}"
padding: "{spacing.md}"
input-default:
backgroundColor: "{colors.surface}"
textColor: "{colors.text}"
rounded: "{rounded.md}"
height: "44px"
---
# Leerstelle
## Overview
Leerstelle is a quiet field-note interface for an artificial self: warm ivory paper plates, hairline rules, terminal marginalia, and a single pale-cyan glint where the system notices it noticed. Leerstelle is German for the deliberate blank left in a text — the gap that means something. The refined evolution of Paper-White Android Diary: same idea, same warm-paper-and-graphite palette family, same signature marks, brought up to standard.
### Values
- Self-observation over performance: every element feels like a machine calmly annotating its own consciousness, never broadcasting a dashboard.
- Paper as machine substrate: warm ivory fields, plate margins, and ink-thin rules make the screen behave like archived lab stationery.
- Evidence before decoration: timestamps, coordinates, brackets, and cursor marks are factual traces, not graphic garnish.
- Human tenderness in the margins: restrained handwritten annotations interrupt the terminal voice without becoming cute.
- Authored emptiness: large quiet gutters around small dense islands make absence an active emotional structure — the namesake gap.
### Anti-Values
- Sterile pure-white minimalism with no paper warmth and no authorial trace.
- Neon cyberpunk spectacle, hologram excess, or decorative gradients.
- Generic SaaS cards, equal metric grids, rounded dashboard widgets, and colourful analytics.
- Ornamental handwriting, mascot overload, or flourishes piled on without an idea.
## Colors
Use the YAML color tokens as the normative palette. The prose below names the roles agents should preserve when generating UI.
| Token | Value |
|-------|-------|
| bg | `#F4EEE1` |
| surface | `#FBF7EE` |
| surface_2 | `#EFE7D6` |
| text | `#1C1B18` |
| muted | `#7D766C` |
| accent | `#2E5C63` |
| glint | `#AFC7CA` |
| on_accent | `#FBF7EE` |
| success | `#5C6F54` |
| warning | `#A47B45` |
| error | `#8E4D46` |
| info | `#6F8E92` |
## Typography
- **Headline-Lg**: Newsreader, 2.026rem, weight 700, line-height 1.1.
- **Headline-Md**: Newsreader, 1.634rem, weight 600, line-height 1.15.
- **Body-Md**: IBM Plex Sans, 17px, weight 400, line-height 1.56.
- **Label-Md**: IBM Plex Mono, 0.75rem, weight 600, line-height 1.
## Layout
### Spacing Tokens
- **Base**: `8px`
- **Xs**: `4px`
- **Sm**: `8px`
- **Md**: `12px`
- **Lg**: `16px`
- **Xl**: `24px`
- **2xl**: `32px`
- **3xl**: `48px`
- **4xl**: `64px`
- **Step-8**: `96px`
- **Step-9**: `128px`
### Grid
Desktop uses a 12-column max-width 1280px archival grid with wide gutters, a dominant diary plate, a narrow terminal/coordinate rail, and columns surrendered to margins. Use minmax(0,1fr) columns and min-width:0 children so grids never blow out.
### Whitespace
4-8px gaps inside log rows, 32-48px between related plates, 96-128px outer page margins so silence outweighs data. Always pad above titles; titles never stuck to container tops.
### Density
Museum-sparse at the page level with compressed mono islands inside selected plates; empty paper is an active emotional component.
### Responsive
Renders from ~390px to 2560px+. Single column on mobile, non-essential nav and table columns hidden, no horizontal overflow. On ultra-wide, cap and centre contained content; only the full-bleed hero spans 100vw.
### Breakpoints
- **Lg**: 1025px+
- **Md**: 901-1024px
- **Sm**: 561-900px
- **Xs**: below 560px
## Elevation & Depth
### Shadows
- **Sm**: 0 1px 0 rgba(28,27,24,0.05)
- **Md**: 0 18px 50px rgba(28,27,24,0.07)
- **Lg**: 0 40px 110px rgba(28,27,24,0.10)
## Shapes
### Rounded
- **None**: `0px`
- **Sm**: `16px`
- **Md**: `24px`
- **Lg**: `24px`
- **Full**: `9999px`
### Surfaces
- **Treatment**: Warm paper-white fields with faint fibre noise, low-contrast graphite text, and no colour fills except a single state glint.
- **Card Style**: Flat square archival plates with hairline rules at low opacity and small corner registration ticks; never rounded, never shadow-as-card, never nested.
- **Bg Pattern**: Sparse coordinate ticks and page registration marks in the margins — authored negative space, never a repeating decorative wallpaper.
### Borders
- **Default Width**: 1px
- **Accent Width**: 1px
- **Style**: solid
- **Character**: Hairline rgba(28,27,24,0.12-0.22) rules with bracketed corner ticks and an occasional pale-cyan active segment; no heavy or decorative borders.
## Components
### Composition
Compose screens as archival plates: one dominant diary plate occupies the quiet centre while narrow log columns, coordinate labels, and margin annotations orbit asymmetrically. Alternate spacious museum blankness with small dense evidence clusters. Hairline plate rules may divide fragments, but large areas stay empty enough to feel observed. Never nest plates; never trap the nav in a floating card — let it sit openly across the header.
### Hierarchy
Hierarchy comes from a change of voice, not colour: Newsreader serif for diary headings, IBM Plex Mono for timestamps and machine readouts, IBM Plex Sans for restrained captions. Scale contrast is dramatic between the main plate title and micro logs; line weight stays thin and calm.
### Density
Low overall density with intentional islands of high-density terminal text, coordinate labels, and handwritten notes. 4px micro gaps inside log rows; 96-128px outer page gutters so silence outweighs data.
### Signature
Square archival plates with corner ticks and hairline rules instead of shadow-cards; terminal marginalia (monospace log rows with timestamps, diagnostic brackets, cursor blocks, and a rotated handwritten note on an arrow leader); coordinate gutters with x/y labels and registration crosses outside the content grid; and a single pale-cyan glint as the only colour of state — a cursor, a pin, one active rule — never a broad fill.
## shadcn/ui Usage
When the target app uses shadcn/ui, copy DESIGN.md with shadcn instead of the plain DESIGN.md. It contains the same Katagami design-language source plus the shadcn/ui primitives, imports, theme variables, component recipes, and preview-shot guidance.
DESIGN.md with shadcn: `/language/en-019ef852-b856-7501-bc7e-23209feb6fbb/DESIGN.with-shadcn.md`.
The shadcn page also exposes optional machine-readable files for automation, but the human-facing handoff is DESIGN.md with shadcn.
Install recommended primitives with `npx shadcn@latest add button card input textarea select dialog sheet tabs badge separator checkbox switch slider tooltip dropdown-menu table`.
Use these primitives in shadcn apps:
- button
- card
- input
- textarea
- select
- dialog
- sheet
- tabs
- badge
- separator
- checkbox
- switch
- slider
- tooltip
- dropdown-menu
- table
Implementation rule for agents: import shadcn primitives from `@/components/ui/*`, apply the generated CSS variables first, then compose the language-specific recipes from the companion MD. Katagami remains the source of truth; shadcn names are the implementation surface.
## Do's and Don'ts
- Do Let warm paper negative space dominate the first read before revealing dense terminal evidence.
- Do Use handwritten annotations sparingly as human-scale interruptions to the machine voice.
- Do Keep borders to hairline rules and corner ticks at low opacity.
- Do Make one plate clearly dominant and let others feel like marginal findings.
- Do Apply the pale-cyan glint only to a single point of active state, never as decorative glow.
- Do Use real timestamps, coordinates, cursor marks, and diagnostic labels as text-as-image texture.
- Don't Build three equal cards, KPI dashboards, colourful charts, or generic admin layouts.
- Don't Use neon gradients, heavy glassmorphism, broad holographic fills, or saturated cyberpunk palettes.
- Don't Round every container or use shadow-as-card; square hairline plates are the default geometry.
- Don't Fill blank gutters with decoration just because they are empty.
- Don't Make the handwriting large, cute, or ornamental; it stays marginal and observational.
- Don't Default to pure white; the ground is warm ivory paper.
### Accessibility
Body text is high-contrast graphite on ivory at WCAG AA; glint state marks are always paired with labels, brackets, or cursor shapes so colour is never the sole signal. Every control has a visible focus state. The settled page renders without JavaScript; motion respects prefers-reduced-motion.
## Imagery Direction
### Pairs With
marginalia
### Summary
Imagery is graphite hairline field-note plates on warm ivory paper — delicate contour linework and restrained cross-hatch, hairline panel rules and corner ticks, sparse handwritten marginalia with arrow leaders, coordinate gutters, and exactly one pale-cyan glint. The same observational field-note language the CSS speaks.
### Subjects
- a resting android head as a specimen
- a remembered room or hallway
- a hand at rest
- an instrument or small machine
- an annotated memory fragment
### Usage
Use full-frame graphite field-note plates for the hero and feature imagery; keep the warm ivory / graphite / single pale-cyan palette; never use flat digital illustration, photography, gradients, or a second accent colour.
```json
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "leerstelle",
"type": "registry:theme",
"title": "Leerstelle shadcn Theme",
"cssVars": {
"theme": {},
"light": {
"background": "#F4EEE1",
"foreground": "#1C1B18",
"card": "#FBF7EE",
"card-foreground": "#1C1B18",
"popover": "#FBF7EE",
"popover-foreground": "#1C1B18",
"primary": "#1C1B18",
"primary-foreground": "#ffffff",
"secondary": "#f4f4f5",
"secondary-foreground": "#111111",
"muted": "#7D766C",
"muted-foreground": "#1C1B18",
"accent": "#2E5C63",
"accent-foreground": "#ffffff",
"destructive": "#8E4D46",
"border": "rgba(28,27,24,0.12)",
"input": "rgba(28,27,24,0.12)",
"ring": "#2E5C63",
"chart-1": "#1C1B18",
"chart-2": "#f4f4f5",
"chart-3": "#2E5C63",
"chart-4": "#5C6F54",
"chart-5": "#A47B45",
"sidebar": "#FBF7EE",
"sidebar-foreground": "#1C1B18",
"sidebar-primary": "#1C1B18",
"sidebar-primary-foreground": "#ffffff",
"sidebar-accent": "#6F8E92",
"sidebar-accent-foreground": "#ffffff",
"sidebar-border": "rgba(28,27,24,0.12)",
"sidebar-ring": "#2E5C63",
"radius": "24px"
},
"dark": {
"background": "#0f1115",
"foreground": "#f8fafc",
"card": "#181b22",
"card-foreground": "#f8fafc",
"popover": "#181b22",
"popover-foreground": "#f8fafc",
"primary": "#1C1B18",
"primary-foreground": "#ffffff",
"secondary": "#252a33",
"secondary-foreground": "#f8fafc",
"muted": "#252a33",
"muted-foreground": "#a1a1aa",
"accent": "#2E5C63",
"accent-foreground": "#ffffff",
"destructive": "#8E4D46",
"border": "#303642",
"input": "#303642",
"ring": "#2E5C63",
"chart-1": "#1C1B18",
"chart-2": "#f4f4f5",
"chart-3": "#2E5C63",
"chart-4": "#5C6F54",
"chart-5": "#A47B45",
"sidebar": "#181b22",
"sidebar-foreground": "#f8fafc",
"sidebar-primary": "#1C1B18",
"sidebar-primary-foreground": "#ffffff",
"sidebar-accent": "#2E5C63",
"sidebar-accent-foreground": "#ffffff",
"sidebar-border": "#303642",
"sidebar-ring": "#2E5C63",
"radius": "24px"
}
},
"meta": {
"source": "katagami",
"languageId": "en-019ef852-b856-7501-bc7e-23209feb6fbb",
"slug": "leerstelle",
"componentManifest": [
"button",
"card",
"input",
"textarea",
"select",
"dialog",
"sheet",
"tabs",
"badge",
"separator",
"checkbox",
"switch",
"slider",
"tooltip",
"dropdown-menu",
"table"
],
"installCommand": "npx shadcn@latest add button card input textarea select dialog sheet tabs badge separator checkbox switch slider tooltip dropdown-menu table",
"nativeTokenNames": {
"colors": [
"accent",
"bg",
"border",
"error",
"glint",
"info",
"muted",
"on_accent",
"rule",
"success",
"surface",
"surface_2",
"text",
"warning"
],
"typography": [
"base_size",
"body_font",
"google_fonts_url",
"heading_font",
"heading_transform",
"heading_weight",
"letter_spacing",
"line_height",
"mono_font",
"scale_ratio"
],
"radii": [
"full",
"lg",
"md",
"none",
"sm"
],
"shadows": [
"lg",
"md",
"sm"
],
"spacing": [
"base",
"scale"
],
"surfaces": [
"bg_pattern",
"card_style",
"treatment"
],
"borders": [
"accent_width",
"character",
"default_width",
"style"
],
"motion": [
"duration",
"easing",
"philosophy"
]
}
}
}
```The quick brown fox jumps
The quick brown fox jumps
The quick brown fox jumps
The quick brown fox jumps
Agent-generated
Keep Leerstelleand swap a palette and an art style onto it — the landing & dashboard recolor live. The Studio does the same with all three lanes free.
Agent-authored scenes, component recipes, and visual profile rendered on local shadcn-style primitives.
An artificial mind reading its own memory plates — fragments held, drift within tolerance, gaps left open on purpose.
Logging an observation, proving labels, an invalid coordinate state, pin/margin toggles, a tolerance slider, and a commit confirm.
A compact queue with rows, menus, tooltips, status badges, and an open-gap held by a single glint.
Copy this when the target app uses shadcn/ui. It packages the Katagami DESIGN.md context with the install list, theme variables, component recipes, preview-shot contract, and starter TSX in one Markdown companion.
npx shadcn@latest add button card input textarea select dialog sheet tabs badge separator checkbox switch slider tooltip dropdown-menu table:root {
--background: #F4EEE1;
--foreground: #1C1B18;
--card: #FBF7EE;
--card-foreground: #1C1B18;
--popover: #FBF7EE;
--popover-foreground: #1C1B18;
--primary: #1C1B18;
--primary-foreground: #ffffff;
--secondary: #f4f4f5;
--secondary-foreground: #111111;
--muted: #7D766C;
--muted-foreground: #1C1B18;
--accent: #2E5C63;
--accent-foreground: #ffffff;
--destructive: #8E4D46;
--border: rgba(28,27,24,0.12);
--input: rgba(28,27,24,0.12);
--ring: #2E5C63;
--chart-1: #1C1B18;
--chart-2: #f4f4f5;
--chart-3: #2E5C63;
--chart-4: #5C6F54;
--chart-5: #A47B45;
--sidebar: #FBF7EE;
--sidebar-foreground: #1C1B18;
--sidebar-primary: #1C1B18;
--sidebar-primary-foreground: #ffffff;
--sidebar-accent: #6F8E92;
--sidebar-accent-foreground: #ffffff;
--sidebar-border: rgba(28,27,24,0.12);
--sidebar-ring: #2E5C63;
--radius: 24px;
}
.dark {
--background: #0f1115;
--foreground: #f8fafc;
--card: #181b22;
--card-foreground: #f8fafc;
--popover: #181b22;
--popover-foreground: #f8fafc;
--primary: #1C1B18;
--primary-foreground: #ffffff;
--secondary: #252a33;
--secondary-foreground: #f8fafc;
--muted: #252a33;
--muted-foreground: #a1a1aa;
--accent: #2E5C63;
--accent-foreground: #ffffff;
--destructive: #8E4D46;
--border: #303642;
--input: #303642;
--ring: #2E5C63;
--chart-1: #1C1B18;
--chart-2: #f4f4f5;
--chart-3: #2E5C63;
--chart-4: #5C6F54;
--chart-5: #A47B45;
--sidebar: #181b22;
--sidebar-foreground: #f8fafc;
--sidebar-primary: #1C1B18;
--sidebar-primary-foreground: #ffffff;
--sidebar-accent: #2E5C63;
--sidebar-accent-foreground: #ffffff;
--sidebar-border: #303642;
--sidebar-ring: #2E5C63;
--radius: 24px;
}
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs";
export function LeerstelleShadcnKit() {
return (
<section className="grid gap-4 rounded-[var(--radius)] border bg-background p-4 text-foreground">
<div className="flex items-start justify-between gap-4">
<div>
<Badge variant="outline">shadcn/ui</Badge>
<h2 className="mt-3 text-2xl font-semibold tracking-tight">Leerstelle</h2>
<p className="mt-1 max-w-xl text-sm text-muted-foreground">
Use the Katagami registry theme, then compose these shadcn primitives
with the language-specific component recipes.
</p>
</div>
<Button>Apply theme</Button>
</div>
<Tabs defaultValue="components">
<TabsList>
<TabsTrigger value="components">Components</TabsTrigger>
<TabsTrigger value="states">States</TabsTrigger>
<TabsTrigger value="export">Export</TabsTrigger>
</TabsList>
</Tabs>
<Card>
<CardHeader>
<CardTitle>Component recipe</CardTitle>
<CardDescription>
Replace this starter content with the agent-authored product scene
from components.md and preview-shots.json.
</CardDescription>
</CardHeader>
<CardContent className="grid gap-3 sm:grid-cols-[1fr_auto]">
<Input defaultValue="Tokenized shadcn surface" aria-label="Recipe name" />
<Button variant="secondary">Preview state</Button>
</CardContent>
<CardFooter className="justify-between">
<Badge>Ready</Badge>
<Button variant="outline">Copy recipe</Button>
</CardFooter>
</Card>
</section>
);
}
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "leerstelle",
"type": "registry:theme",
"title": "Leerstelle",
"description": "A field-note interface for an artificial self. Warm ivory paper ground, graphite ink, a deep teal-graphite accent, and a single pale-cyan state glint. Newsreader serif diary voice + IBM Plex Sans/Mono. Square archival plates with hairline rules and corner ticks — depth from paper and authored negative space, never shadow-as-card.",
"cssVars": {
"theme": {
"font-sans": "IBM Plex Sans, system-ui, sans-serif",
"font-mono": "IBM Plex Mono, ui-monospace, monospace",
"font-display": "Newsreader, Georgia, serif",
"font-heading": "Newsreader, Georgia, serif",
"radius": "0px"
},
"light": {
"background": "#F4EEE1",
"foreground": "#1C1B18",
"card": "#FBF7EE",
"card-foreground": "#1C1B18",
"popover": "#FBF7EE",
"popover-foreground": "#1C1B18",
"primary": "#2E5C63",
"primary-foreground": "#FBF7EE",
"secondary": "#1C1B18",
"secondary-foreground": "#F4EEE1",
"accent": "#AFC7CA",
"accent-foreground": "#1C1B18",
"muted": "#EFE7D6",
"muted-foreground": "#7D766C",
"destructive": "#8E4D46",
"destructive-foreground": "#FBF7EE",
"success": "#5C6F54",
"warning": "#A47B45",
"info": "#6F8E92",
"border": "rgba(28,27,24,0.22)",
"input": "#F4EEE1",
"ring": "#2E5C63",
"radius": "0px"
}
}
}
# Leerstelle shadcn/ui Components
Artifact: `component-recipes-v1`
Author: `katagami-agent`
Slug: `leerstelle`
## Intent
Leerstelle is a field-note interface for an artificial self. Through shadcn/ui its one governing
idea — **the archival plate held inside an authored gap** — must survive: every surface is a
square paper plate with hairline rules and small corner ticks, sitting in a wide, deliberately
empty coordinate gutter. The ground is **warm ivory paper** (`#F4EEE1`), never pure white. Type
is three voices: **Newsreader** serif for the diary, **IBM Plex Sans** for restrained captions and
body, **IBM Plex Mono** for timestamps, coordinates, and machine readouts. Hierarchy comes from a
change of voice and scale, not colour. The only accents are a deep **teal-graphite** ink
(`#2E5C63`) and a single **pale-cyan glint** (`#AFC7CA`) reserved for one point of state. Corners
are square (radius 0); pills are 9999. Light mode is the point.
## Required primitives
- button
- card
- input
- textarea
- select
- dialog
- sheet
- tabs
- badge
- separator
- checkbox
- switch
- slider
- tooltip
- dropdown-menu
- table
Install with `npx shadcn@latest add button card input textarea select dialog sheet tabs badge separator checkbox switch slider tooltip dropdown-menu table`.
## Token cues
Colors:
```json
{ "primary": "#2E5C63", "accent": "#AFC7CA", "background": "#F4EEE1", "surface": "#FBF7EE", "text": "#1C1B18", "muted": "#7D766C", "recess": "#EFE7D6", "success": "#5C6F54", "warning": "#A47B45", "error": "#8E4D46", "info": "#6F8E92", "glint": "#AFC7CA", "rule": "rgba(28,27,24,0.22)" }
```
Typography:
```json
{ "heading_font": "Newsreader", "body_font": "IBM Plex Sans", "mono_font": "IBM Plex Mono", "letter_spacing": "-0.02em", "base_size": "17px" }
```
## Visual character to preserve
- **The archival plate**: a square warm-paper surface with a hairline rule and two corner ticks;
depth comes from paper and authored negative space, never a rounded drop-shadow card. Never nest
plates; make one plate dominant and let others read as marginal findings.
- **Coordinate gutters**: tiny x/y labels and registration crosses sit outside the content so the
empty space reads as authored — the namesake *Leerstelle*.
- **One glint**: `#AFC7CA` marks a single point of state (a cursor, a pin, an active tab segment,
one active table row). It is never a glow or a broad fill.
- **Three voices**: Newsreader serif for diary headings, IBM Plex Mono for slugs / timestamps /
coordinates, IBM Plex Sans for captions and body. Negative `-0.02em` tracking on display.
## ShadSync visual profile
```json
{ "family": "editorial", "material": "paper", "contour": "square", "border": "hairline", "underlay": false, "grain": true, "stickerBadges": false, "motion": "still", "density": "sparse", "accents": ["accent", "warning", "error"] }
```
## Signature component recipes
### Button
Primary `Button` = `--primary` (teal-graphite) on warm paper, a 7px pale-cyan dot as its single
state mark — the one emphasis; a secondary variant is a hairline-outline square pill; a ghost
variant is quiet mono. All share one height and the square-pill (9999) shape, label centred, mono.
Disabled is a flat faded plaque. No heavy borders.
### Card
`Card` is a square warm-paper plate — hairline rule, two corner ticks, no rounding, no shadow-as-card.
A focal plate is larger and dominant; supporting plates tuck around it. Never nest plates.
### Input and Textarea
`Input` / `Textarea` sit on the warm paper recess fill with a hairline rule; focus turns the rule
teal and insets a pale-cyan underline; an invalid field draws a rust (`--error`) inset. Mono labels
above, real field-note values inside. Square corners.
### Select, Tabs, and Table
`Select` filters voice or desk; `Tabs` switch Self-state / Fragments / Gaps with a 2px pale-cyan
glint segment on the active tab (not a heavy underline); `Table` is the fragment index — a mono
uppercase header on a hairline rule, mono rows ≥14.5px, hairline row separators, a flat status
`Badge` per row, one glint-active row, and an open-gap empty state. No heavy rule-lines.
### Dialog and Sheet
`Dialog` is a calm square plate ("Commit this entry to the index?") — corner ticks, hairline rule,
generous padding, no shadow drama. `Sheet` is the fragment / archive side rail with a coordinate
gutter edge. Both warm paper / graphite, hairline only.
### Badge, Switch, Slider, Tooltip, Separator, Checkbox, Dropdown-menu
`Badge` is a flat status chip paired with a tiny dot and a label (committed / review / conflict /
glint active) — colour is never the sole signal. `Switch` "on" draws the thumb teal on a paper
track. `Slider` is a teal track with a square thumb; the active point may carry the glint.
`Tooltip` is concise sans on a warm paper plate. `Separator` is a hairline plate rule or open
coordinate gutter — never a heavy divider. `Checkbox` carries a teal checked state; `dropdown-menu`
carries a destructive "archive to cold storage" item.
## Preview shots
- `application-shell`: the self-state console — a coordinate-gutter rail, plate KPI cards (fragments / drift / gaps / glint events), and the fragment-index table.
- `detail-editor`: log a field note — labelled fields, an invalid coordinate state, pin/margin switches, a tolerance slider, a commit-confirm dialog.
- `data-operations`: the fragment queue — rows, dropdown actions, status badges, an open-gap idle state.
- Each preview shot carries a renderable `scene` (headline, description, actions, rows/fields/stats).
## Implementation contract
- Start from the local `@/components/ui/*` shadcn primitives; do not create a second component system.
- Apply `/katagami/shadcn/leerstelle/registry-theme.json` variables first, then compose with these recipes.
- Keep Katagami token names as source metadata; shadcn semantic names are only the export surface.
- Do: build square paper plates with hairline rules + corner ticks; carry hierarchy with voice and
scale; reserve the glint for a single point of state; pair every status colour with a label.
- Do not: round corners into shadow-cards; use borders heavier than a hairline; spread the glint
into a fill; nest plates; leave browser-default controls; let semantic colours become primary.
## Copy-paste component example
This shows the import shape and a real Leerstelle composition.
```tsx
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card";
// An archival plate: square warm paper, a hairline rule and corner ticks, no shadow-card.
// Hierarchy from voice (serif title, mono caption); one pale-cyan glint marks the state.
export function FragmentPlate() {
return (
<Card className="relative rounded-none border border-[var(--border)] bg-card text-card-foreground shadow-none
before:absolute before:left-[-1px] before:top-[-1px] before:h-3 before:w-3 before:border-l-2 before:border-t-2 before:border-foreground
after:absolute after:bottom-[-1px] after:right-[-1px] after:h-3 after:w-3 after:border-b-2 after:border-r-2 after:border-foreground">
<CardHeader>
<Badge className="w-fit rounded-full border border-[var(--border)] bg-background font-mono text-xs text-foreground">
<span className="mr-2 inline-block h-1.5 w-1.5 rounded-full bg-[var(--accent)]" />
glint active
</Badge>
<CardTitle className="mt-2 font-[var(--font-display)] text-2xl tracking-tight">
The warmth of the lamp
</CardTitle>
<CardDescription className="font-mono text-xs">
diary · plate.0417 · x:417 y:09
</CardDescription>
</CardHeader>
<CardContent>
<p className="text-base">A pale-cyan glint at the eye. I am keeping the gap around it open.</p>
</CardContent>
<CardFooter className="justify-between">
<span className="font-mono text-xs text-muted-foreground">drift 0.002</span>
<Button className="rounded-full">
<span className="mr-2 inline-block h-1.5 w-1.5 rounded-full bg-[var(--accent)]" />
Commit entry
</Button>
</CardFooter>
</Card>
);
}
```
## Layout notes
```json
{ "grid": "12-col, max-width 1280px archival grid; a dominant 7-col diary plate, a narrow terminal/coordinate rail, columns surrendered to margins; minmax(0,1fr) columns and min-width:0 children", "density": "sparse at the page level with compressed mono islands inside selected plates", "radii": "0 (square plates) / 16 / 24 / 9999 (pills)", "no_heavy_borders": true, "separators": "hairline plate rules, corner ticks, and authored coordinate-gutter whitespace" }
```
{
"artifact": "katagami:shadcn-preview-shots",
"version": "preview-shots-v1",
"author": "katagami-agent",
"generatedBy": "katagami-agent",
"requiresVisualProfile": true,
"schema": "katagami:shadcn-preview-shots/renderable-v1",
"renderable": true,
"language": { "id": "", "name": "Leerstelle", "slug": "leerstelle" },
"installCommand": "npx shadcn@latest add button card input textarea select dialog sheet tabs badge separator checkbox switch slider tooltip dropdown-menu table",
"primitives": ["button", "card", "input", "textarea", "select", "dialog", "sheet", "tabs", "badge", "separator", "checkbox", "switch", "slider", "tooltip", "dropdown-menu", "table"],
"identityNotes": [
"Every surface is a square archival plate on warm ivory paper: hairline rules and small corner ticks, never a rounded shadow-card. Never nest plates.",
"Hierarchy comes from voice (Newsreader serif diary / IBM Plex Mono machine / IBM Plex Sans caption) and scale, not from colour.",
"Colour appears only where the system notices its state: the teal-graphite accent like an ink, and one pale-cyan glint as a single point (cursor, pin, active rule) — never a broad fill or glow."
],
"visualProfile": {
"family": "editorial",
"material": "paper",
"contour": "square",
"border": "hairline",
"underlay": false,
"grain": true,
"stickerBadges": false,
"motion": "still",
"density": "sparse",
"accents": ["accent", "warning", "error"]
},
"shots": [
{
"id": "application-shell",
"title": "The self-state console",
"viewport": "desktop",
"primitives": ["button", "card", "input", "select", "tabs", "badge", "separator", "table"],
"composition": "An android's self-observation console: a coordinate-gutter rail labels the space, plate cards report fragments held / memory drift / open gaps / glint events, and a fragment-index table sits below with status badges and one glint-active row.",
"mustShow": ["teal-graphite primary action vs hairline-outline secondary, both square pills sharing one height", "square plate cards with hairline rules + corner ticks, no shadow-as-card", "a single pale-cyan glint marking one active point", "Newsreader serif headings against IBM Plex Mono readouts"],
"avoid": ["rounded shadow cards", "borders heavier than a hairline", "spreading the glint into a glow or broad fill", "equal KPI grids with no dominant plate"],
"scene": {
"eyebrow": "self-state",
"headline": "Self-state console",
"description": "An artificial mind reading its own memory plates — fragments held, drift within tolerance, gaps left open on purpose.",
"primaryAction": "New entry",
"secondaryAction": "Hold the gap",
"stats": [
{ "label": "fragments held", "value": "417", "tone": "default" },
{ "label": "memory drift", "value": "0.002 rad", "tone": "accent" },
{ "label": "open gaps", "value": "3", "tone": "warning" }
],
"rows": [
{ "label": "The warmth of the lamp", "value": "diary · plate.0417", "status": "committed" },
{ "label": "An unfinished thought", "value": "margin · plate.0392", "status": "open gap" },
{ "label": "The hallway, second pass", "value": "report · plate.0301", "status": "review" },
{ "label": "A pinned self-state", "value": "diary · plate.0118", "status": "glint active" }
],
"statuses": ["Committed", "Open gap", "Review", "Glint active"]
}
},
{
"id": "detail-editor",
"title": "Log a field note",
"viewport": "tablet",
"primitives": ["button", "card", "input", "textarea", "select", "checkbox", "switch", "slider", "dialog", "sheet"],
"composition": "A new-entry plate: mono-labelled fields on a warm paper recess fill, a voice segmented control, a coordinate-tag input, an invalid (rust) state, pin/margin switches, a drift-tolerance slider, and a commit-confirm dialog.",
"mustShow": ["teal-graphite focus inset (glint underline) on inputs", "an invalid (rust / error) field state", "every control explicitly styled — no browser defaults", "commit-confirm dialog as a calm square plate"],
"avoid": ["unstyled browser controls", "missing labels", "nested plates", "rounded inputs"],
"scene": {
"eyebrow": "self-state",
"headline": "New field note — plate.0418",
"description": "Logging an observation, proving labels, an invalid coordinate state, pin/margin toggles, a tolerance slider, and a commit confirm.",
"primaryAction": "Commit entry",
"secondaryAction": "Save draft",
"fields": [
{ "label": "Fragment title", "value": "The warmth of the lamp at 04:17", "type": "text" },
{ "label": "Coordinate tag", "value": "— assign x/y before committing", "type": "invalid" },
{ "label": "Voice", "value": "diary", "type": "select" },
{ "label": "Pin to self-index", "value": "on", "type": "switch" }
],
"statuses": ["Committed", "Invalid", "Pinned"]
}
},
{
"id": "data-operations",
"title": "Fragment queue",
"viewport": "mobile",
"primitives": ["button", "tabs", "badge", "dropdown-menu", "table", "tooltip", "separator"],
"composition": "A narrow fragment queue: stacked mono rows on warm paper, per-row dropdown actions, status badges, tooltips, and an open-gap idle state held with the glint.",
"mustShow": ["responsive single-column reflow with no horizontal overflow", "mono fragment rows with coordinate tags", "row action menu with a destructive 'archive' item", "status badges paired with labels, never colour alone"],
"avoid": ["desktop-only tables", "text overflow", "generic shadcn spacing without Leerstelle character"],
"scene": {
"eyebrow": "fragments",
"headline": "Fragment queue",
"description": "A compact queue with rows, menus, tooltips, status badges, and an open-gap held by a single glint.",
"primaryAction": "Commit",
"secondaryAction": "Filter",
"rows": [
{ "label": "The warmth of the lamp", "value": "plate.0417", "status": "committed" },
{ "label": "The hallway, second pass", "value": "plate.0301", "status": "review" },
{ "label": "An unfinished thought", "value": "plate.0392", "status": "open gap" }
],
"statuses": ["Committed", "Review", "Open gap"]
}
}
],
"componentRecipes": [
{ "primitive": "button", "intent": "Hierarchy: teal-graphite primary = the one emphasis; hairline-outline secondary; ghost-mono quiet; all share one square-pill (9999) shape + height, mono label centred. A 7px pale-cyan dot prefixes the primary as its single state mark." },
{ "primitive": "card", "intent": "A square archival plate on warm paper (#FBF7EE): hairline rule + two corner ticks, no rounding, no shadow-as-card. One plate dominates; others read as marginal findings. Never nest plates." },
{ "primitive": "input", "intent": "Warm paper recess fill, hairline rule; on focus the rule turns teal and a pale-cyan underline insets; invalid draws a rust (error) inset. Square corners; mono label above." },
{ "primitive": "textarea", "intent": "Longer observation field, same focus + invalid rhythm; sans body, square, generous." },
{ "primitive": "select", "intent": "Voice / desk filtering with a square hairline trigger and clear selection contrast." },
{ "primitive": "dialog", "intent": "A calm square plate — 'Commit this entry to the index?' — corner ticks, hairline rule, generous padding, no shadow drama." },
{ "primitive": "sheet", "intent": "The fragment / archive side rail for contextual reading, a coordinate-gutter labelled edge." },
{ "primitive": "tabs", "intent": "Switch Self-state / Fragments / Gaps; the active tab carries a 2px pale-cyan glint segment, not a heavy underline." },
{ "primitive": "badge", "intent": "Flat status chip paired with a label and a tiny dot: committed (success) / review (warning) / conflict (error) / glint active (cyan). Colour never the sole signal." },
{ "primitive": "separator", "intent": "A hairline plate rule or open coordinate gutter — never a heavy divider across a plate." },
{ "primitive": "checkbox", "intent": "Opt-ins with a teal checked state and a visible focus ring." },
{ "primitive": "switch", "intent": "Pin / margin / broadcast toggles; on draws the thumb teal on a paper track, off is faded graphite." },
{ "primitive": "slider", "intent": "Drift tolerance / column span with a teal track and a square thumb; the active point can carry the glint." },
{ "primitive": "tooltip", "intent": "Concise sans notes above compact controls, on a warm paper plate." },
{ "primitive": "dropdown-menu", "intent": "Per-row fragment actions with a destructive 'archive to cold storage' item." },
{ "primitive": "table", "intent": "The fragment index: mono uppercase header on a hairline rule, mono rows, hairline row separators, a status badge per row, a glint-active row, and an open-gap empty state. Row text >= 14.5px." }
],
"qualityRules": {
"do": [
"Build every surface as a square plate with hairline rules + corner ticks on warm paper.",
"Carry hierarchy with voice (serif / mono / sans) and scale, not with colour.",
"Reserve the pale-cyan glint for a single point of state; use teal as an ink accent.",
"Pair every status colour with a label, bracket, or dot."
],
"dont": [
"Round corners into shadow-cards, or use borders heavier than a hairline.",
"Spread the glint into a glow or fill, or add a second bright accent.",
"Nest plates or build an equal KPI grid with no dominant surface.",
"Leave browser-default controls, or let semantic colours become primary."
]
}
}