Brutalist Academic UI
Opinionated design skill for interfaces where intellectual rigor, typographic precision, and structural honesty matter.
Skriptoteket Compatibility (must follow)
- Vue 3 + Vite SPA only. SSR/HTMX is removed; do not re-introduce it.
- Tailwind CSS v4 with
@theme inline token bridge. Prefer utilities in templates over custom CSS.
- Tokens are canonical:
src/skriptoteket/web/static/css/huleedu-design-tokens.css (do not edit directly).
- SPA entry point:
frontend/apps/skriptoteket/src/assets/main.css (import Tailwind + tokens + theme once).
- Use SPA primitives before inventing new ones:
- Buttons:
.btn-primary, .btn-cta, .btn-ghost
- Panels (nested):
.panel-inset, .panel-inset-canvas
- Messages:
.toast-* (via ToastHost), .system-message* (via SystemMessage)
- Badges:
.status-pill
- Page text:
.page-title, .page-description
- No stacked brutal shadows: only the outermost “panel/card” gets
shadow-brutal*. Panels/fields nested inside a
shadowed surface must use shadow-none + thicker, uniform borders (panel-inset*, or border-2 border-navy/20) to
keep the UI calm and readable.
- No Tailwind default palette leakage in product UI: avoid
bg-slate-*, text-gray-*, etc. Use token-mapped utilities
(bg-canvas, text-navy, shadow-brutal-sm) or CSS variables (var(--color-*), var(--huleedu-*)).
- Editor ergonomics: full-height editor routes require
min-h-0 + overflow discipline; follow the Script Editor
layout patterns (route-stage--editor, AuthLayout).
When to Use
Activate when user:
- Builds websites, landing pages, dashboards, documentation sites
- Needs institutional or academic visual language
- Mentions: "brutalist", "academic", "minimal", "serious UI"
- Wants to avoid generic startup aesthetics (gradients, soft shadows, pill-everything)
I Need To...
| Task |
Read |
| Token + Tailwind mapping rules |
.agent/rules/045-huleedu-design-system.md |
| Tailwind v4 token bridge ADR |
docs/adr/adr-0032-tailwind-4-theme-tokens.md |
| Canonical tokens |
src/skriptoteket/web/static/css/huleedu-design-tokens.css |
| SPA token bridge |
frontend/apps/skriptoteket/src/styles/tokens.css + frontend/apps/skriptoteket/src/styles/tailwind-theme.css |
| SPA primitives (buttons, toasts, system messages) |
frontend/apps/skriptoteket/src/assets/main.css |
| Well-aligned editor layout example |
frontend/apps/skriptoteket/src/views/admin/ScriptEditorView.vue |
| Workspace panel (IDE layout) |
frontend/apps/skriptoteket/src/components/editor/EditorWorkspacePanel.vue |
| Grid/typography/color principles |
fundamentals.md |
| Layout patterns |
patterns.md |
| Components |
examples/components.md |
| Tables + ledgers |
examples/tables-ledgers.md |
Quick Reference
Do
- Use token-mapped utilities:
bg-canvas, text-navy, border-navy, shadow-brutal-sm, font-serif.
- Use CSS variables when a token is not mapped:
p-[var(--huleedu-space-4)], text-[var(--huleedu-text-sm)].
- Use the SPA button primitives for actions.
- Prefer opacity-only transitions (hard borders/shadows shimmer when translated).
- Prefer one brutal shadow per major surface (page card / editor workspace / modal). Nested sections get borders, not
shadows.
Avoid
- Tailwind default palette (
bg-slate-*, text-gray-*) in product UI.
- Hardcoded hex colors or ad-hoc shadows.
- Large radii, blur/backdrop filters, or decorative gradients.
- Motion/hover transforms that distort “hard” edges (
translate, scale) unless there’s a strong UX reason.
Font Stack
Use token fonts via Tailwind utilities: font-sans, font-serif, font-mono.
Button Primitives
<button class="btn-primary">Spara</button>
<button class="btn-cta">Publicera</button>
<button class="btn-ghost">Redigera</button>
Utility Buttons (Toolbars / Micro UI)
Use .btn-ghost as a base and override size/shadow for dense controls:
<button
class="btn-ghost shadow-none h-[28px] px-2.5 py-1 text-[10px] font-semibold normal-case tracking-[var(--huleedu-tracking-label)] border-navy/30 bg-canvas leading-none"
>
Formatera
</button>
Core Principle
The best interface is one where you notice the content, not the interface. Every element earns its place. Typography does the work. Whitespace is structure.
1---2name: brutalist-academic-ui3description: Skriptoteket-specific brutalist/academic UI design for the Vue 3 + Vite SPA. Uses Tailwind v4 utilities mapped to HuleEdu tokens and SPA primitives.4---5
6# Brutalist Academic UI
7
8Opinionated design skill for interfaces where intellectual rigor, typographic precision, and structural honesty matter.
9
10## Skriptoteket Compatibility (must follow)
11
12- Vue 3 + Vite SPA only. SSR/HTMX is removed; do not re-introduce it.
13- Tailwind CSS v4 with `@theme inline` token bridge. Prefer utilities in templates over custom CSS.
14- Tokens are canonical: `src/skriptoteket/web/static/css/huleedu-design-tokens.css` (do not edit directly).
15- SPA entry point: `frontend/apps/skriptoteket/src/assets/main.css` (import Tailwind + tokens + theme once).
16- Use SPA primitives before inventing new ones:
17 - Buttons: `.btn-primary`, `.btn-cta`, `.btn-ghost`
18 - Panels (nested): `.panel-inset`, `.panel-inset-canvas`
19 - Messages: `.toast-*` (via `ToastHost`), `.system-message*` (via `SystemMessage`)
20 - Badges: `.status-pill`
21 - Page text: `.page-title`, `.page-description`
22- **No stacked brutal shadows**: only the outermost “panel/card” gets `shadow-brutal*`. Panels/fields nested inside a
23 shadowed surface must use `shadow-none` + thicker, uniform borders (`panel-inset*`, or `border-2 border-navy/20`) to
24 keep the UI calm and readable.
25- No Tailwind default palette leakage in product UI: avoid `bg-slate-*`, `text-gray-*`, etc. Use token-mapped utilities
26 (`bg-canvas`, `text-navy`, `shadow-brutal-sm`) or CSS variables (`var(--color-*)`, `var(--huleedu-*)`).
27- Editor ergonomics: full-height editor routes require `min-h-0` + `overflow` discipline; follow the Script Editor
28 layout patterns (`route-stage--editor`, `AuthLayout`).
29
30## When to Use
31
32Activate when user:
33- Builds websites, landing pages, dashboards, documentation sites
34- Needs institutional or academic visual language
35- Mentions: "brutalist", "academic", "minimal", "serious UI"
36- Wants to avoid generic startup aesthetics (gradients, soft shadows, pill-everything)
37
38## I Need To...
39
40| Task | Read |
41|------|------|
42| Token + Tailwind mapping rules | `.agent/rules/045-huleedu-design-system.md` |
43| Tailwind v4 token bridge ADR | `docs/adr/adr-0032-tailwind-4-theme-tokens.md` |
44| Canonical tokens | `src/skriptoteket/web/static/css/huleedu-design-tokens.css` |
45| SPA token bridge | `frontend/apps/skriptoteket/src/styles/tokens.css` + `frontend/apps/skriptoteket/src/styles/tailwind-theme.css` |
46| SPA primitives (buttons, toasts, system messages) | `frontend/apps/skriptoteket/src/assets/main.css` |
47| Well-aligned editor layout example | `frontend/apps/skriptoteket/src/views/admin/ScriptEditorView.vue` |
48| Workspace panel (IDE layout) | `frontend/apps/skriptoteket/src/components/editor/EditorWorkspacePanel.vue` |
49| Grid/typography/color principles | [fundamentals.md](fundamentals.md) |
50| Layout patterns | [patterns.md](patterns.md) |
51| Components | [examples/components.md](examples/components.md) |
52| Tables + ledgers | [examples/tables-ledgers.md](examples/tables-ledgers.md) |
53
54## Quick Reference
55
56### Do
57
58- Use token-mapped utilities: `bg-canvas`, `text-navy`, `border-navy`, `shadow-brutal-sm`, `font-serif`.
59- Use CSS variables when a token is not mapped: `p-[var(--huleedu-space-4)]`, `text-[var(--huleedu-text-sm)]`.
60- Use the SPA button primitives for actions.
61- Prefer opacity-only transitions (hard borders/shadows shimmer when translated).
62- Prefer **one** brutal shadow per major surface (page card / editor workspace / modal). Nested sections get borders, not
63 shadows.
64
65### Avoid
66
67- Tailwind default palette (`bg-slate-*`, `text-gray-*`) in product UI.
68- Hardcoded hex colors or ad-hoc shadows.
69- Large radii, blur/backdrop filters, or decorative gradients.
70- Motion/hover transforms that distort “hard” edges (`translate`, `scale`) unless there’s a strong UX reason.
71
72### Font Stack
73
74Use token fonts via Tailwind utilities: `font-sans`, `font-serif`, `font-mono`.
75
76### Button Primitives
77
78```html
79<button class="btn-primary">Spara</button>
80<button class="btn-cta">Publicera</button>
81<button class="btn-ghost">Redigera</button>
82```
83
84### Utility Buttons (Toolbars / Micro UI)
85
86Use `.btn-ghost` as a base and override size/shadow for dense controls:
87
88```html
89<button
90 class="btn-ghost shadow-none h-[28px] px-2.5 py-1 text-[10px] font-semibold normal-case tracking-[var(--huleedu-tracking-label)] border-navy/30 bg-canvas leading-none"
91>
92 Formatera
93</button>
94```
95
96## Core Principle
97
98The best interface is one where you notice the content, not the interface. Every element earns its place. Typography does the work. Whitespace is structure.