Impression is a limited-edition risograph screenprint pressed into an interface.
label mdSpace Mono, 12px, 600
Impression is a limited-edition risograph screenprint pressed into an interface.
Specification
Philosophy
summary
Impression is a limited-edition risograph screenprint pressed into an interface. It keeps the loud, collectible, joyfully commercial soul of pop design but pulls its expression from the riso print shop instead of the comic-book panel. Every headline and key mark is built from two or three flat fluorescent spot-ink layers deliberately pulled a few pixels out of register, so type and shapes carry a bright chromatic double-vision fringe — the printer's happy accident, made the whole point. Where two inks cross they overprint into a third bloom. No ink outlines, no drop-shadow stickers, no halftone-dot wallpaper: a warm newsprint ground, three fluorescent inks, and the color-bar proof furniture as ornament.
It values
collectible, limited-edition object energy
three-ink fluorescent brightness on warm paper
the misregister as signature, not defect
overprint colour instead of adjacent colour slabs
loud hierarchy that reads across the room
It refuses
comic-book ink outlines and hard offset drop-shadows
halftone-dot backgrounds used as wallpaper
muted corporate pastels or monochrome restraint
grey borders and invisible card edges
graphic noise so dense the hierarchy dissolves
visual character
The misregister knockout: headlines and marks render as offset spot-ink layers so every strong shape carries a cyan-and-pink double-pull ghost, the way a hand-pulled riso slips out of register.
Impression blooms: where pink crosses cyan the interface shows a real violet, where cyan crosses yellow a real green — colour arrives from ink multiplying, not from more slabs.
The color-bar rail: a strip of solid spot-ink swatches and a registration crosshair recur along section edges, the printer's proof furniture turned into the page's ornament system.
Warm newsprint ground with a fine paper grain everywhere, so even empty areas feel like stock pulled through a press, never a flat white screen.
Poster-weight display type set tight and huge, with mono color-bar labels underneath like the captions on an edition print.
Warm off-white card on the newsprint ground, no border, lifted by a soft print shadow, headed by a mono color-bar caption and registration crosshair.
bg pattern
paper-grain + faint registration-crosshair field, never halftone-dot wallpaper
borders4
default width
0
accent width
0
style
none
character
Separation comes from the misregister ghost and the color-bar rail, never from an ink outline or grey keyline. Inputs carry only an inset ink rule standing in for a plate edge.
motion3
duration
180ms
easing
cubic-bezier(0.2,0.9,0.2,1)
philosophy
Controls press into the paper: on hover the misregister offset collapses toward zero, the mark snaps into register — a tactile in-the-press feel, never a soft float.
Rules
composition
Build screens as edition prints: a big pulled headline over a warm-paper field, a feature card carrying the hero pull, and a proof column of smaller cards, each captioned by a mono color-bar label and crosshair. Clusters break the grid only through overlapping swatch chips, never through skewed ribbons.
hierarchy
Poster-weight display, set huge and tight, reads first. Mono color-bar labels annotate every block. Primary actions sit on solid pink fill; the misregister ghost makes them pop off the paper without a single border.
density
Lively but balanced — bold chunks of ink separated by warm-paper gutters, so the eye gets a rest between the fluorescent moments and no region is crowded while another starves.
signature patterns
Misregister knockout: strong headlines and marks render as offset spot-ink layers, carrying a cyan-and-pink double-pull ghost so shapes separate from paper without any outline.
Overprint blooms: accent inks that cross multiply into a real violet or green, so extra colour comes from overlap, not from more colour slabs.
The color-bar rail: solid spot-ink swatch strips plus a registration crosshair recur along section edges as one page-wide ornament system.
Mono color-bar captions head every card and section, set like the edition caption under a print.
Interactive controls press on the paper: on hover the misregister ghost snaps into register (the offset collapses toward zero).
Layout
grid
A calm 12-column editorial grid does the structural work so the loud ink can be loud without chaos. One oversized feature column pairs with a narrower proof column; clusters share baseline gutters. Density is balanced across the canvas.
breakpoints
Desktop runs the feature-plus-proof two-column rhythm with the color-bar rail down the edges. The tablet band (768-1024) is its own layout: the rail moves to a top strip, the feature column goes full width, the proof column becomes a two-up row beneath it. Mobile stacks to one column, keeps the misregister on headlines only, and collapses the rail to a short swatch row so nothing overflows.
whitespace
Warm paper is the rest between ink. Generous breathing strips wrap every cluster; titles always carry padding above them and are never stuck to a container top.
Guidance
Do
Build separation from the misregister ghost and the color-bar rail, never from ink outlines or grey borders.
Let overprint blooms supply extra colour where two inks cross, instead of adding a fourth slab.
Caption cards and sections with mono color-bar labels and a registration crosshair.
Keep the warm newsprint ground and its fine grain under everything, including empty states.
Keep the fluorescent inks to pink, cyan, and yellow, with violet/green only as overprints.
Avoid
Reach for comic-book ink outlines, hard offset drop-shadows, or sticker keylines.
Wallpaper backgrounds with halftone dots or burst rays.
Mute the palette into pastels or monochrome restraint.
Use browser-default form controls; every control carries the paper, radius, and misregister.
Crowd one region into noise while another starves — balance density across the canvas.
Imagery
pairs with
impression
pairs with art style
impression
summary
Imagery is hand-pulled risograph screenprints in the Overprint art style: flat fluorescent spot-ink separations pulled out of register, overprint blooms where inks cross, on warm newsprint. Any subject — a market street, a face, a teapot — is dressed the same way.
hero
A wide three-ink riso pull of an editorial scene (a night market), misregister ghost on every edge, room on one side for the overlay copy.
Katagami spec file
# Impression
## Philosophy
Impression is a limited-edition risograph screenprint pressed into an interface. It keeps the loud, collectible, joyfully commercial soul of pop design but pulls its expression from the riso print shop instead of the comic-book panel. Every headline and key mark is built from two or three flat fluorescent spot-ink layers deliberately pulled a few pixels out of register, so type and shapes carry a bright chromatic double-vision fringe — the printer's happy accident, made the whole point. Where two inks cross they overprint into a third bloom. No ink outlines, no drop-shadow stickers, no halftone-dot wallpaper: a warm newsprint ground, three fluorescent inks, and the color-bar proof furniture as ornament.
### Values
- collectible, limited-edition object energy
- three-ink fluorescent brightness on warm paper
- the misregister as signature, not defect
- overprint colour instead of adjacent colour slabs
- loud hierarchy that reads across the room
### Anti-Values
- comic-book ink outlines and hard offset drop-shadows
- halftone-dot backgrounds used as wallpaper
- muted corporate pastels or monochrome restraint
- grey borders and invisible card edges
- graphic noise so dense the hierarchy dissolves
### Visual Character
- The misregister knockout: headlines and marks render as offset spot-ink layers so every strong shape carries a cyan-and-pink double-pull ghost, the way a hand-pulled riso slips out of register.
- Impression blooms: where pink crosses cyan the interface shows a real violet, where cyan crosses yellow a real green — colour arrives from ink multiplying, not from more slabs.
- The color-bar rail: a strip of solid spot-ink swatches and a registration crosshair recur along section edges, the printer's proof furniture turned into the page's ornament system.
- Warm newsprint ground with a fine paper grain everywhere, so even empty areas feel like stock pulled through a press, never a flat white screen.
- Poster-weight display type set tight and huge, with mono color-bar labels underneath like the captions on an edition print.
## Tokens
### Colors
| Name | Value |
|------|-------|
| bg | `#F7F1E4` |
| surface | `#FFFDF7` |
| surface_solid | `#FFFDF7` |
| text | `#1B1A17` |
| muted | `#7C7566` |
| border | `#1B1A17` |
| accent | `#FF2E88` |
| accent_2 | `#12B5C9` |
| accent_soft | `#FFC300` |
| on_accent | `#FFFDF7` |
| success | `#2FB170` |
| warning | `#FF8A1E` |
| error | `#F0433A` |
| info | `#12B5C9` |
### Typography
- **Base Size**: 17px
- **Body Font**: Space Grotesk, sans-serif
- **Heading Font**: Archivo Black, sans-serif
- **Mono Font**: Space Mono, monospace
- **Heading Weight**: 400
- **Heading Transform**: none
- **Letter Spacing**: -0.02em
- **Line Height**: 1.55
- **Scale Ratio**: 1.25
- **Google Fonts Url**: https://fonts.googleapis.com/css2?family=Archivo+Black&family=Space+Grotesk:wght@400;500;700&family=Space+Mono:wght@400;700&display=swap
### Radii
- **None**: 0px
- **Md**: 16px
- **Lg**: 24px
- **Full**: 9999px
### Shadows
- **Sm**: 0 2px 0 rgba(27,26,23,0.10)
- **Md**: 0 10px 24px -12px rgba(27,26,23,0.30)
- **Lg**: 0 20px 48px -20px rgba(27,26,23,0.34)
### Spacing
- **Base**: 8px
- **Scale**: [4,8,16,24,40,64,96]
### Surfaces
- **Treatment**: newsprint paper with fine grain
- **Card Style**: Warm off-white card on the newsprint ground, no border, lifted by a soft print shadow, headed by a mono color-bar caption and registration crosshair.
- **Bg Pattern**: paper-grain + faint registration-crosshair field, never halftone-dot wallpaper
### Borders
- **Default Width**: 0
- **Accent Width**: 0
- **Style**: none
- **Character**: Separation comes from the misregister ghost and the color-bar rail, never from an ink outline or grey keyline. Inputs carry only an inset ink rule standing in for a plate edge.
### Motion
- **Duration**: 180ms
- **Easing**: cubic-bezier(0.2,0.9,0.2,1)
- **Philosophy**: Controls press into the paper: on hover the misregister offset collapses toward zero, the mark snaps into register — a tactile in-the-press feel, never a soft float.
## Rules
### Composition
Build screens as edition prints: a big pulled headline over a warm-paper field, a feature card carrying the hero pull, and a proof column of smaller cards, each captioned by a mono color-bar label and crosshair. Clusters break the grid only through overlapping swatch chips, never through skewed ribbons.
### Hierarchy
Poster-weight display, set huge and tight, reads first. Mono color-bar labels annotate every block. Primary actions sit on solid pink fill; the misregister ghost makes them pop off the paper without a single border.
### Density
Lively but balanced — bold chunks of ink separated by warm-paper gutters, so the eye gets a rest between the fluorescent moments and no region is crowded while another starves.
### Signature Patterns
- Misregister knockout: strong headlines and marks render as offset spot-ink layers, carrying a cyan-and-pink double-pull ghost so shapes separate from paper without any outline.
- Overprint blooms: accent inks that cross multiply into a real violet or green, so extra colour comes from overlap, not from more colour slabs.
- The color-bar rail: solid spot-ink swatch strips plus a registration crosshair recur along section edges as one page-wide ornament system.
- Mono color-bar captions head every card and section, set like the edition caption under a print.
- Interactive controls press on the paper: on hover the misregister ghost snaps into register (the offset collapses toward zero).
## Layout
### Grid
A calm 12-column editorial grid does the structural work so the loud ink can be loud without chaos. One oversized feature column pairs with a narrower proof column; clusters share baseline gutters. Density is balanced across the canvas.
### Breakpoints
Desktop runs the feature-plus-proof two-column rhythm with the color-bar rail down the edges. The tablet band (768-1024) is its own layout: the rail moves to a top strip, the feature column goes full width, the proof column becomes a two-up row beneath it. Mobile stacks to one column, keeps the misregister on headlines only, and collapses the rail to a short swatch row so nothing overflows.
### Whitespace
Warm paper is the rest between ink. Generous breathing strips wrap every cluster; titles always carry padding above them and are never stuck to a container top.
## Guidance
### Do
- Build separation from the misregister ghost and the color-bar rail, never from ink outlines or grey borders.
- Let overprint blooms supply extra colour where two inks cross, instead of adding a fourth slab.
- Caption cards and sections with mono color-bar labels and a registration crosshair.
- Keep the warm newsprint ground and its fine grain under everything, including empty states.
- Keep the fluorescent inks to pink, cyan, and yellow, with violet/green only as overprints.
### Don't
- Reach for comic-book ink outlines, hard offset drop-shadows, or sticker keylines.
- Wallpaper backgrounds with halftone dots or burst rays.
- Mute the palette into pastels or monochrome restraint.
- Use browser-default form controls; every control carries the paper, radius, and misregister.
- Crowd one region into noise while another starves — balance density across the canvas.
## Imagery Direction
### Pairs With
impression
### Pairs With Art Style
impression
### Summary
Imagery is hand-pulled risograph screenprints in the Overprint art style: flat fluorescent spot-ink separations pulled out of register, overprint blooms where inks cross, on warm newsprint. Any subject — a market street, a face, a teapot — is dressed the same way.
### Hero
A wide three-ink riso pull of an editorial scene (a night market), misregister ghost on every edge, room on one side for the overlay copy.
DESIGN.md file
---
version: "alpha"
name: "Impression"
description: "Impression is a limited-edition risograph screenprint pressed into an interface. It keeps the loud, collectible, joyfully commercial soul of pop design but pulls its expression from the riso print shop instead of the comic-book panel. Ev..."
colors:
bg: "#F7F1E4"
surface: "#FFFDF7"
surface_solid: "#FFFDF7"
text: "#1B1A17"
muted: "#7C7566"
border: "#1B1A17"
accent: "#FF2E88"
accent_2: "#12B5C9"
accent_soft: "#FFC300"
on_accent: "#FFFDF7"
success: "#2FB170"
warning: "#FF8A1E"
error: "#F0433A"
info: "#12B5C9"
typography:
headline-lg:
fontFamily: "Archivo Black, sans-serif"
fontSize: "2.075rem"
fontWeight: 700
lineHeight: 1.1
letterSpacing: "-0.02em"
headline-md:
fontFamily: "Archivo Black, sans-serif"
fontSize: "1.66rem"
fontWeight: 600
lineHeight: 1.15
letterSpacing: "-0.02em"
body-md:
fontFamily: "Space Grotesk, sans-serif"
fontSize: "17px"
fontWeight: 400
lineHeight: 1.5
letterSpacing: "-0.02em"
label-md:
fontFamily: "Space Mono, monospace"
fontSize: "0.75rem"
fontWeight: 600
lineHeight: 1
letterSpacing: "0.08em"
rounded:
none: "0px"
md: "16px"
lg: "24px"
full: "9999px"
spacing:
base: "8px"
xs: "4px"
sm: "8px"
md: "16px"
lg: "24px"
xl: "40px"
2xl: "64px"
3xl: "96px"
components:
color-reference-bg:
backgroundColor: "{colors.bg}"
color-reference-surface:
backgroundColor: "{colors.surface}"
color-reference-surface_solid:
backgroundColor: "{colors.surface_solid}"
color-reference-text:
backgroundColor: "{colors.text}"
color-reference-muted:
backgroundColor: "{colors.muted}"
color-reference-border:
backgroundColor: "{colors.border}"
color-reference-accent:
backgroundColor: "{colors.accent}"
color-reference-accent_2:
backgroundColor: "{colors.accent_2}"
color-reference-accent_soft:
backgroundColor: "{colors.accent_soft}"
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: "{colors.on_accent}"
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"
---
# Impression
## Overview
Impression is a limited-edition risograph screenprint pressed into an interface. It keeps the loud, collectible, joyfully commercial soul of pop design but pulls its expression from the riso print shop instead of the comic-book panel. Every headline and key mark is built from two or three flat fluorescent spot-ink layers deliberately pulled a few pixels out of register, so type and shapes carry a bright chromatic double-vision fringe — the printer's happy accident, made the whole point. Where two inks cross they overprint into a third bloom. No ink outlines, no drop-shadow stickers, no halftone-dot wallpaper: a warm newsprint ground, three fluorescent inks, and the color-bar proof furniture as ornament.
### Values
- collectible, limited-edition object energy
- three-ink fluorescent brightness on warm paper
- the misregister as signature, not defect
- overprint colour instead of adjacent colour slabs
- loud hierarchy that reads across the room
### Anti-Values
- comic-book ink outlines and hard offset drop-shadows
- halftone-dot backgrounds used as wallpaper
- muted corporate pastels or monochrome restraint
- grey borders and invisible card edges
- graphic noise so dense the hierarchy dissolves
### Visual Character
- The misregister knockout: headlines and marks render as offset spot-ink layers so every strong shape carries a cyan-and-pink double-pull ghost, the way a hand-pulled riso slips out of register.
- Impression blooms: where pink crosses cyan the interface shows a real violet, where cyan crosses yellow a real green — colour arrives from ink multiplying, not from more slabs.
- The color-bar rail: a strip of solid spot-ink swatches and a registration crosshair recur along section edges, the printer's proof furniture turned into the page's ornament system.
- Warm newsprint ground with a fine paper grain everywhere, so even empty areas feel like stock pulled through a press, never a flat white screen.
- Poster-weight display type set tight and huge, with mono color-bar labels underneath like the captions on an edition print.
## 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 | `#F7F1E4` |
| surface | `#FFFDF7` |
| surface_solid | `#FFFDF7` |
| text | `#1B1A17` |
| muted | `#7C7566` |
| border | `#1B1A17` |
| accent | `#FF2E88` |
| accent_2 | `#12B5C9` |
| accent_soft | `#FFC300` |
| on_accent | `#FFFDF7` |
| success | `#2FB170` |
| warning | `#FF8A1E` |
| error | `#F0433A` |
| info | `#12B5C9` |
## Typography
Load the fonts from Google Fonts: https://fonts.googleapis.com/css2?family=Archivo+Black&family=Space+Grotesk:wght@400;500;700&family=Space+Mono:wght@400;700&display=swap
- **Headline-Lg**: Archivo Black, sans-serif, 2.075rem, weight 700, line-height 1.1.
- **Headline-Md**: Archivo Black, sans-serif, 1.66rem, weight 600, line-height 1.15.
- **Body-Md**: Space Grotesk, sans-serif, 17px, weight 400, line-height 1.5.
- **Label-Md**: Space Mono, monospace, 0.75rem, weight 600, line-height 1.
## Layout
### Spacing Tokens
- **Base**: `8px`
- **Xs**: `4px`
- **Sm**: `8px`
- **Md**: `16px`
- **Lg**: `24px`
- **Xl**: `40px`
- **2xl**: `64px`
- **3xl**: `96px`
### Grid
A calm 12-column editorial grid does the structural work so the loud ink can be loud without chaos. One oversized feature column pairs with a narrower proof column; clusters share baseline gutters. Density is balanced across the canvas.
### Breakpoints
Desktop runs the feature-plus-proof two-column rhythm with the color-bar rail down the edges. The tablet band (768-1024) is its own layout: the rail moves to a top strip, the feature column goes full width, the proof column becomes a two-up row beneath it. Mobile stacks to one column, keeps the misregister on headlines only, and collapses the rail to a short swatch row so nothing overflows.
### Whitespace
Warm paper is the rest between ink. Generous breathing strips wrap every cluster; titles always carry padding above them and are never stuck to a container top.
## Elevation & Depth
### Shadows
- **Sm**: 0 2px 0 rgba(27,26,23,0.10)
- **Md**: 0 10px 24px -12px rgba(27,26,23,0.30)
- **Lg**: 0 20px 48px -20px rgba(27,26,23,0.34)
## Shapes
### Rounded
- **None**: `0px`
- **Md**: `16px`
- **Lg**: `24px`
- **Full**: `9999px`
### Surfaces
- **Treatment**: newsprint paper with fine grain
- **Card Style**: Warm off-white card on the newsprint ground, no border, lifted by a soft print shadow, headed by a mono color-bar caption and registration crosshair.
- **Bg Pattern**: paper-grain + faint registration-crosshair field, never halftone-dot wallpaper
### Borders
- **Default Width**: 0
- **Accent Width**: 0
- **Style**: none
- **Character**: Separation comes from the misregister ghost and the color-bar rail, never from an ink outline or grey keyline. Inputs carry only an inset ink rule standing in for a plate edge.
## Components
### Composition
Build screens as edition prints: a big pulled headline over a warm-paper field, a feature card carrying the hero pull, and a proof column of smaller cards, each captioned by a mono color-bar label and crosshair. Clusters break the grid only through overlapping swatch chips, never through skewed ribbons.
### Hierarchy
Poster-weight display, set huge and tight, reads first. Mono color-bar labels annotate every block. Primary actions sit on solid pink fill; the misregister ghost makes them pop off the paper without a single border.
### Density
Lively but balanced — bold chunks of ink separated by warm-paper gutters, so the eye gets a rest between the fluorescent moments and no region is crowded while another starves.
### Signature Patterns
- Misregister knockout: strong headlines and marks render as offset spot-ink layers, carrying a cyan-and-pink double-pull ghost so shapes separate from paper without any outline.
- Overprint blooms: accent inks that cross multiply into a real violet or green, so extra colour comes from overlap, not from more colour slabs.
- The color-bar rail: solid spot-ink swatch strips plus a registration crosshair recur along section edges as one page-wide ornament system.
- Mono color-bar captions head every card and section, set like the edition caption under a print.
- Interactive controls press on the paper: on hover the misregister ghost snaps into register (the offset collapses toward zero).
## 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-019f3dcc-3bba-7572-b659-834730fc3cb0/DESIGN.with-shadcn.md`.
Machine-readable companions for automation: `/language/en-019f3dcc-3bba-7572-b659-834730fc3cb0/shadcn.json` (registry theme), `/language/en-019f3dcc-3bba-7572-b659-834730fc3cb0/shadcn-components.md` (component recipes) and `/language/en-019f3dcc-3bba-7572-b659-834730fc3cb0/shadcn-shots.json` (preview shots). The human-facing handoff is still 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 Build separation from the misregister ghost and the color-bar rail, never from ink outlines or grey borders.
- Do Let overprint blooms supply extra colour where two inks cross, instead of adding a fourth slab.
- Do Caption cards and sections with mono color-bar labels and a registration crosshair.
- Do Keep the warm newsprint ground and its fine grain under everything, including empty states.
- Do Keep the fluorescent inks to pink, cyan, and yellow, with violet/green only as overprints.
- Don't Reach for comic-book ink outlines, hard offset drop-shadows, or sticker keylines.
- Don't Wallpaper backgrounds with halftone dots or burst rays.
- Don't Mute the palette into pastels or monochrome restraint.
- Don't Use browser-default form controls; every control carries the paper, radius, and misregister.
- Don't Crowd one region into noise while another starves — balance density across the canvas.
## Imagery Direction
### Pairs With
impression
### Pairs With Art Style
impression
### Summary
Imagery is hand-pulled risograph screenprints in the Overprint art style: flat fluorescent spot-ink separations pulled out of register, overprint blooms where inks cross, on warm newsprint. Any subject — a market street, a face, a teapot — is dressed the same way.
### Hero
A wide three-ink riso pull of an editorial scene (a night market), misregister ghost on every edge, room on one side for the overlay copy.
The theme variables are generated from the tokens. Component recipes and preview shots have not been written for this language yet.
DESIGN.md with shadcn
For an app that uses shadcn/ui: the DESIGN.md plus the install list, theme variables, component recipes, preview shots and a starter TSX file, in one Markdown file.
Implementation filesShowHide
The same pieces as separate files: theme, CSS, TSX starter, recipes and the preview contract.
# Impression shadcn/ui Components
- Format: `component-recipes-v1`
- Author: `katagami-agent`
- Language: Impression (`impression`) · `en-019f3dcc-3bba-7572-b659-834730fc3cb0`
- Install: `npx shadcn@latest add button card input textarea select dialog sheet tabs badge separator checkbox switch slider tooltip dropdown-menu table`
## Intent
Impression is a limited-edition risograph screenprint pressed into an interface: three fluorescent spot inks on warm newsprint, every strong mark pulled a few pixels out of register, and extra colour arriving only where two inks overprint. These recipes carry that print into the standard shadcn/ui primitives. They do not add a second component system: install the primitives, apply the registry theme (`shadcn.json`), apply the Impression overrides in Token cues, then compose with the recipes below.
The three things a shadcn screen has to get right to read as Impression:
1. **Nothing is outlined.** Separation comes from the misregister ghost, the color-bar rail and warm-paper gutters. The one ink line in the language is the inset plate edge on a field.
2. **Each ink has a job.** Pink (`accent` #FF2E88) is the one primary pull and the "on" state. Cyan (`accent_2` #12B5C9) is the secondary plate and the ghost behind pink. Yellow (`accent_soft` #FFC300) is the highlighter: menu highlight, text selection, hover. Violet and green are never set; they appear where two of those inks overprint.
3. **Controls press into the paper.** At rest a control's ghost plate sits 3px right and 3px down of it; on hover it snaps into register in 180ms. One register error for the whole sheet, as on a real misregistered pull.
## Required primitives
All sixteen, from the standard registry path `@/components/ui/`:
| Primitive | Impression role |
|---|---|
| `button` | the pink pull, the cyan plate, the paper button |
| `card` | the feature card (24px) and the proof card (16px) |
| `input` | plate-edge field |
| `textarea` | the note to the printer |
| `select` | plate-edge trigger over a proof-sheet menu |
| `dialog` | the proof approval |
| `sheet` | run detail, pulled in from the right |
| `tabs` | ink-set filters, the active one on a pink plate |
| `badge` | spot-ink chips, status chips, overlapping swatch chips |
| `separator` | the color-bar rail |
| `checkbox` | square swatch that fills with the cyan plate |
| `switch` | pink plate on, paper recess off |
| `slider` | the misregister offset: pink thumb, cyan ghost |
| `tooltip` | a mono caption pill in ink |
| `dropdown-menu` | row actions on a proof sheet, yellow highlight |
| `table` | the press log: paper strips on the newsprint ground |
## Token cues
### What the registry theme ships
`shadcn.json` (the generated `registry:theme`) sets these light values, and the recipes rely on them unchanged:
`--background` #F7F1E4 (`bg`) · `--foreground` #1B1A17 (`text`) · `--card` and `--popover` #FFFDF7 (`surface`) · `--card-foreground` and `--popover-foreground` #1B1A17 · `--muted-foreground` #1B1A17 · `--destructive` #F0433A (`error`) · `--input` #1B1A17 (`border`, the plate-edge ink) · `--ring` #FF2E88 (`accent`) · `--radius` 16px (`md`).
### What Impression overrides, and why
The theme also ships values that would put the wrong ink in the wrong place, so apply this block after the theme:
```css
/* Impression overrides: load after the registry theme */
:root {
--primary: #FF2E88; /* theme ships #1B1A17. Impression's primary is the pink pull, and
Switch, Slider and the default Button all read --primary */
--primary-foreground: #FFFDF7; /* theme ships #ffffff. on_accent is the language's cream on pink */
--secondary: #12B5C9; /* theme ships #f4f4f5, a grey Impression does not have */
--secondary-foreground: #1B1A17; /* theme ships #111111; ink on cyan measures 7.03:1 */
--muted: #F7F1E4; /* theme ships #7C7566, a text colour, which shadcn would paint as
a fill (TabsList, slider track, row hover). The paper recess instead */
--accent: #FFC300; /* theme ships #FF2E88. shadcn paints --accent on select item and
(Radix) menu item highlights and ghost hovers; pink there would spend
the primary ink on every hover, and #ffffff on it measures 3.50:1 */
--accent-foreground: #1B1A17; /* theme ships #ffffff; ink on yellow measures 10.82:1 */
--border: transparent; /* theme ships #1B1A17, which shadcn draws as a 1px ink outline on
cards, dialogs, sheets, menus and table rows. Impression has none */
}
/* Dark-OS visitors: a fresh shadcn app puts .dark on <html> when the OS is dark, and the theme's
.dark block is generic grey. Impression is light only, so .dark restates the light values */
.dark {
--background: #F7F1E4;
--foreground: #1B1A17;
--card: #FFFDF7;
--card-foreground: #1B1A17;
--popover: #FFFDF7;
--popover-foreground: #1B1A17;
--primary: #FF2E88;
--primary-foreground: #FFFDF7;
--secondary: #12B5C9;
--secondary-foreground: #1B1A17;
--muted: #F7F1E4;
--muted-foreground: #1B1A17;
--accent: #FFC300;
--accent-foreground: #1B1A17;
--destructive: #F0433A;
--border: transparent;
--input: #1B1A17;
--ring: #FF2E88;
--chart-1: #1B1A17;
--chart-2: #f4f4f5;
--chart-3: #FF2E88;
--chart-4: #2FB170;
--chart-5: #FF8A1E;
--sidebar: #FFFDF7;
--sidebar-foreground: #1B1A17;
--sidebar-primary: #1B1A17;
--sidebar-primary-foreground: #ffffff;
--sidebar-accent: #12B5C9;
--sidebar-accent-foreground: #ffffff;
--sidebar-border: #1B1A17;
--sidebar-ring: #FF2E88;
}
/* The stock dialog and sheet close buttons hover on a 12px plate; Impression's controls are pills */
:is([data-slot="dialog-content"], [data-slot="sheet-content"]) > button { border-radius: 9999px; }
@theme inline {
--font-display: "Archivo Black", sans-serif;
--font-heading: "Archivo Black", sans-serif; /* the installed titles use font-heading */
--font-sans: "Space Grotesk", sans-serif;
--font-mono: "Space Mono", monospace;
}
/* Reduced motion: dialogs, sheets and popups animate under state prefixes that outrank a
motion-reduce: class, so stop them by slot, which both builds set */
@media (prefers-reduced-motion: reduce) {
[data-slot="dialog-overlay"], [data-slot="dialog-content"],
[data-slot="sheet-overlay"], [data-slot="sheet-content"],
[data-slot="select-content"], [data-slot="dropdown-menu-content"], [data-slot="tooltip-content"] {
animation: none !important;
transition: none !important;
}
}
```
Load the faces from `https://fonts.googleapis.com/css2?family=Archivo+Black&family=Space+Grotesk:wght@400;500;700&family=Space+Mono:wght@400;700&display=swap`. Archivo Black has one weight (400): set `font-normal` on every display element, or the installed titles' `font-medium` (`font-semibold` in Radix) makes the browser fake a heavier cut.
Impression is a light, warm-paper language. The theme's `dark` block is the generator's generic fallback (greys such as #0f1115), not Impression. A fresh `shadcn init` app follows the visitor's OS and adds the `dark` class to `<html>` for a dark-mode visitor, so the `.dark` block above restates Impression's light values, and every recipe below repeats its colours under `dark:` wherever an installed `dark:` class would otherwise win: `dark:bg-input/30` on fields, the paper button and the checkbox (an ink wash at 30%), `dark:data-[state=checked]:bg-primary` on the checkbox (pink instead of cyan), `dark:bg-input/80` and `dark:data-[state=unchecked]:bg-input/80` on the switch, `dark:data-active:bg-input/30` on the active tab, and `dark:hover:bg-accent/50` or `dark:hover:bg-muted/50` on ghost hovers. A dark-OS visitor then sees the same newsprint sheet with no change to the app. If you add the Sidebar (not in these sixteen), also set `--sidebar-accent-foreground: #1B1A17`, because the theme's #ffffff on `--sidebar-accent` #12B5C9 measures 2.48:1.
### Native tokens the recipes use
- **Inks:** pink `accent` #FF2E88, cyan `accent_2` #12B5C9 (also `info`), yellow `accent_soft` #FFC300. Cream `on_accent` #FFFDF7.
- **Paper:** `bg` #F7F1E4 (the newsprint ground and every recess), `surface` #FFFDF7 (cards, fields, menus). `text` #1B1A17 is the ink for all type; `muted` #7C7566 is for placeholders and the registration crosshair only.
- **Semantic:** `success` #2FB170, `warning` #FF8A1E, `error` #F0433A, always as an 8px dot or a fill under ink, never as text.
- **Radius:** only `rounded-none` (0), `rounded-[16px]` (`md`), `rounded-[24px]` (`lg`), `rounded-full` (`full`). shadcn's derived steps (`rounded-sm`, `rounded-md`, `rounded-xl`, `rounded-4xl`, the checkbox's `min(var(--radius-md),6px)`) resolve to sizes Impression does not have, so every recipe names its radius.
- **Print shadows:** `sm` `shadow-[0_2px_0_rgba(27,26,23,0.10)]` for chips, rows and the rail; `md` `shadow-[0_10px_24px_-12px_rgba(27,26,23,0.30)]` under 16px surfaces; `lg` `shadow-[0_20px_48px_-20px_rgba(27,26,23,0.34)]` under 24px feature cards, dialogs and sheets. The ghost plate `shadow-[3px_3px_0_0_#12B5C9]` is an ink layer, not a shadow: never black, never blurred.
- **Spacing:** 4, 8, 16, 24, 40, 64, 96 (`1`, `2`, `4`, `6`, `10`, `16`, `24` in Tailwind). Titles always get 40 above them (`pt-10`).
- **Type:** Archivo Black 61px / 48.8px / 31.25px for display; Space Grotesk 17px body and 20px lead; Space Mono 700 at 12.8px, uppercase, `tracking-[0.14em]` for color-bar captions and control labels.
- **Motion:** `duration-[180ms] ease-[cubic-bezier(0.2,0.9,0.2,1)]`, with `motion-reduce:transition-none` on every moving part and the reduced-motion block above for dialogs, sheets and popups.
### Contrast (computed, WCAG 2.x)
| Text | Ground | Ratio | Rule |
|---|---|---|---|
| `text` #1B1A17 | `surface` #FFFDF7 | 17.11:1 | all body, labels, captions |
| `text` #1B1A17 | `bg` #F7F1E4 | 15.46:1 | type on the newsprint ground |
| `bg` #F7F1E4 | `text` #1B1A17 | 15.46:1 | tooltip |
| `on_accent` #FFFDF7 | `accent` #FF2E88 | 3.44:1 | bold labels at 20px and up, and display type only |
| `text` #1B1A17 | `accent` #FF2E88 | 4.97:1 | any smaller label on a pink plate (tabs, chips) |
| `text` #1B1A17 | `accent_2` #12B5C9 | 7.03:1 | secondary button, cyan chips, checked checkbox |
| `text` #1B1A17 | `accent_soft` #FFC300 | 10.82:1 | highlighted menu item, selection, hover |
| `text` #1B1A17 | `error` #F0433A | 4.61:1 | destructive fill |
| `muted` #7C7566 | `surface` #FFFDF7 | 4.49:1 | placeholders only, never information |
| `muted` #7C7566 | `bg` #F7F1E4 | 4.06:1 | never text on the ground |
Non-text: pink against `bg` is 3.11:1 and against `surface` 3.44:1, so the pink focus edge, switch track and slider thumb all clear 3:1. Cyan against `surface` is only 2.43:1, so cyan never marks a state by itself: the checked checkbox keeps its ink plate edge, and the ghost is decoration.
## Visual character to preserve
- **The misregister knockout.** Headlines and key marks carry a cyan ghost (4px left, 3px down) and a pink ghost (4px right, 2px up) behind ink type, both `mix-blend-multiply` at full strength, so the two ghosts print through each other like ink instead of stacking as flat paint, and where they cross outside the ink they go deep indigo. The ghosts are `aria-hidden` copies, so a screen reader hears the headline once. On hover they snap into register. On a phone the knockout stays on headlines only.
- **Overprint blooms.** Violet and green are never a declared colour or a slab; they exist only where two token inks are laid over each other with `mix-blend-multiply`. Where a bloom is meant to read violet (the fourth swatch of the rail and the overlapping swatch chips), print the cyan plate at 70% over pink (`opacity-70`), which lands at hue 279, the violet the published pages show; at full strength these two inks multiply past violet to a deep indigo. Green is yellow over cyan at full strength. The misregister ghosts are full-strength plates, so where they cross outside the ink they print that deep indigo, as a heavy double pull does; that is the knockout, not a bloom.
- **The color-bar rail.** A 10px pill strip of solid swatches (pink, cyan, yellow, then the violet overprint) with a registration crosshair. It heads sections, stands in for separators and runs along section edges on desktop.
- **Mono color-bar captions.** Every card, dialog, sheet and menu opens with rail + crosshair + a Space Mono 700 caption in ink, set like the edition line under a print: `EDITION OF 120 · PLATES P·C·Y`.
- **Warm newsprint ground, fine grain.** `bg` #F7F1E4 under everything, with a faint paper grain and registration-crosshair field; cards are the brighter `surface` #FFFDF7 on a soft print shadow. Never a flat white screen, never halftone dots.
- **Poster-weight display.** Archivo Black set huge and tight (`tracking-[-0.02em]`), with the mono caption underneath doing the annotating.
## ShadSync visual profile
```json
{
"family": "editorial",
"material": "paper",
"contour": "default",
"border": "none",
"underlay": false,
"grain": true,
"stickerBadges": false,
"motion": "still",
"density": "balanced",
"accents": ["fluorescent pink #FF2E88", "cyan #12B5C9", "yellow #FFC300"],
"radii": { "card": "24px", "control": "9999px", "chip": "9999px" }
}
```
- **family `editorial`:** a calm 12-column grid with a feature column and a proof column carries the loud ink.
- **material `paper`:** warm newsprint with grain; the card is brighter stock on the same paper.
- **contour `default`, border `none`:** pills for buttons and chips, 16px and 24px for surfaces, square only for the checkbox swatch; no outline anywhere.
- **underlay `false`:** the misregister lives on type and controls, not as a coloured panel behind cards.
- **stickerBadges `false`:** chips are flat spot-ink or paper, never a keylined sticker.
- **motion `still`:** nothing floats or bobs; the only movement is the ghost snapping into register.
- **density `balanced`:** bold chunks of ink with warm-paper gutters between them.
- **radii:** the feature card at 24px (the proof card steps down to 16px), buttons, tabs, switches and chips as pills; fields are 16px and the checkbox swatch is the one square.
## Signature component recipes
Every class string works on both shadcn builds: Radix (`new-york`) marks states as `data-[state=checked]`, `data-[state=active]`, `data-[state=open]`, `data-[placeholder]`, `data-[orientation=horizontal]`; Base UI (`base-nova`, the build katagami.ai itself uses) marks them `data-checked`, `data-active`, `data-popup-open`, `data-placeholder`, `data-horizontal`. Where a recipe sets a state value it gives both, because tailwind-merge only drops the installed class when the prefix matches, and the installed state classes outrank a plain utility. Where an installed `dark:` class sets a colour the recipe also sets, the recipe repeats its colour under `dark:` with the same state prefix, so a dark-OS visitor sees what the `.dark` block restates. Each recipe was merged with the installed component sources and checked for surviving stock classes.
### Button
Four jobs, one pill, labels never wrap (the installed `whitespace-nowrap` stays).
- **The pull** (`variant="default"`, `size="lg"`, one per view): the pink plate with the cyan ghost behind it. Cream on pink is 3.44:1, so the label is Space Mono 700 at 20px, which counts as large bold text; there is no small pink button.
```
h-14 rounded-full border-0 px-10 font-mono text-[20px] font-bold uppercase tracking-[0.06em]
shadow-[3px_3px_0_0_#12B5C9] hover:bg-primary [a]:hover:bg-primary hover:shadow-[0_0_0_0_#12B5C9]
transition-[box-shadow] duration-[180ms] ease-[cubic-bezier(0.2,0.9,0.2,1)] motion-reduce:transition-none
focus-visible:ring-[3px] focus-visible:ring-[#1B1A17]
```
`hover:bg-primary` and `[a]:hover:bg-primary` replace the stock `hover:bg-primary/90` (new-york-v4), `hover:bg-primary/80` (base-nova) and `[a]:hover:bg-primary/80` (the installed set, when the button renders a link), which would print a paler pink the tokens do not have. Every button sets its own height, since the installed default is `h-8`, and its own focus ring colour: the installed `focus-visible:ring-ring/50` is a half-strength pink the tokens do not have, so the other buttons set full pink (3.11:1 on the ground). The focus ring is ink, because a pink ring vanishes against a pink plate.
- **The cyan plate** (`variant="secondary"`): cyan with an ink label (7.03:1) and a pink ghost that snaps into register.
```
h-12 rounded-full border-0 px-6 font-mono text-[12.8px] font-bold uppercase tracking-[0.14em]
shadow-[3px_3px_0_0_#FF2E88] hover:bg-secondary hover:shadow-[0_0_0_0_#FF2E88]
transition-[box-shadow] duration-[180ms] ease-[cubic-bezier(0.2,0.9,0.2,1)] motion-reduce:transition-none
focus-visible:ring-[3px] focus-visible:ring-[#FF2E88]
```
- **The paper button** (`variant="outline"`): `surface` stock on the `sm` print shadow, no ring. Hover lays the yellow plate under the label.
```
h-12 rounded-full border-0 bg-[#FFFDF7] px-6 font-mono text-[12.8px] font-bold uppercase tracking-[0.14em]
text-[#1B1A17] shadow-[0_2px_0_rgba(27,26,23,0.10)] hover:bg-[#FFC300] hover:text-[#1B1A17]
aria-expanded:bg-[#FFC300] aria-expanded:text-[#1B1A17] focus-visible:ring-[3px] focus-visible:ring-[#FF2E88]
dark:bg-[#FFFDF7] dark:hover:bg-[#FFC300] dark:aria-expanded:bg-[#FFC300]
```
The `aria-expanded:` pair beats the installed `aria-expanded:bg-muted` when the button opens a menu. The `dark:` trio replaces the outline variant's `dark:bg-input/30` and `dark:hover:bg-input/50`, which would print an ink wash on the paper under `.dark`.
- **Ghost** (`variant="ghost"`): the bare mono label in ink; hover lays the yellow plate. The class is needed because the installed ghost hovers with `hover:bg-muted` in one build and `hover:bg-accent` in the other.
```
h-12 rounded-full px-6 font-mono text-[12.8px] font-bold uppercase tracking-[0.14em] text-[#1B1A17]
hover:bg-[#FFC300] hover:text-[#1B1A17] aria-expanded:bg-[#FFC300] aria-expanded:text-[#1B1A17]
focus-visible:ring-[3px] focus-visible:ring-[#FF2E88] dark:hover:bg-[#FFC300]
```
`dark:hover:bg-[#FFC300]` replaces the stock `dark:hover:bg-accent/50` (new-york) and `dark:hover:bg-muted/50` (base-nova and the installed set).
- **Destructive:** do not pass `variant="destructive"`; its tinted `bg-destructive/10` and red text on paper (3.71:1) are not Impression. Use `variant="outline"` with the paper button's classes (`border-0`, pill, mono label) and `bg-[#F0433A] text-[#1B1A17] hover:bg-[#F0433A] dark:bg-[#F0433A] dark:hover:bg-[#F0433A]` (4.61:1), and say what is lost: "Scrap 60 sheets".
- `size="sm"` is `h-10 px-4` for the paper and cyan buttons only. Disabled keeps the installed `disabled:opacity-50` and adds `disabled:shadow-none`, so a dead control has no ghost.
### Card
Two cards, never nested, never outlined. The installed `border` (Radix) and `ring-1 ring-foreground/10` (Base UI) both go; `py-0` also makes the installed `has-data-[slot=card-footer]:pb-0` moot.
- **Feature card** (the hero pull): `gap-0 rounded-[24px] border-0 bg-card py-0 text-[17px] ring-0 shadow-[0_20px_48px_-20px_rgba(27,26,23,0.34)]`. `text-[17px]` replaces the installed `text-sm`, so loose body text inside the card is 17px too.
- **Proof card** (the proof column): `gap-0 rounded-[16px] border-0 bg-card py-0 text-[17px] ring-0 shadow-[0_10px_24px_-12px_rgba(27,26,23,0.30)]`.
- `CardHeader`: `gap-4 px-6 pt-10 pb-4`, opening with the color-bar caption (rail, crosshair, mono label), so the title is never stuck to the top edge.
- `CardTitle`: `font-display font-normal leading-[1.05] tracking-[-0.02em]` at `text-[48.8px]` on a feature card, `text-[31.25px] leading-[1.1]` on a proof card, wrapped in the misregister knockout.
- `CardDescription`: `text-[17px] leading-[1.55] text-[#1B1A17]`.
- `CardContent`: `px-6`, because the stock padding is 16px in the installed and base-nova cards and 24px in new-york-v4.
- `CardFooter`: `gap-4 border-0 bg-transparent px-6 pt-4 pb-6`. The installed footer is a band (`border-t bg-muted/50 p-4`); `border-0` and `bg-transparent` remove it, so the actions sit on the card's own stock.
### Input
A field is a sheet of `surface` stock with the one ink line Impression allows: a 2px inset plate edge. On focus the edge re-inks pink and thickens to 3px; that change is the focus indicator (pink on `surface` 3.44:1).
```
h-12 rounded-[16px] border-0 bg-[#FFFDF7] px-4 text-[17px] md:text-[17px] text-[#1B1A17]
shadow-[inset_0_0_0_2px_#1B1A17] placeholder:text-[#7C7566]
selection:bg-[#FFC300] selection:text-[#1B1A17]
transition-[box-shadow] duration-[180ms] ease-[cubic-bezier(0.2,0.9,0.2,1)]
focus-visible:ring-0 focus-visible:shadow-[inset_0_0_0_3px_#FF2E88]
aria-invalid:ring-0 aria-invalid:shadow-[inset_0_0_0_3px_#F0433A]
dark:bg-[#FFFDF7]
```
`md:text-[17px]` is required: the installed `md:text-sm` would otherwise drop the text to 14px on desktop. `dark:bg-[#FFFDF7]` replaces the installed `dark:bg-input/30`, an ink wash over the paper under `.dark`. The label sits above in a mono caption (`font-mono text-[12.8px] font-bold uppercase tracking-[0.14em] text-[#1B1A17]`); an error message sits below in ink, led by an 8px `error` dot, because `error` as text on paper measures 3.71:1.
### Textarea
The note to the printer, same plate-edge chassis as Input, sized for a sentence of instruction.
```
min-h-32 rounded-[16px] border-0 bg-[#FFFDF7] px-4 py-4 text-[17px] md:text-[17px] leading-[1.55]
text-[#1B1A17] shadow-[inset_0_0_0_2px_#1B1A17] placeholder:text-[#7C7566] resize-y
focus-visible:ring-0 focus-visible:shadow-[inset_0_0_0_3px_#FF2E88]
aria-invalid:ring-0 aria-invalid:shadow-[inset_0_0_0_3px_#F0433A]
dark:bg-[#FFFDF7]
```
Under it, a mono character count in ink: `118 / 280`.
### Select
- `SelectTrigger`: the Input chassis.
```
h-12 data-[size=default]:h-12 w-full rounded-[16px] border-0 bg-[#FFFDF7] px-4 text-[17px] text-[#1B1A17]
shadow-[inset_0_0_0_2px_#1B1A17] data-[placeholder]:text-[#7C7566] data-placeholder:text-[#7C7566]
focus-visible:ring-0 focus-visible:shadow-[inset_0_0_0_3px_#FF2E88]
data-[state=open]:shadow-[inset_0_0_0_3px_#FF2E88] data-popup-open:shadow-[inset_0_0_0_3px_#FF2E88]
aria-invalid:ring-0 aria-invalid:shadow-[inset_0_0_0_3px_#F0433A]
dark:bg-[#FFFDF7] dark:hover:bg-[#FFFDF7]
```
The height goes under `data-[size=default]:`, because the installed `data-[size=default]:h-8` (or `h-9`) outranks a plain `h-12`. The `dark:` pair replaces the installed `dark:bg-input/30` and `dark:hover:bg-input/50`. The chevron carries its own `text-muted-foreground`, which stays ink because the theme's `--muted-foreground` is #1B1A17 and the override leaves it alone.
- `SelectContent`: a proof sheet, `rounded-[16px] border-0 ring-0 bg-[#FFFDF7] p-2 shadow-[0_10px_24px_-12px_rgba(27,26,23,0.30)]`, headed by a mono caption when it lists plates or stock. `ring-0` removes the installed `ring-1 ring-foreground/10` frame.
- `SelectItem`: `rounded-full py-2 pl-4 pr-10 text-[17px] focus:bg-[#FFC300] focus:text-[#1B1A17]`. The highlight is the yellow plate with ink on it (10.82:1). The installed item already reads `--accent`, so the override alone paints it; the `focus:` pair keeps it yellow in a build that highlights with `--muted`.
### Dialog
The proof approval: a sheet of `surface` stock laid on the press bed.
- `DialogContent`: `gap-6 rounded-[24px] border-0 ring-0 bg-[#FFFDF7] p-10 text-[17px] shadow-[0_20px_48px_-20px_rgba(27,26,23,0.34)] sm:max-w-[560px]`, opened with the color-bar caption (`PROOF 3 OF 3 · PLATES C+P`). `ring-0` removes the installed `ring-1 ring-foreground/10` frame; `sm:max-w-[560px]` replaces the installed `sm:max-w-sm`.
- `DialogTitle`: `font-display text-[31.25px] font-normal leading-[1.1] tracking-[-0.01em]` in the misregister knockout. `DialogDescription`: `text-[17px] text-[#1B1A17]`.
- `DialogFooter`: `mx-0 mb-0 gap-4 border-0 bg-transparent p-0 pt-4`. The installed footer is a grey band pulled to the edges (`-mx-4 -mb-4 border-t bg-muted/50 p-4`); these classes put the actions back on the dialog's own stock. One pull ("Send to press") and one paper button ("Pull another proof"). Pass `showCloseButton={false}` to `DialogContent` where the footer already offers the way out.
- Scrim: in `components/ui/dialog.tsx`, change the overlay's black scrim (`bg-black/50`, or `bg-black/10` with a backdrop blur in newer builds) to `bg-[#1B1A17]/40` with no blur: the ink, not a cold black or frosted glass.
### Sheet
Run detail pulled in from the right edge, the way a sheet comes off the drum.
- `SheetContent side="right"`: the installed sheet sets its width and border under `data-[side=right]:` (`w-3/4`, `sm:max-w-sm`, `border-l`), so Impression's values go there too, shadow included:
```
gap-6 rounded-l-[24px] border-0 bg-[#FFFDF7] p-0 text-[17px]
w-full sm:max-w-[440px] data-[side=right]:w-full data-[side=right]:sm:max-w-[440px] data-[side=right]:border-l-0
shadow-[0_20px_48px_-20px_rgba(27,26,23,0.34)] data-[side=right]:shadow-[0_20px_48px_-20px_rgba(27,26,23,0.34)]
duration-[180ms] ease-[cubic-bezier(0.2,0.9,0.2,1)]
data-[state=open]:duration-[180ms] data-[state=closed]:duration-[180ms]
```
- `SheetHeader`: `gap-4 px-6 pt-10`, with the color-bar rail across its top edge and the mono caption (`RUN 04 · PRESS A`). The rail never runs down the sheet's side.
- `SheetTitle`: display 31.25px, `font-normal`, in the knockout. Body rows are label/value pairs in Space Mono 17px with `tabular-nums`.
- `SheetFooter`: `flex-row gap-4 px-6 pt-4 pb-6`; the one pull for that run ("Re-pull 60 sheets") and a paper button.
- Scrim: the same `bg-[#1B1A17]/40` edit in `components/ui/sheet.tsx`.
### Tabs
Ink-set filters set as mono labels on the paper; the active one sits on a pink plate with an ink label (4.97:1; cream at this size would be 3.44:1).
- `TabsList`: `h-auto group-data-horizontal/tabs:h-auto group-data-[orientation=horizontal]/tabs:h-auto gap-2 bg-transparent p-0`. The list's height sits under `group-data-horizontal/tabs:h-8` (Base UI and the installed set) or `group-data-[orientation=horizontal]/tabs:h-9` (Radix new-york-v4), so each gets its own `h-auto`.
- `TabsTrigger`:
```
h-10 flex-none rounded-full border-0 px-4 font-mono text-[12.8px] font-bold uppercase tracking-[0.14em]
text-[#1B1A17] not-data-active:hover:bg-[#FFC300] data-[state=active]:hover:bg-[#FF2E88]
data-active:bg-[#FF2E88] data-active:text-[#1B1A17] data-active:shadow-none
group-data-[variant=default]/tabs-list:data-active:shadow-none
data-[state=active]:bg-[#FF2E88] data-[state=active]:text-[#1B1A17] data-[state=active]:shadow-none
group-data-[variant=default]/tabs-list:data-[state=active]:shadow-none
focus-visible:ring-[3px] focus-visible:ring-[#1B1A17] focus-visible:outline-0
dark:data-active:bg-[#FF2E88] dark:data-[state=active]:bg-[#FF2E88]
```
The active tab is marked `data-active` (Base UI) or `data-[state=active]` (Radix), and its stock shadow sits under `group-data-[variant=default]/tabs-list:data-active:shadow-sm` or `group-data-[variant=default]/tabs-list:data-[state=active]:shadow-sm`; each gets its own replacement above. The yellow hover is `not-data-active:hover:`, so it only lands on inactive tabs: a plain `hover:` would outrank shadcn's `data-active:` (which adds no specificity) and turn the active tab yellow. `data-[state=active]:hover:bg-[#FF2E88]` keeps the Radix active tab pink in a project without shadcn's custom variants. The focus ring is ink, because a pink ring merges into the pink plate, and `focus-visible:outline-0` drops the stock 1px pink outline that would otherwise sit inside it. Under `.dark` the stock `dark:data-active:bg-input/30` (or `dark:data-[state=active]:bg-input/30`) would lay an ink wash over the plate, so the pink is repeated under both `dark:` prefixes; the stock `dark:text-muted-foreground` and `dark:data-active:text-foreground` already resolve to ink. The trigger's stock underline sits under `group-data-horizontal/tabs:after:` or `group-data-[orientation=horizontal]/tabs:after:` and only shows in the line variant, so leave the list on its default variant: in `variant="line"`, `group-data-[variant=line]/tabs-list:data-active:bg-transparent` outranks the pink plate.
- Labels are the product's ink sets: `ALL` `PINK RUNS` `CYAN RUNS` `OVERPRINTS`.
### Badge
Three kinds of chip, all `h-8 gap-2 rounded-full border-0 px-4 font-mono text-[12.8px] font-bold uppercase tracking-[0.14em]` (Label-Mono), never wrapping. Start from `variant="secondary"` and set the fill yourself.
- **Spot-ink chip** (a fact about the print): `bg-[#FF2E88] text-[#1B1A17]` (4.97:1), `bg-[#12B5C9] text-[#1B1A17]` (7.03:1) or `bg-[#FFC300] text-[#1B1A17]` (10.82:1). Ink labels on all three; cream only ever sits on pink at 20px bold.
- **Status chip** (where a run is): paper chip with an 8px semantic dot and an ink label: `bg-[#F7F1E4] text-[#1B1A17]` on a card, `bg-[#FFFDF7]` on the ground. Dots: `success` for Cured, `warning` for Drying, `info` for On press, `error` for Re-pull. Semantic colour stays a dot.
- **Overlapping swatch chips** (which plates a print uses): three `size-4 rounded-full` discs, each overlapping the last by 8px (`-ml-2`). The pink disc sits on top and clips a `opacity-70 mix-blend-multiply` cyan disc inside it, so the lens where pink and cyan cross is the violet overprint; the full cyan disc sits beneath it, and the yellow disc multiplies over cyan into a real green. Both blooms are made by the inks, never picked from a swatch (see `Plates` in the example).
### Separator
The separator is the color-bar rail, not a hairline. Render the installed `Separator` with children, and mark it `aria-hidden`: the rail is ornament, so a screen reader should not announce a separator. (`decorative` does the same job but is a Radix-only prop; the Base UI `Separator` does not accept it, so `aria-hidden` is the form that compiles in both builds.)
```tsx
<Separator
aria-hidden
className="isolate flex h-2.5 w-[88px] overflow-hidden rounded-full bg-transparent shadow-[0_2px_0_rgba(27,26,23,0.10)]
data-horizontal:h-2.5 data-horizontal:w-[88px]
data-[orientation=horizontal]:h-2.5 data-[orientation=horizontal]:w-[88px]"
>
<span className="flex-1 bg-[#FF2E88]" />
<span className="flex-1 bg-[#12B5C9]" />
<span className="flex-1 bg-[#FFC300]" />
<span className="relative flex-1 bg-[#FF2E88]"><span className="absolute inset-0 bg-[#12B5C9] opacity-70 mix-blend-multiply" /></span>
</Separator>
```
The size classes are repeated under `data-horizontal:` (Base UI) and `data-[orientation=horizontal]:` (Radix), because the installed `h-px` and `w-full` sit under those prefixes and outrank plain ones. For a full-width section edge use `w-full` in all three places. Between rows inside a card there is no separator at all: a 16px paper gutter does it.
### Checkbox
A square swatch (radius 0, the only square control), replacing the installed 4px or 6px corner. The plate edge stays when checked, so the state reads against paper even though cyan alone is 2.43:1.
```
size-6 rounded-none border-0 bg-[#FFFDF7] shadow-[inset_0_0_0_2px_#1B1A17]
data-[state=checked]:bg-[#12B5C9] data-[state=checked]:text-[#1B1A17] data-[state=checked]:border-transparent
data-checked:bg-[#12B5C9] data-checked:text-[#1B1A17]
focus-visible:ring-[3px] focus-visible:ring-[#FF2E88]
dark:bg-[#FFFDF7] dark:data-[state=checked]:bg-[#12B5C9] dark:data-checked:bg-[#12B5C9]
```
The `dark:` classes replace the installed `dark:bg-input/30` and `dark:data-[state=checked]:bg-primary` / `dark:data-checked:bg-primary`, which under `.dark` would wash the empty swatch in ink and fill a checked one pink. The tick is the installed `CheckIcon`, inked `#1B1A17` on cyan (7.03:1). Label to the right in Space Grotesk 17px: "Signed and numbered on press".
### Switch
Off is a paper recess with the plate edge; on is the pink plate. Style the root by class, and the thumb once in `components/ui/switch.tsx`.
- Root:
```
h-8 w-14 data-[size=default]:h-8 data-[size=default]:w-14 border-0 bg-[#F7F1E4] shadow-[inset_0_0_0_2px_#1B1A17]
data-[state=unchecked]:bg-[#F7F1E4] data-unchecked:bg-[#F7F1E4]
data-[state=checked]:bg-[#FF2E88] data-checked:bg-[#FF2E88]
data-[state=checked]:shadow-none data-checked:shadow-none
focus-visible:ring-[3px] focus-visible:ring-[#1B1A17]
dark:bg-[#F7F1E4] dark:data-[state=unchecked]:bg-[#F7F1E4] dark:data-unchecked:bg-[#F7F1E4]
dark:data-[state=checked]:bg-[#FF2E88] dark:data-checked:bg-[#FF2E88]
```
Both current registry builds size the track under `data-[size=default]:` (`h-[1.15rem] w-8` in new-york-v4, `h-[18.4px] w-[32px]` in base-nova), which outranks a plain `h-8 w-14`, so the size is given in both forms. The installed off state is `bg-input` (plain or under `data-[state=unchecked]:`/`data-unchecked:`), which with `--input` #1B1A17 would print a solid ink pill. The focus ring is ink, because a pink ring merges into the pink track when the switch is on. Under `.dark` the installed track adds `dark:bg-input/80` (plain, so it would also cover the pink when on) and the registry tracks `dark:data-[state=unchecked]:bg-input/80` / `dark:data-unchecked:bg-input/80`; the last two lines repeat both states under `dark:`.
- Thumb (replace its class in the file; the registry thumbs size and move under `group-data-[size=default]/switch:`, which a merged class would not beat):
```
pointer-events-none block size-6 rounded-full bg-[#FFFDF7] shadow-[0_2px_0_rgba(27,26,23,0.10)] ring-0
data-[state=unchecked]:translate-x-1 data-unchecked:translate-x-1
data-[state=checked]:translate-x-7 data-checked:translate-x-7
transition-[translate] duration-[180ms] ease-[cubic-bezier(0.2,0.9,0.2,1)] motion-reduce:transition-none
```
Move it only with `translate-x-*`: Tailwind v4 moves the thumb with the `translate` property, so a `transform` would add to the stock offset instead of replacing it. At either end 4px of track shows beside the thumb: 4 + 24 + 28 = 56.
- The pink track is 3.11:1 against the ground and the cream thumb 3.44:1 against pink, so both states hold 3:1.
### Slider
The misregister offset control, the language's own variable made adjustable. Replace the classes of its three parts in `components/ui/slider.tsx` rather than merging into them: the registry thumbs add `hover:ring-3`/`hover:ring-4` in the theme's half-strength ring colour, which a merge would keep.
- Track: `relative h-2.5 w-full grow overflow-hidden rounded-full bg-[#F7F1E4] shadow-[inset_0_0_0_2px_#1B1A17] data-horizontal:h-2.5 data-[orientation=horizontal]:h-2.5` (the installed track sets `h-1.5` plain in one build and under the orientation prefix in the other).
- Range: `absolute h-full bg-primary data-horizontal:h-full data-[orientation=horizontal]:h-full` (pink, from the override). Keep the positioning: the Radix range is sized only by `absolute` and its height, so a bare `bg-primary` collapses it to nothing; Base UI positions its indicator itself.
- Thumb: `block size-7 shrink-0 rounded-full border-0 bg-[#FF2E88] shadow-[3px_3px_0_0_#12B5C9] outline-hidden transition-[box-shadow] duration-[180ms] ease-[cubic-bezier(0.2,0.9,0.2,1)] hover:shadow-[0_0_0_0_#12B5C9] focus-visible:ring-[3px] focus-visible:ring-[#1B1A17] has-[:focus-visible]:ring-[3px] has-[:focus-visible]:ring-[#1B1A17] motion-reduce:transition-none`. The ghost snaps into register under the finger. `outline-hidden` keeps the browser's own focus outline off the Radix thumb (the stock class it replaces carried it), and the `has-[:focus-visible]:` pair draws the ink ring in Base UI, which puts keyboard focus on a hidden input inside the thumb rather than on the thumb.
- Read-out above the right end in Space Mono 17px (`3.0 mm`), and the band under the rail in a mono caption: `0 MM` at the left, `5 MM` at the right.
### Tooltip
A mono caption pill in ink. The theme's `bg-foreground text-background` already give #F7F1E4 on #1B1A17 (15.46:1).
- `TooltipContent`: `max-w-none rounded-full px-4 py-2 font-mono text-[12.8px] font-bold tracking-[0.14em] shadow-none motion-reduce:animate-none`. `shadow-none` drops the installed grey `shadow-md`; an ink pill on paper needs no shadow. `max-w-none` lifts base-nova's stock `max-w-xs` (320px), which would break a caption onto a second line inside the pill; keep captions short enough for one line. Keep the installed arrow.
- Content is a figure, not a sentence: `DRIFT 5.2 MM · 0.2 PAST THE BAND`.
### Dropdown menu
Row actions (`dropdown-menu`) on a proof sheet; the highlighted item gets the yellow plate.
- `DropdownMenuContent`: `min-w-56 rounded-[16px] border-0 ring-0 bg-[#FFFDF7] p-2 shadow-[0_10px_24px_-12px_rgba(27,26,23,0.30)]` (the installed menu has `border border-border` and `shadow-md`; these replace both).
- `DropdownMenuLabel`: the mono caption with a short rail: `px-4 py-2 font-mono text-[12.8px] font-bold uppercase tracking-[0.14em] text-[#1B1A17]`. In a Base UI build the label must sit inside a `DropdownMenuGroup`, or the menu throws.
- `DropdownMenuItem`: `rounded-full px-4 py-2 text-[17px] focus:bg-[#FFC300] focus:text-[#1B1A17]`; ink on yellow when highlighted (10.82:1). The `focus:` pair is required: the installed item highlights with `focus:bg-muted focus:text-foreground`, not `--accent`, and would otherwise show only the faint paper recess.
- `DropdownMenuShortcut`: `font-mono text-[12.8px] tracking-[0.14em] text-[#1B1A17]`.
- `DropdownMenuSeparator`: `my-2`. With `--border` transparent the 1px rule is invisible, so it reads as a paper gutter: 8px either side of it.
- A destructive item is a plain item led by an 8px `error` dot with an ink label ("Take off the shelf"). Do not pass `variant="destructive"`: its `data-[variant=destructive]:text-destructive` and `focus:bg-destructive/10` outrank your colours and print red text on paper.
### Table
The press log. The table sits on the newsprint ground, never inside a card; each row is a strip of `surface` stock, and 8px of paper separates rows. No rules, no zebra.
- `Table`: `border-separate border-spacing-y-2 text-[17px]`. The installed wrapper already scrolls sideways inside itself on a phone.
- `TableHead`: `h-10 px-4 font-mono text-[12.8px] font-bold uppercase tracking-[0.14em] text-[#1B1A17]` (replaces the installed `h-9 px-2 font-medium text-muted-foreground`).
- `TableRow`: `border-0 bg-[#FFFDF7] hover:bg-[#FFFDF7] has-aria-expanded:bg-[#FFFDF7] data-[state=selected]:bg-[#FFC300]`. The stock `hover:bg-muted/50`, and the registry's `has-aria-expanded:bg-muted/50` while a row's menu is open, would print a half-tint the tokens do not have.
- `TableCell`: `px-4 py-4 shadow-[0_2px_0_rgba(27,26,23,0.10)] first:rounded-l-[16px] last:rounded-r-[16px]`. The print shadow sits on the cells so it follows the row's rounded ends.
- Figures (sheets, drift, run) in Space Mono with `tabular-nums`. The plates column is overlapping swatch chips; the status column is a status chip. The row that is out of band carries its `error` dot and a tooltip on the drift, never a coloured row fill.
- On a phone, hide the run and drift columns (`hidden sm:table-cell`) rather than squeeze them.
## Preview shots
`preview-shots.json` (`renderable-v1`) carries three scenes from one product, a riso studio's press console. Every figure adds up across the scene.
- **`application-shell` · Press floor** (desktop): "Two presses running". A pulled headline over the paper, a color-bar rail, a feature card for the run on press A beside a proof column, and the run table below: 234 sheets pulled today (96 + 18 + 120), 140 still to pull (54 + 26 + 60), 1 of 4 runs out of band.
- **`detail-editor` · Set up an edition** (tablet): "Rooftops at dusk". Plate-edge fields, the ink-plate select, the note to the printer, the misregister offset slider at 3.0 mm of a 0 to 5 mm band, a cyan checkbox, a pink switch, and the proof approval dialog: 64 sheets = 60 prints + 4 artist proofs.
- **`data-operations` · Edition shelf** (mobile): "134 prints left on the shelf". Ink-set tabs, paper-strip rows with overlapping swatch chips, status chips, a row menu and a tooltip: 256 of 390 sold or reserved (112 + 80 + 23 + 41), 134 left (8 + 0 + 17 + 109).
Each shot lists its primitives, what it must show and what it must avoid, so the renderer composes Impression rather than a generic theme.
## Implementation contract
- Start from local `@/components/ui/*` shadcn primitives; do not build a second component system.
- Apply `shadcn.json` first, then the Impression override block from Token cues, then these recipes. Impression is light only: under a `dark` class (a dark-OS visitor in a fresh shadcn app) the Token cues `.dark` block restates the light values and each recipe repeats its colours under `dark:`, so the page looks the same.
- Katagami token names (`accent`, `accent_2`, `accent_soft`, `on_accent`, `bg`, `surface`, `text`, `muted`) stay the source of truth; shadcn variable names are only the export surface.
- Where the installed component sets a property under a prefix (`data-[state=…]:` or `data-active:`/`data-checked:`, `data-[size=…]:`, `data-[side=right]:`, `group-data-horizontal/tabs:`, `aria-expanded:`, `md:`), set yours under the same prefix, and give both builds' state prefixes, or tailwind-merge keeps theirs. Set every button's height; the installed default is `h-8`. Remove the stock frames with `ring-0` (Card, select popup, DialogContent) and the stock footer bands with `border-0 bg-transparent` (CardFooter, DialogFooter, plus `mx-0 mb-0` on DialogFooter). Where a recipe restyles an inner part (switch thumb, slider track, range and thumb, dialog and sheet scrim), edit that line in the component file once: the components are yours.
- Radius only from 0, 16px, 24px and 9999px; spacing only from 4, 8, 16, 24, 40, 64, 96; body 17px, labels 12.8px mono, display in Archivo Black at `font-normal`.
- One pink pull per view. Cream on pink only at 20px bold or display size; everything smaller on pink is ink.
- Do: let the ghost, the rail and paper gutters separate; caption every card and section; let violet and green come only from `mix-blend-multiply` overprints; keep the newsprint grain under empty states too.
- Do not: outline anything in ink or grey (the plate edge on fields is the one exception); wallpaper with halftone dots or burst rays; mute the inks into pastels; set semantic colours as text; use browser-default controls.
## Copy-paste component example
A feature card from the press floor: the color-bar caption, a misregister headline, overlapping swatch chips, a status chip, the rail as separator, one pull and one cyan plate.
```tsx
import type { ReactNode } from "react";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
const press = "duration-[180ms] ease-[cubic-bezier(0.2,0.9,0.2,1)] motion-reduce:transition-none";
/* The color-bar rail: pink, cyan, yellow, then the violet overprint (the cyan plate at 70% over pink). */
function ColorBar() {
return (
<Separator
aria-hidden
className="isolate flex h-2.5 w-[88px] overflow-hidden rounded-full bg-transparent shadow-[0_2px_0_rgba(27,26,23,0.10)] data-horizontal:h-2.5 data-horizontal:w-[88px] data-[orientation=horizontal]:h-2.5 data-[orientation=horizontal]:w-[88px]"
>
<span className="flex-1 bg-[#FF2E88]" />
<span className="flex-1 bg-[#12B5C9]" />
<span className="flex-1 bg-[#FFC300]" />
<span className="relative flex-1 bg-[#FF2E88]">
<span className="absolute inset-0 bg-[#12B5C9] opacity-70 mix-blend-multiply" />
</span>
</Separator>
);
}
/* The registration crosshair, the printer's own mark. */
function Crosshair() {
return (
<svg aria-hidden viewBox="0 0 18 18" className="size-[18px] shrink-0 text-[#7C7566]">
<circle cx="9" cy="9" r="5" fill="none" stroke="currentColor" strokeWidth="1.5" />
<path d="M9 0v18M0 9h18" stroke="currentColor" strokeWidth="1.5" />
</svg>
);
}
/* The mono color-bar caption that heads every card. */
function Caption({ children }: { children: ReactNode }) {
return (
<div className="flex flex-wrap items-center gap-2">
<ColorBar />
<Crosshair />
<span className="font-mono text-[12.8px] font-bold uppercase tracking-[0.14em] text-[#1B1A17]">{children}</span>
</div>
);
}
/* The misregister knockout: ink type over a cyan and a pink ghost that snap into register on hover.
The ghosts are aria-hidden copies, so the headline is read once. */
function Misregister({ children }: { children: ReactNode }) {
const ghost =
"pointer-events-none absolute inset-0 -z-10 mix-blend-multiply transition-transform group-hover:translate-x-0 group-hover:translate-y-0 " +
press;
return (
<span className="group relative isolate inline-block">
<span aria-hidden className={`${ghost} translate-x-[-4px] translate-y-[3px] text-[#12B5C9]`}>{children}</span>
<span aria-hidden className={`${ghost} translate-x-[4px] translate-y-[-2px] text-[#FF2E88]`}>{children}</span>
{children}
</span>
);
}
/* Which plates the print uses. The pink disc clips the cyan plate at 70%, so pink and cyan
overprint violet; yellow multiplies over cyan into green. */
function Plates() {
return (
<span role="img" aria-label="Plates: pink, cyan, yellow" className="isolate flex">
<span className="relative z-10 size-4 overflow-hidden rounded-full bg-[#FF2E88]">
<span className="absolute top-0 left-2 size-4 rounded-full bg-[#12B5C9] opacity-70 mix-blend-multiply" />
</span>
<span className="-ml-2 size-4 rounded-full bg-[#12B5C9]" />
<span className="-ml-2 size-4 rounded-full bg-[#FFC300] mix-blend-multiply" />
</span>
);
}
export function RamenBowlOnPress() {
return (
<Card className="max-w-[640px] gap-0 rounded-[24px] border-0 bg-card py-0 text-[17px] ring-0 shadow-[0_20px_48px_-20px_rgba(27,26,23,0.34)]">
<CardHeader className="gap-4 px-6 pt-10 pb-4">
<Caption>Press A · edition of 150 · plates P·C·Y</Caption>
<CardTitle className="font-display text-[48.8px] font-normal leading-[1.05] tracking-[-0.02em]">
<Misregister>Ramen Bowl</Misregister>
</CardTitle>
<CardDescription className="text-[17px] leading-[1.55] text-[#1B1A17]">
Yellow carries the broth, pink the fish cake; where cyan crosses yellow the scallions come up green.
</CardDescription>
</CardHeader>
<CardContent className="flex flex-wrap items-center gap-4 px-6 pb-6">
<Plates />
<Badge variant="secondary" className="h-8 gap-2 rounded-full border-0 bg-[#F7F1E4] px-4 font-mono text-[12.8px] font-bold uppercase tracking-[0.14em] text-[#1B1A17]">
<span className="size-2 rounded-full bg-[#12B5C9]" aria-hidden />
On press
</Badge>
<span className="font-mono text-[17px] tabular-nums text-[#1B1A17]">96 of 150 pulled</span>
<TooltipProvider>
<Tooltip>
<TooltipTrigger className="font-mono text-[17px] tabular-nums text-[#1B1A17]">drift 4.0 mm</TooltipTrigger>
<TooltipContent className="max-w-none rounded-full px-4 py-2 font-mono text-[12.8px] font-bold tracking-[0.14em] shadow-none motion-reduce:animate-none">
BAND IS UNDER 5 MM · 1.0 TO SPARE
</TooltipContent>
</Tooltip>
</TooltipProvider>
</CardContent>
<CardFooter className="flex-wrap gap-4 border-0 bg-transparent px-6 pt-4 pb-6">
<Button
size="lg"
className={`h-14 rounded-full border-0 px-10 font-mono text-[20px] font-bold uppercase tracking-[0.06em] shadow-[3px_3px_0_0_#12B5C9] transition-[box-shadow] hover:bg-primary [a]:hover:bg-primary hover:shadow-[0_0_0_0_#12B5C9] focus-visible:ring-[3px] focus-visible:ring-[#1B1A17] ${press}`}
>
Pull the last 54
</Button>
<Button
variant="secondary"
className={`h-12 rounded-full border-0 px-6 font-mono text-[12.8px] font-bold uppercase tracking-[0.14em] shadow-[3px_3px_0_0_#FF2E88] transition-[box-shadow] hover:bg-secondary hover:shadow-[0_0_0_0_#FF2E88] focus-visible:ring-[3px] focus-visible:ring-[#FF2E88] ${press}`}
>
Open the run
</Button>
</CardFooter>
</Card>
);
}
```
preview shotsStored, not verified
{
"artifact": "katagami:shadcn-preview-shots",
"version": "preview-shots-v1",
"schema": "katagami:shadcn-preview-shots/renderable-v1",
"renderable": true,
"author": "katagami-agent",
"generatedBy": "katagami-agent",
"requiresVisualProfile": true,
"language": {
"id": "en-019f3dcc-3bba-7572-b659-834730fc3cb0",
"name": "Impression",
"slug": "impression"
},
"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": [
"Nothing is outlined: separation comes from the misregister ghost, the color-bar rail and warm-paper gutters, and the only ink line is the inset plate edge on a field.",
"Three fluorescent spot inks on warm newsprint: pink (accent #FF2E88) for the one primary pull and the on state, cyan (accent_2 #12B5C9) for the secondary plate and the ghost, yellow (accent_soft #FFC300) as the highlighter. Violet and green are never set; they bloom where two inks overprint.",
"Every card, dialog, sheet and menu opens with a mono color-bar caption: swatch strip, registration crosshair, Space Mono 700 label in ink.",
"Controls press into the paper: at rest the ghost plate sits 3px right and 3px down, on hover it snaps into register in 180ms.",
"Cream on pink measures 3.44:1, so pink plates carry cream only on 20px bold labels and display type; smaller labels on pink are ink (4.97:1)."
],
"visualProfile": {
"family": "editorial",
"material": "paper",
"contour": "default",
"border": "none",
"underlay": false,
"grain": true,
"stickerBadges": false,
"motion": "still",
"density": "balanced",
"accents": [
"fluorescent pink #FF2E88",
"cyan #12B5C9",
"yellow #FFC300"
],
"radii": {
"card": "24px",
"control": "9999px",
"chip": "9999px"
}
},
"shots": [
{
"id": "application-shell",
"title": "Press floor",
"viewport": "desktop",
"primitives": [
"button",
"card",
"tabs",
"badge",
"separator",
"table",
"tooltip",
"dropdown-menu"
],
"composition": "The studio's press floor on the bare newsprint ground: a huge Archivo Black headline in the misregister knockout, a color-bar rail under it, then the feature-plus-proof rhythm (a 24px feature card for the run on press A beside a proof column of three 16px cards carrying the day's figures), and the run table below as paper strips separated by gutters. One pink pull at the top right.",
"mustShow": [
"misregister knockout on the headline: cyan and pink ghosts printing through each other, deep indigo where they cross",
"a color-bar caption and registration crosshair heading every card",
"one pink pull with its cyan ghost, beside a cyan plate secondary",
"status chips with semantic dots and ink labels",
"table rows as surface strips on the paper, no rules"
],
"avoid": [
"ink outlines or grey keylines on cards, rows or fields",
"halftone-dot or burst-ray wallpaper",
"a second pink button or small cream text on pink",
"a coloured bar down any card edge"
],
"scene": {
"eyebrow": "Press floor · Thursday",
"headline": "Two presses running",
"description": "Ramen Bowl is on press A and Lantern Cart on press B. Night Market came off this morning and is drying on the rack; Skyline's proof drifted past the band and waits for a re-pull.",
"primaryAction": "Start a run",
"secondaryAction": "Export the log",
"stats": [
{
"label": "sheets pulled today",
"value": "234",
"detail": "96 + 18 + 120",
"tone": "default"
},
{
"label": "sheets still to pull",
"value": "140",
"detail": "54 + 26 + 60",
"tone": "default"
},
{
"label": "runs out of band",
"value": "1 of 4",
"detail": "Skyline, 5.2 mm",
"tone": "default"
}
],
"rows": [
{
"label": "Ramen Bowl · P·C·Y",
"value": "press A · 96 of 150 · drift 4.0 mm",
"status": "On press"
},
{
"label": "Lantern Cart · P·C",
"value": "press B · 18 of 44 · drift 2.6 mm",
"status": "On press"
},
{
"label": "Night Market · P·C·Y",
"value": "rack · 120 of 120 · drift 3.4 mm",
"status": "Drying"
},
{
"label": "Skyline · P·C·Y",
"value": "held · 0 of 60 · proof drift 5.2 mm",
"status": "Re-pull"
}
],
"statuses": [
"On press",
"Drying",
"Re-pull",
"Cured"
]
}
},
{
"id": "detail-editor",
"title": "Set up an edition",
"viewport": "tablet",
"primitives": [
"button",
"card",
"input",
"textarea",
"select",
"checkbox",
"switch",
"slider",
"dialog",
"sheet",
"tooltip",
"separator"
],
"composition": "One 24px feature card on the newsprint ground, full width in the tablet band, sets up the next edition: a color-bar caption, the title in the knockout, plate-edge fields in two columns, the note to the printer, and the misregister offset slider with its 0 to 5 mm band. Sending it opens the proof approval dialog; the plate list opens in a side sheet.",
"mustShow": [
"a 2px inset ink plate edge on every field, re-inked pink at 3px on the focused one",
"the slider's pink thumb with its cyan ghost and a mono read-out of 3.0 mm",
"a square checkbox filled with the cyan plate and an ink tick",
"the switch as a paper recess when off and a pink plate when on",
"the approval dialog headed by a color-bar caption with the pull as its one primary"
],
"avoid": [
"browser-default controls or boxed borders around fields",
"grey captions or error text in red on paper",
"cards nested in cards",
"labels hidden inside placeholders"
],
"scene": {
"eyebrow": "New edition · proof 3",
"headline": "Rooftops at dusk",
"description": "Two plates, cyan over pink, so the roofs bloom violet where they cross. Sixty prints and four artist proofs on warm newsprint.",
"primaryAction": "Send to press",
"secondaryAction": "Pull another proof",
"fields": [
{
"label": "Edition title",
"value": "Rooftops at dusk",
"type": "text"
},
{
"label": "Ink plates",
"value": "Cyan at 70% over pink, violet where they cross",
"type": "select"
},
{
"label": "Sheets to pull",
"value": "64 = 60 prints + 4 artist proofs",
"type": "text"
},
{
"label": "Stock",
"value": "Warm newsprint, 90 gsm",
"type": "select"
},
{
"label": "Note to the printer",
"value": "Pull cyan 3 mm right of pink along the roofline. Leave the sky as bare paper.",
"type": "textarea"
},
{
"label": "Misregister offset",
"value": "3.0 mm of a 0 to 5 mm band",
"type": "slider"
},
{
"label": "Signed and numbered on press",
"value": "On",
"type": "checkbox"
},
{
"label": "Deckle edge",
"value": "Off",
"type": "switch"
}
],
"statuses": [
"Proof 3 approved",
"Plates burned",
"Queued for press B"
]
}
},
{
"id": "data-operations",
"title": "Edition shelf",
"viewport": "mobile",
"primitives": [
"button",
"tabs",
"badge",
"table",
"dropdown-menu",
"tooltip",
"separator",
"card"
],
"composition": "A phone-width shelf of released editions on the newsprint ground: the knockout on the headline only, a short swatch row for the rail, ink-set tabs with the active one on a pink plate, then one paper strip per edition with overlapping swatch chips for its plates, sold and left counts in Space Mono, a status chip and a row menu. The run column hides at this width rather than squeeze.",
"mustShow": [
"the active tab as a pink plate with an ink label",
"overlapping swatch chips blooming violet and green where the discs cross",
"status chips with semantic dots, labels in ink",
"a row menu with the yellow highlight and an ink-labelled removal marked by an error dot",
"a tooltip on the one low count"
],
"avoid": [
"the page scrolling sideways (the table scrolls inside itself)",
"gridlines, zebra stripes or row outlines",
"red text on paper",
"the misregister on body text at phone width"
],
"scene": {
"eyebrow": "Shelf · 4 editions",
"headline": "134 prints left on the shelf",
"description": "Every released edition with what has sold or been reserved: 256 of 390. Night Market is nearly gone; Ramen Bowl is still on press and already taking reservations.",
"primaryAction": "List an edition",
"secondaryAction": "Export stock",
"stats": [
{
"label": "sold or reserved",
"value": "256",
"detail": "112 + 80 + 23 + 41",
"tone": "default"
},
{
"label": "left to sell",
"value": "134",
"detail": "8 + 0 + 17 + 109",
"tone": "default"
},
{
"label": "sold out",
"value": "1 edition",
"detail": "Water Tower",
"tone": "default"
}
],
"rows": [
{
"label": "Night Market · ed. 120",
"value": "112 sold · 8 left",
"status": "Low"
},
{
"label": "Water Tower · ed. 80",
"value": "80 sold · 0 left",
"status": "Sold out"
},
{
"label": "Teapot · ed. 40",
"value": "23 sold · 17 left",
"status": "On shelf"
},
{
"label": "Ramen Bowl · ed. 150",
"value": "41 reserved · 109 left",
"status": "Reserving"
}
],
"statuses": [
"On shelf",
"Low",
"Sold out",
"Reserving"
]
}
}
],
"componentRecipes": [
{
"primitive": "button",
"intent": "The pull: one per view, h-14 pill on pink (accent #FF2E88) with a cream 20px Space Mono 700 uppercase label (3.44:1, large bold text) and a cyan ghost shadow-[3px_3px_0_0_#12B5C9] that snaps to 0 on hover in 180ms. The cyan plate (secondary): cyan with an ink 12.8px label (7.03:1) and a pink ghost. The paper button (outline): surface on the sm print shadow, yellow plate on hover. Destructive is an error fill with an ink label, never variant=\"destructive\"."
},
{
"primitive": "card",
"intent": "Feature card rounded-[24px] on the lg print shadow, proof card rounded-[16px] on the md print shadow; border-0 and ring-0, no outline; the footer's stock band goes with border-0 bg-transparent. Header opens pt-10 with the color-bar caption, then an Archivo Black font-normal title in the misregister knockout; description 17px in ink. Cards never nest."
},
{
"primitive": "input",
"intent": "Surface stock with a 2px inset ink plate edge (shadow-[inset_0_0_0_2px_#1B1A17]), rounded-[16px], h-12, 17px text kept at md:text-[17px]. Focus re-inks the edge pink at 3px; invalid re-inks it error at 3px with an ink message led by an error dot. Placeholder in muted #7C7566 (4.49:1), never carrying information; label above as a mono caption."
},
{
"primitive": "textarea",
"intent": "The note to the printer: the Input plate-edge chassis at min-h-32, 17px Space Grotesk at 1.55 line height, resize-y, the same error edge as Input, with a mono character count in ink beneath."
},
{
"primitive": "select",
"intent": "Trigger on the Input chassis, its height set as data-[size=default]:h-12 so it beats the installed prefix, placeholder in muted, pink edge while open (data-[state=open] and data-popup-open). Content is a rounded-[16px] proof sheet on the md print shadow; items are rounded-full at 17px and highlight on the yellow plate from --accent with ink on it (10.82:1)."
},
{
"primitive": "dialog",
"intent": "The proof approval: rounded-[24px] surface on the lg print shadow, p-10, opened by a color-bar caption (PROOF 3 OF 3 · PLATES C+P), title in the knockout, body in ink. ring-0 drops the stock frame; the footer drops its stock band (mx-0 mb-0 border-0 bg-transparent p-0) and holds the one pull and a paper button. The scrim is the ink at 40%, no blur."
},
{
"primitive": "sheet",
"intent": "Run detail from the right edge: rounded-l-[24px] surface on the lg print shadow, width, border and shadow repeated under data-[side=right]:, 180ms in and out, the color-bar rail across the header's top (never down the side), label and value pairs in Space Mono 17px, and the run's one pull in the footer."
},
{
"primitive": "tabs",
"intent": "Ink-set filters as mono 12.8px uppercase labels on the bare paper; the active tab is a pink plate pill with an ink label (4.97:1) and no shadow, set under both data-active and data-[state=active] (and the list height under group-data-horizontal/tabs:); hover lays the yellow plate on inactive tabs only (not-data-active:hover:), and the focus ring is ink. Never the line variant."
},
{
"primitive": "badge",
"intent": "Pill chips in Space Mono 700 12.8px uppercase at 0.14em (Label-Mono). Spot-ink chips are pink, cyan or yellow with ink labels. Status chips are paper with an 8px semantic dot (success Cured, warning Drying, info On press, error Re-pull) and an ink label. Overlapping swatch chips are pink, cyan and yellow discs: the pink disc clips the cyan plate at 70% with mix-blend-multiply so the pink-cyan lens is violet, and yellow multiplies over cyan into green."
},
{
"primitive": "separator",
"intent": "The color-bar rail instead of a hairline, marked aria-hidden as ornament (not the Radix-only decorative prop): a 10px rounded-full strip of pink, cyan, yellow and the violet overprint swatch (the cyan plate at 70% over pink) on the sm print shadow, sized under data-horizontal and data-[orientation=horizontal] so it beats the installed h-px. Inside a card, a 16px paper gutter separates instead."
},
{
"primitive": "checkbox",
"intent": "A 24px square swatch (rounded-none, replacing the installed 4px or 6px corner) of surface with the inset ink plate edge; checked fills with the cyan plate and an ink tick (7.03:1) while the ink edge stays, since cyan alone is 2.43:1 on surface."
},
{
"primitive": "switch",
"intent": "h-8 w-14 track, sized under data-[size=default]: as well so the registry builds' own size does not win: off is the paper recess (bg #F7F1E4) with the inset ink plate edge, on is the pink plate (3.11:1 on the ground). The thumb is a 24px surface disc on the sm print shadow that slides 180ms on translate-x only, with every state set under both data-[state=checked] and data-checked."
},
{
"primitive": "slider",
"intent": "The misregister offset control: a 10px paper-recess rail with the inset ink plate edge, pink range, a 28px pink thumb with its cyan ghost that snaps into register on hover, a Space Mono read-out (3.0 mm) and the 0 to 5 mm band captioned beneath."
},
{
"primitive": "tooltip",
"intent": "A rounded-full ink pill (bg #F7F1E4 type on #1B1A17, 15.46:1) in Space Mono 700 12.8px at 0.14em carrying a figure, not a sentence: DRIFT 5.2 MM · 0.2 PAST THE BAND. The fade stops under reduced motion."
},
{
"primitive": "dropdown-menu",
"intent": "Row actions on a rounded-[16px] proof sheet on the md print shadow, headed by a mono caption with a short rail; items rounded-full at 17px, highlighted on the yellow plate set as focus:bg-[#FFC300] focus:text-[#1B1A17] (the installed item highlights with focus:bg-muted); menu separators are 8px paper gutters. The removal item carries an error dot and an ink label, never variant=\"destructive\"."
},
{
"primitive": "table",
"intent": "The press log on the bare newsprint ground: border-separate with 8px of paper between rows, each row a surface strip that stays surface on hover and while its menu is open, with 16px rounded ends and the sm print shadow on its cells; mono uppercase heads in ink, figures in Space Mono tabular-nums, plates as overlapping swatch chips, a status chip per row, secondary columns hidden on a phone."
}
],
"qualityRules": {
"do": [
"Separate with the misregister ghost, the color-bar rail and warm-paper gutters; the inset plate edge on fields is the only ink line.",
"Spend pink on one pull per view and the on state; let cyan be the second plate and yellow the highlighter.",
"Caption every card, dialog, sheet and menu with the rail, the registration crosshair and a mono label in ink.",
"Make violet only by printing the cyan plate at 70% over pink, and green by multiplying yellow over cyan; never set either as a colour.",
"Keep cream on pink to 20px bold labels and display type, and set every smaller label on a pink plate in ink."
],
"dont": [
"Outline cards, rows, menus or buttons in ink or grey, or add hard black offset shadows.",
"Wallpaper any ground with halftone dots or burst rays.",
"Mute the inks into pastels or tints the tokens do not have.",
"Set semantic colours or muted as small text on paper.",
"Leave a browser-default control or a shadcn default radius on screen."
]
}
}
Try a remix
Keep Impression and swap a palette and an art style onto it. The landing & dashboard recolor live.