Approva
Remix this template to create a similar design — same sections, layout, animations, colors, and typography.
A dashboard for finance approval workflows. Mint-green canvas, brutalist black borders with green, amber and red accents, Archivo and Hanken Grotesk.
Palette
Typography
30px
14px
12px
10px
24px
Spacing & Shape
| Token | Value | Preview |
|---|---|---|
| xs | 4px | |
| sm | 8px | |
| md | 16px | |
| lg | 20px | |
| xl | 24px | |
| xxl | 28px |
Border Radius
| Token | Value | Preview |
|---|---|---|
| none | 0px | |
| sm | 4px | |
| full | 999px |
design.md
tokens (raw)
name: approva-design
version: alpha
description: >
Approva ("Stamply") is a neo-brutalist approval-ledger dashboard on a soft mint
surface (#CFE8D6) with near-black ink (#121210). Every surface is outlined in
thick 2-3px black borders with hard offset drop shadows (4px 4px 0) that deepen
on hover and collapse on press — the signature "stamp" tactility. Three saturated
voltages carry status: green #2E8C42 (approve/pass), red #C03A3A (reject/escalate),
and amber #E8A030 (pending/needs-detail). Type is a three-face system: Archivo for
bold display, Hanken Grotesk for body, and Space Mono for tabular numerics and
metadata. Decorative motifs include grid-paper, polka dots, diagonal amber stripes,
rubber-stamp badges, and a spring-loaded big-stamp drop animation.
colors:
# Brand / Voltage
approve: '#2E8C42' # green — approve, pass, submitter, positive chain nodes
reject: '#C03A3A' # red — reject, escalation, past-SLA, error nodes
pending: '#E8A030' # amber — pending, needs-detail, SLA warning, logo tile
# Surface
surface: '#CFE8D6' # page mint background, sidebar, headers, tabs
card: '#FFFFFF' # white card/panel fill
ink: '#121210' # near-black — borders, text, audit-log fill, active tab
# Text
text: '#121210' # primary heading + body
on-ink: '#FFFFFF' # text on black/colored fills
# Hairlines
border: '#121210' # all structural borders (2-3px solid)
hairline: 'rgba(18,18,16,0.20)' # faint table row dividers (#121210/20)
# Decorative
grid: 'rgba(18,18,16,0.08)' # grid-paper lines
grid-faint: 'rgba(18,18,16,0.05)'# detail-pane grid background
stripe-light: '#F4D89A' # amber stripe (light band)
stripe-dark: '#E8A030' # amber stripe (dark band)
typography:
display:
fontFamily: "'Archivo', sans-serif"
fontSize: 30px
fontWeight: 700
letterSpacing: -0.01em
body:
fontFamily: "'Hanken Grotesk', sans-serif"
fontSize: 14px
fontWeight: 400
mono:
fontFamily: "'Space Mono', monospace"
fontSize: 12px
fontWeight: 400
metaLabel:
fontFamily: "'Space Mono', monospace"
fontSize: 10px
fontWeight: 400
letterSpacing: 0.1em
textTransform: uppercase
amount:
fontFamily: "'Space Mono', monospace"
fontSize: 24px
fontWeight: 700
rounded: # mostly sharp; only stamp/chain-node round
none: 0px
sm: 4px # stamp badges
full: 999px # chain nodes, pill avatars
spacing: # 4px base unit
xs: 4px
sm: 8px
md: 16px
lg: 20px
xl: 24px
xxl: 28px
components:
brutCard:
backgroundColor: '{colors.card}'
border: '3px solid {colors.ink}'
boxShadow: '4px 4px 0 {colors.ink}'
rounded: '{rounded.none}'
padding: '16px'
hover: 'translate(-2px,-2px); shadow 8px 8px 0'
navItem:
backgroundColor: '{colors.card}'
border: '3px solid {colors.ink}'
boxShadow: '4px 4px 0 {colors.ink}'
typography: '{typography.display}'
padding: '12px'
hover: 'translate(-1px,-1px); shadow 5px 5px 0'
primaryButton:
backgroundColor: '{colors.ink}'
textColor: '{colors.on-ink}'
typography: '{typography.display}'
border: '3px solid {colors.ink}'
boxShadow: '4px 4px 0 {colors.ink}'
pressed: 'translate(4px,4px); shadow none'
stampButton:
backgroundColor: '{colors.approve}' # approve green; reject red; detail amber
textColor: '{colors.on-ink}'
typography: '{typography.display}'
border: '3px solid {colors.ink}'
boxShadow: '4px 4px 0 {colors.ink}'
padding: '18px 14px'
letterSpacing: '0.1em'
tag:
backgroundColor: '{colors.card}'
border: '2px solid {colors.ink}'
typography: '{typography.metaLabel}'
fontSize: '11px'
padding: '4px 10px'
textTransform: uppercase
stamp:
textColor: '{colors.approve}' # rubber-stamp; color = status voltage
typography: '{typography.display}'
border: '4px solid currentColor'
rounded: '{rounded.sm}'
padding: '10px 22px'
letterSpacing: '0.15em'
chainNode:
backgroundColor: '{colors.approve}' # status-colored circular node
border: '2px solid {colors.ink}'
rounded: '{rounded.full}'
size: '28px'
auditLog:
backgroundColor: '{colors.ink}'
textColor: '{colors.on-ink}'
typography: '{typography.mono}'
border: '3px solid {colors.ink}'
boxShadow: '4px 4px 0 {colors.ink}'
motion:
cardEntrance: 'GSAP: .req-card fade + y:24 → 0, 0.5s power3.out, stagger 0.06'
invoiceEntrance: 'GSAP: #invoice fade + y:20 → 0, 0.6s power3.out, delay 0.15'
stampButtonEntrance: 'GSAP: .stamp-btn fade + x:30 → 0, 0.5s power3.out, stagger 0.08, delay 0.3'
stampDrop: 'anime.js: big-stamp scale 3→1, rotate -15→-6, opacity 0→0.88, 600ms, spring(stiffness 90, damping 8, mass 1.4)'
invoiceShake: 'anime.js: #invoice x:[0,-8,6,-4,2,0], 600ms, outElastic(1,0.5) on stamp'
cardPress: 'CSS :active translate(4px,4px), shadow collapses to 0'
icons:
library: Tabler Icons (webfont, ti)
style: outline
sizes: { xs: 12px, sm: 16px, md: 20px, lg: 24px, xl: 30px }
color: '{colors.ink}'Approva
approva-design · alpha
Design spec — version alpha. Source: static HTML (
index.html); tokens read from inline styles + class rules. Fictional/sample product; described factually.
Overview
Approva (branded "STAMPLY · v2.4 · LEDGER") is a neo-brutalist approval-workflow
dashboard for finance teams. The whole interface sits on a soft mint surface
(#CFE8D6) inked in near-black (#121210), and its signature move is the
rubber-stamp: every panel is a brut card — a thick black border with a hard,
shadowless offset drop shadow (4px 4px 0 #121210) that lifts to 8px 8px 0 on
hover and slams flat (translate(4px,4px), shadow 0) on :active. Status is
carried by three saturated voltages — green #2E8C42 for approve/pass, red
#C03A3A for reject/escalation/past-SLA, amber #E8A030 for pending and
needs-detail. The layout is a fixed 260px sidebar, a top bar + tab strip, and a
split list/detail workspace; the detail pane renders an actual purchase-order
document with a line-item table, a horizontal approval chain, and three giant
"stamp buttons" that physically slam an angled big-stamp watermark onto the
invoice via a spring animation. Type triangulates Archivo (bold display), Hanken
Grotesk (body), and Space Mono (every number, ID, and timestamp). Decorative
texture comes from grid-paper, polka dots, and diagonal amber warning stripes.
Colors
Brand / Voltage. Three status colors do all the semantic work: approve
#2E8C42 (green) on the APPROVE stamp button, "PASS" policy checks, the
submitter chain node, completed approval-chain cards, and PUBLISH; reject
#C03A3A (red) on the REJECT button, escalation tags, past-SLA badges, error
chain nodes, and the alert-triangle; pending #E8A030 (amber) on NEEDS DETAIL,
the logo tile, pending chain nodes ("M"), SLA-risk warnings, and the
Escalations nav.
Surface. surface #CFE8D6 is the page background and fills the sidebar,
header, tab strip, list column, and table heads. card #FFFFFF is the white
fill for cards, nav items, the invoice, and inputs. ink #121210 fills the
active tab, the primary + NEW REQUEST button, count badges, and the audit-log
panel.
Text. text/ink #121210 is all headings and body. on-ink #FFFFFF
is text on black and on colored voltage fills.
Hairlines. border #121210 draws every structural border at 2-3px solid.
hairline rgba(18,18,16,0.20) (#121210/20) and /30 are faint inner table
row dividers.
Decorative. grid rgba(18,18,16,0.08) is the grid-paper line color;
grid-faint rgba(18,18,16,0.05) tiles the detail pane. polka dots are solid
#121210. The amber warning stripes alternate stripe-light #F4D89A and
stripe-dark #E8A030 at a 45deg repeat.
Typography
Three Google Fonts loaded via @import: Archivo (500-900) for display,
Hanken Grotesk (400-700) for body, Space Mono (400/700) for mono. Body
defaults to Hanken Grotesk. .font-display adds letter-spacing:-0.01em;
.font-mono enables tabular-nums. All three are open-source Google Fonts, so
no substitution is needed.
| Token | Size | Weight | Tracking | Usage |
|---|---|---|---|---|
| display | 30px (text-3xl) | 700 | -0.01em | Page title, panel headings, invoice title |
| display-lg | 18-20px | 600-700 | -0.01em | Card vendor names, nav labels, logo |
| body | 14px | 400 | 0 | Descriptions, secondary text |
| mono | 12px | 400/700 | 0 | Numbers, audit log, table cells, ⌘K |
| amount | 24px (text-2xl) | 700 | 0 | Card $ amounts (Space Mono) |
| metaLabel | 10px | 400 | 0.1em+ | Uppercase mono labels (VENDOR, TODAY) |
Layout
4px base unit (Tailwind scale); panel padding clusters at 16/20/24px. The page is
a full-height flex: a fixed w-[260px] sidebar (mint, 3px right border) holding
the brand, workspace nav, a stamped-today progress card, and the current user;
then a flex-1 main column with a header (title + tags + search + new-request),
a tab strip (active tab is black, joined tabs share borders via -mb-[3px]),
and a split body — a w-[44%] scrollable request list and a flex-1 detail pane.
The detail pane is grid-paper textured and stacks: the invoice document (white
brut-lg with a stamp drop-target), a 3-column stamp-button rail (sticky), an
audit-log terminal, a recently-stamped table, a workflow-builder node graph
(polka background), and an escalation queue framed in amber stripes. Whitespace
is tight and structural — borders, not gaps, define regions.
Elevation & Depth
No soft shadows or blur anywhere — depth is entirely hard offset shadows on top
of thick borders. The system: brut = 3px border + 4px 4px 0 #121210;
brut-lg = 3px + 6px 6px 0; brut-sm = 2px + 3px 3px 0. Hover on
brut-card lifts to translate(-2px,-2px) with 8px 8px 0; nav-item hover
goes translate(-1px,-1px) with 5px 5px 0. The btn-press/stamp-btn
:active state collapses the shadow to 0 0 0 and pushes translate(4px,4px) —
the "stamp pressed down" feel.
Shapes
Overwhelmingly sharp — border-radius: 0 is the default for cards, buttons, tags,
inputs, and tables. The only rounding: stamp badges at 4px (rounded.sm,
with nested 2px inner frames), the big-stamp watermark at 6px, and fully
round (999px) chain nodes and circular avatar/logo pills (avatars are actually
square 2px-bordered thumbnails).
Components
- brut card — white fill, 3px
#121210border,4px 4px 0shadow, 0 radius, 16px padding; hover lifts and deepens shadow. Base for request cards and panels. - nav item — white (or amber for Escalations)
brut, Archivo semibold, icon + label + count badge; hover nudges with5px 5px 0. - primary button — black fill, white Archivo semibold,
brut, label+ NEW REQUEST; press collapses shadow. - stamp button — large square
brutin voltage color (green APPROVE / red REJECT / amber NEEDS DETAIL), big Tabler icon + label + shortcut, 18×14px pad. - tag — 2px-bordered inline pill, 11px uppercase Space Mono semibold,
4×10px pad; fill varies (white, mint, voltage). Labels:
CAPEX,3 PAST SLA. - stamp — rubber-stamp badge, 4px currentColor border, 4px radius, nested
dashed inner frames, slightly rotated; color = status. Labels
APPROVEDetc. - chain node — 28px round, 2px border, status fill, single-char content
(
✓M!·) joined by 18×3px blackchain-linesegments. - audit log — black panel, white tabular Space Mono
<pre>,IMMUTABLE · SHA-256 CHAINEDcaption, blinking-cursor last line. - invoice — white
brut-lgdocument: PO header, 3-col meta, mono line-item table with 3px header/footer rules, horizontal approval-chain cards.
Motion
Entrance via GSAP gsap.from: request cards fade up (y:24, 0.5s power3.out,
0.06 stagger), the invoice fades up (0.6s, delay 0.15), stamp buttons slide in
from the right (x:30, stagger 0.08, delay 0.3). The hallmark is the stamp drop
on anime.js v4: clicking APPROVE/REJECT/NEEDS DETAIL injects a big-stamp
that springs from scale 3 / rotate -15deg / opacity 0 to scale 1 / rotate -6deg / opacity 0.88 (600ms, spring(stiffness 90, damping 8, mass 1.4)) while the
invoice shakes horizontally (x:[0,-8,6,-4,2,0], outElastic(1,0.5)). CSS
:active press transforms are authored and live for all brut buttons/cards.
Iconography
Tabler Icons via webfont (ti ti-*), outline style, inherited currentColor
(default ink). Sizes range 12px (text-xs inline) to 30px (text-3xl on stamp
buttons). UI icons: ti-stamp, ti-inbox, ti-flame, ti-archive,
ti-git-merge, ti-search, ti-check, ti-x, ti-info-circle,
ti-arrow-narrow-right, ti-alert-triangle, ti-list-details. Flame and
alert-triangle take voltage colors (red/amber) when signalling escalation.
Do's and Don'ts
- Do outline every surface in 2-3px
#121210and pair it with a hard offset shadow (4px 4px 0) — no soft shadows, no blur. - Do keep corners sharp (
radius 0); reserve rounding for stamp badges (4px) and round chain nodes (999px). - Do reserve green/red/amber for status only, and set all numbers, IDs, and timestamps in Space Mono with tabular-nums.
- Do make buttons and cards feel physical — lift on hover, slam flat on press.
- Don't introduce gradients, glass, or mid-tone greys; the palette is mint + ink + three voltages.
- Don't soften the brutalist shadow into a CSS blur, or use display type
without the
-0.01emtracking. - Don't mix icon libraries — stay on Tabler outline.
Known Gaps
- Type sizes come from Tailwind utility classes (
text-3xl=30px,text-2xl=24px,text-xl=20px,text-lg=18px,text-xs=12px); thedisplaytoken uses the dominant page-title 30px. No explicit:rootfont-size scale is defined. letterSpacingon tags/stamps (0.06em/0.15em) and mono labels (0.1em,tracking-widest≈0.1em) are read from class rules;tracking-widestis Tailwind's default ~0.1em.- The big-stamp/invoice-shake values are exact from the script; perceived final appearance depends on anime.js spring resolution.
- avatars use external pravatar placeholders (square, 2px-bordered), not a brand asset.