MB-Minimalistic art direction — calm editorial minimalism, near-monochrome OKLCH palette, Manrope + IBM Plex Mono, tight radii, zero shadows, 1px rule separation. Use when building or redesigning any interface in this style (storefront, landing page, dashboard, portfolio, docs, app). On an empty repo it asks what to build and proposes directions; on an existing codebase it audits the current stack first, then migrates in reversible waves.
Scanned 9/6/2026
Install to Claude Code
npx -y skills add MoeBamba01/MB-Minimalistic --skill mb-minimalistic --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Mb Minimalistic?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/moebamba01-mb-minimalistic)More formats (shields.io, HTML) on the badges page.
---
name: mb-minimalistic
description: MB-Minimalistic art direction — calm editorial minimalism, near-monochrome OKLCH palette, Manrope + IBM Plex Mono, tight radii, zero shadows, 1px rule separation. Use when building or redesigning any interface in this style (storefront, landing page, dashboard, portfolio, docs, app). On an empty repo it asks what to build and proposes directions; on an existing codebase it audits the current stack first, then migrates in reversible waves.
---
# MB-Minimalistic — calm editorial minimalism
A complete art direction extracted from a production skincare storefront (Next.js 16 + Tailwind v4 + base-ui), generalized to any product surface.
One principle: **the page is a document, not a shop window.** Anything that draws the eye without carrying information is removed. Contrast comes from typography and whitespace — never from color or elevation.
---
## STEP 0 — Always start here
**First, decide which of two paths you are on.** Do not ask anything before this — it is a filesystem check, not a question:
```bash
ls app pages src components 2>/dev/null | head
cat package.json 2>/dev/null | head -30
```
- **Empty or near-empty repo** → path A, greenfield. Continue below.
- **Existing UI code** (routes, components, a stylesheet with variables) → **path B. Stop and read `references/adoption.md` now.** Path A's first move is pasting `tokens.css`, which in a live project duplicates the Tailwind import and deletes every variable the project owns. Path B audits first, merges tokens, and migrates in waves.
Ambiguous (a fresh `create-next-app` with only boilerplate)? Treat it as path A, but keep the merge rule: never delete a variable you did not introduce.
---
### Path A — greenfield
If the user has **not** already stated precisely what they want to build, ask with `AskUserQuestion` **before writing a single line of code**.
Question 1 — "What do you want to build with MB-Minimalistic?" (header: `Project`)
Pick the 4 most plausible options given the current repo:
| Direction | What it becomes in this DA |
|---|---|
| **Storefront / e-commerce** | Card-less product grid, 4/5 imagery, mono prices, side-sheet cart, single-column checkout with sticky summary |
| **Product or brand landing** | Two-column hero, `border-y` promise band, process section, restrained CTAs |
| **Dashboard / internal app** | 1px rules everywhere, mono numerals, high density (`h-8` default), no floating cards |
| **Portfolio / editorial site** | `max-w-2xl` column, mono eyebrows, declarative headlines, full-bleed imagery |
| **Docs / technical blog** | Quiet table of contents, Plex Mono code, `label-mono` metadata |
| **Mobile app screens** | Same palette, `h-11` touch targets, bottom sheets, no colored tab bar |
Question 2 — "Base hue?" (header: `Hue`)
- **Sage (original)** — hue 145–152, the reference
- **Pure neutral** — chroma 0, paper grey
- **Other hue** — same chroma ceiling (≤ 0.06), any hue (terracotta 40, ink 250, sand 80)
Question 3 — "Type pairing?" (header: `Type`) — see the four sanctioned pairings under [Typography](#typography). Default to **Manrope + IBM Plex Mono** if the user has no opinion; never invent a pairing outside that list.
Question 4 (when relevant) — "Scope?" (header: `Scope`): single page / multi-page flow / isolated components / redesign of an existing surface.
Then propose a concrete 3–5 line section plan for the chosen direction, and build.
**Never skip this step because the request seems obvious.** If the user already specified everything ("build me a coffee roaster landing in MB-Minimalistic, sage"), go straight to building.
---
### Path B — existing project
Full procedure in `references/adoption.md`. The shape of it:
1. **Audit before asking anything.** Detect the Tailwind version, the component base (`base-nova` / Radix shadcn / none), which CSS variables the project already owns, and how fonts are loaded. Count the DA violations.
2. **Report the gap** as a P0/P1/P2 table with real counts, so the size of the job is visible before any code moves.
3. **Then** ask — and the questions are different from path A:
- Question 1 — "Scope?" (header: `Scope`): whole app / one route as a pilot *(recommended)* / just the design tokens / components only
- Question 2 — "Base hue?" — same three options as path A, but default to **keeping their existing hue** if the brand already has one; only the chroma ceiling and the OKLCH conversion are non-negotiable
- Question 3 — "Type pairing?" — offer to keep their current faces if the pairing already satisfies the rules (one sans, one mono, ≤ 500 weight)
- Question 4 — "How far?" (header: `Depth`): tokens only / tokens + primitives / full visual migration
4. **Migrate in waves**, one commit each: wave 0 tokens and fonts with no component touched, wave 1 primitives, wave 2 a single route end to end, wave 3 the rest, wave 4 cleanup. After wave 0 the app is *supposed* to look wrong but coherent.
Two hard rules on this path: **never delete a variable you did not introduce**, and **never rewrite a screen before the user has seen and approved the gap report**. If the audit shows P0 violations in the hundreds, say the migration is a multi-day job and propose a pilot route instead of starting.
---
## Tokens — copy verbatim
Full block ready to paste: `references/tokens.css`. The contract:
- **OKLCH only.** No hex, no `rgb()`.
- **Chroma capped at 0.06** on everything except `--destructive`. A single hue family (145–152 in sage) across the entire UI, light and dark.
- `--radius: 0.25rem` and the scale is **multiplicative** (`calc(var(--radius) * 0.6)` … `* 2.6`), not additive. Changing one variable resizes every corner.
- Dark mode inverts lightness and **raises** the primary (0.42 → 0.82): light theme has a dark primary, dark theme a light one. Never the same value in both.
- Dark borders are `oklch(1 0 0 / 12%)` — translucent, never an opaque color.
Signature utility, always recreate it:
```css
@utility label-mono {
@apply font-mono text-[0.7rem] uppercase tracking-[0.18em];
}
```
---
## Typography
Two typefaces, never three: one sans for everything, one mono for every numeral. Loaded via `next/font/google` with `variable` + `display: 'swap'`.
### The four sanctioned pairings
Ask which one (Question 3), then wire only that one. Do not mix, do not substitute a face that is not on this list.
**1 — Manrope + IBM Plex Mono** (reference, default)
Slightly geometric, warm, French-pharmacy feel. The pairing the DA was designed on.
```ts
const sans = Manrope({ subsets: ['latin'], variable: '--font-manrope', display: 'swap' })
const mono = IBM_Plex_Mono({ subsets: ['latin'], weight: ['400', '500'], variable: '--font-plex-mono', display: 'swap' })
```
**2 — Geist + Geist Mono** (`geist` package, not Google)
Cooler, more technical, tighter default tracking. Best for dashboards and developer products.
```ts
import { GeistSans } from 'geist/font/sans'
import { GeistMono } from 'geist/font/mono'
// className={`${GeistSans.variable} ${GeistMono.variable}`}
// --font-sans: var(--font-geist-sans); --font-mono: var(--font-geist-mono);
```
Compensate its tighter metrics: drop hero `leading` to `1.02`, push `label-mono` tracking to `0.2em`.
**3 — Inter Tight + JetBrains Mono**
The most neutral option, widest language coverage. Mono is wider — numeric columns get roomier.
```ts
const sans = Inter_Tight({ subsets: ['latin'], variable: '--font-sans-var', display: 'swap' })
const mono = JetBrains_Mono({ subsets: ['latin'], weight: ['400', '500'], variable: '--font-mono-var', display: 'swap' })
```
**4 — Instrument Serif display + Manrope + IBM Plex Mono** (the one sanctioned exception to the two-face rule)
A serif for `h1`/`h2` **only** — never body, never buttons, never labels. Turns the DA editorial/luxury.
```ts
const display = Instrument_Serif({ subsets: ['latin'], weight: '400', variable: '--font-display', display: 'swap' })
// @theme inline { --font-display: var(--font-display), ui-serif, serif; }
// headings: className="font-display text-5xl font-normal tracking-[-0.01em]"
```
With this pairing headings are `font-normal` (400) and `tracking-[-0.01em]`, not `font-medium tracking-tight` — a serif at 500 looks broken.
The token block always exposes exactly `--font-sans` and `--font-mono` (plus `--font-display` for pairing 4). Every recipe in `references/patterns.md` keeps working whichever pairing is chosen.
### Non-negotiable rules
1. **No heading is ever `font-bold`.** `font-medium` (500) is the heaviest weight on the site — `font-normal` (400) with pairing 4. Weight does not create hierarchy: size and space do.
2. **Headings**: `tracking-tight` + `text-balance`. Hero h1: `text-4xl sm:text-5xl lg:text-6xl leading-[1.05]`. Page h1: `text-3xl lg:text-4xl`. h2: `text-2xl lg:text-3xl`.
3. **Body**: `text-sm leading-relaxed text-muted-foreground text-pretty`, always width-bounded (`max-w-md` / `max-w-lg` / `max-w-xl`). Running text is grey, not black.
4. **Eyebrow**: `.label-mono text-muted-foreground` above every section heading. This is the DA's signature — a short noun ("The ritual", "Catalogue", "Saved"), never a sentence.
5. **Every numeral is mono**: prices, quantities, counters, ratings, references, dates, totals, percentages. No exceptions. This is what produces the apothecary feel.
6. Prices formatted through `Intl.NumberFormat`, never string-concatenated.
---
## Surface, depth, radii
- **Zero `shadow-*`** on cards, buttons, inputs, dropdowns. The only shadow in the whole system is `shadow-lg` on an overlay sheet.
- Separation comes from: `border border-border` (1px), a `bg-secondary` / `bg-muted` fill, or empty space. In that order of preference.
- **No card around grid items.** Image plus text below it — no container, no border.
- Radii: `rounded-md` on thumbnails, `rounded-lg` on large blocks and hero imagery, `rounded-full` **only** for pills, counters and filter chips. Never `rounded-2xl`+ on a container.
- Header: `sticky top-0 z-40 border-b border-border bg-background/85 backdrop-blur-md`. The only blur in the interface.
- Empty state: `border border-dashed border-border` + icon in a `bg-muted` circle + one sentence + an `outline` button.
---
## Grid and rhythm
- Container: `mx-auto w-full max-w-6xl px-4 sm:px-6`.
- Vertical rhythm: `py-12 lg:py-16` for a page, `py-16`/`py-20` for a hero section, `mb-10`/`mb-14` under a page header.
- **Item grid: `grid-cols-2 lg:grid-cols-4 gap-x-4 gap-y-10`.** Vertical gap is ~2.5× horizontal — rows breathe, columns tighten. Always 2 columns on mobile, never 1.
- Full-bleed fact bands: `<section className="border-y border-border">` wrapping a `<dl>` with `lg:divide-x`. Use for promises, stats, guarantees.
- Editorial split: `grid overflow-hidden rounded-lg border border-border lg:grid-cols-2` — image one side, copy plus CTA the other, `p-8 lg:p-12`.
- Asymmetric layouts when two columns carry different weight: `lg:grid-cols-[1.2fr_0.8fr]` (form/summary), `lg:grid-cols-[1.5fr_repeat(3,1fr)]` (footer).
- Summary aside: `h-fit lg:sticky lg:top-24`.
---
## Imagery
Photography carries all the warmth, because the UI carries none. Full direction and prompts: `references/imagery.md`.
- Ratios: `aspect-4/5` (thumbnail), `aspect-square` (detail), `aspect-3/4` or `aspect-4/5` (hero), `aspect-16/10` (editorial banner).
- Always `fill` + explicit `sizes` + `object-cover`, inside a `relative overflow-hidden bg-secondary` parent (that fill acts as the loading placeholder).
- `priority` on the first image only.
- Hover: `transition-transform duration-500 group-hover:scale-[1.03]`. Subtle, slow.
---
## Motion
Little, slow, never decorative.
- Links and text: `transition-colors` alone.
- Thumbnail image: `duration-500`, 1.03 scale maximum.
- Hover-revealed action: `translate-y-2 opacity-0 → group-hover:translate-y-0 group-hover:opacity-100`, `duration-300`, **with a mirrored `focus-within:`** for keyboard users.
- Buttons: `active:translate-y-px`. That is the entire tactile feedback budget.
- Overlays: `duration-150`/`duration-200`, `2.5rem` translation, opacity.
- **Banned**: parallax, scroll-triggered animation, springs, count-up numbers, carousels, shimmering skeletons, `animate-pulse`.
---
## Component architecture
Follow this for every new component (full recipes: `references/patterns.md`).
- **base-ui** primitives (`@base-ui/react/*`) + `cva` for variants + `cn()` (clsx + tailwind-merge).
- `data-slot="..."` on every primitive root.
- Polymorphism via `render={<Link href="..." />}`, **not** `asChild`.
- Dense defaults (`h-8`), **overridden at the call site** for marketing surfaces: `className="h-10 px-5"` (secondary), `className="h-11 px-6"` (primary/hero).
- Button variants: `default`, `outline`, `secondary`, `ghost`, `destructive`, `link`. `destructive` uses a `/10` tinted fill, never solid red.
- **lucide-react** icons only, auto-sized `size-4` (`size-3.5` at `sm`). Never emoji in the UI.
- Static data lives typed in `lib/<domain>.ts`: one `type`, one `const` array, helpers (`getX(slug)`, `formatX()`). No hardcoded data inside components.
---
## shadcn/ui — Next.js projects
When the target is a Next.js app, do not hand-write primitives. Scaffold with shadcn, then apply the DA on top.
### 1. Config — `components.json`
```json
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "base-nova",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "",
"css": "app/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"iconLibrary": "lucide"
}
```
`"style": "base-nova"` matters: it emits **base-ui** primitives with the `render` prop, `data-slot` attributes and the `size` variants this DA assumes. The Radix-based styles do not — they use `asChild` and different sizing. `"config": ""` is correct for Tailwind v4 (no JS config file). `baseColor: neutral` only seeds the generator; the OKLCH block from `references/tokens.css` overwrites it right after.
### 2. Install only what the surface needs
```bash
npx shadcn@latest init # skip if components.json is already written
npx shadcn@latest add button input label separator sheet sonner
```
| Surface | Add |
|---|---|
| Every project | `button input label separator sonner` |
| Storefront / cart | `+ sheet badge checkbox radio-group select` |
| Dashboard | `+ table tabs dropdown-menu tooltip skeleton` |
| Forms / settings | `+ select checkbox radio-group switch textarea` |
| Docs / content | `+ tabs accordion scroll-area` |
Never bulk-add the whole registry. An unused primitive is dead code that drifts from the DA.
### 3. Patch every added component
Generated components ship with defaults this DA forbids. Immediately after `add`, sweep the new files in `components/ui/`:
- Strip `shadow-xs` / `shadow-sm` / `shadow-md` from buttons, inputs, cards, popovers, dropdowns. Only an overlay sheet keeps `shadow-lg`.
- Confirm radii resolve through `var(--radius)` — replace any hardcoded `rounded-xl`/`rounded-2xl` on containers with `rounded-lg`.
- Keep the dense default sizes (`h-8`, `size-7`). Do not globally bump them — override at the call site with `className="h-10 px-5"` or `h-11 px-6`.
- `destructive` must stay a `/10` tinted fill, not a solid red button.
- Toaster: wire `--normal-bg`, `--normal-text`, `--normal-border`, `--border-radius` to the DA tokens and swap in lucide icons at `size-4`.
- Delete any `focus:ring-offset-*` — this DA uses `focus-visible:ring-3 focus-visible:ring-ring/50` with no offset.
### 4. Order of operations (greenfield)
Existing project: skip this and follow `references/adoption.md` §3 — the component base is already chosen for you.
1. `create-next-app` (App Router, TypeScript, Tailwind v4)
2. Write `components.json`
3. Paste `references/tokens.css` into `app/globals.css` — **before** adding components, so generated code reads the right variables
4. Wire the chosen type pairing in `app/layout.tsx`
5. `shadcn add` the needed primitives, then patch them (step 3 above)
6. Build screens from `references/patterns.md`
Non-Next.js stacks (Vite, Remix, Astro, plain React): same tokens, same rules, skip this section and write the primitives by hand — `references/patterns.md` only needs Tailwind v4 and `cn()`.
---
## Accessibility (part of the DA, not an add-on)
- Every icon button carries a `<span className="sr-only">` or an explicit `aria-label`.
- Filters, size pickers, favorites → `aria-pressed`.
- `<nav aria-label="...">` on every nav (primary, mobile, footer columns).
- Forms: `noValidate`, hand-rolled validation, `aria-invalid`, `aria-describedby` pointing at `<p id="{id}-error" className="text-xs text-destructive">`.
- Real semantics: `<dl>` for key/value pairs, `<ol>` for steps, `<article>` for a grid item.
- Active filter state is marked by `border-foreground text-foreground` — never by color alone.
---
## Editorial voice
- Headlines are **short, confident statements**: "Skin doesn't need ten steps.", "Eight formulas, nothing surplus", "Three gestures are enough". Never a rhetorical question as h1, never an exclamation mark.
- Subheads: one or two factual sentences explaining the *how*, not selling.
- Microcopy is numeric and verifiable: "Free shipping over £60", "12 ingredients on average", "ships within 48 h".
- Empty states: observation plus the gesture. "Tap the heart on a product to keep it here."
- Banned: "revolutionary", "amazing", emoji, superlatives, shouty caps, "✨".
---
## Blacklist
If any of these appear, the DA is broken:
gradients · card drop shadows · glassmorphism (outside the header) · 700+ headings · more than two typefaces · SaaS purple/blue · saturated accents · `rounded-2xl`+ containers · hero carousels · emoji · 3D illustration · multiple colored badges · buttons in different fills · sans-serif numerals · centered long-form paragraphs · scroll animations.
---
## References
- `references/adoption.md` — **path B**: auditing an existing project, merging tokens without destroying theirs, Tailwind v3 and Radix-shadcn fallbacks, wave migration, rollback.
- `references/tokens.css` — complete `@theme` + `:root` + `.dark` block to paste into `globals.css`. **Greenfield only** — in an existing project use the merge block in `adoption.md`.
- `references/patterns.md` — JSX recipes: header, item grid, editorial split, fact band, sheet, form field, empty state, footer.
- `references/imagery.md` — photographic direction and generation prompts that match the palette.
---
**MB-Minimalistic** · French edition: `mb-minimalistic-fr`
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!