Design system · v0.1

Quiet by default.
Violet when it matters.

Inkwell is the system behind this portfolio: lilac paper by day, ink by night, and a single violet that only speaks when it has something to say. Every colour, curve and motion on sanjeevkujur.dev starts here.

  • 70 Violet
  • 20 Cream
  • 10 Peach

Try the toggle in the corner. This whole page is the specimen.

Ten chapters.

  1. 01PrinciplesThe beliefs behind every pixel.Design decisionsCommit historyRead →
  2. 02ColorSeventy percent violet. Twenty cream. Ten peach.CSS variablescolor-mix()Tailwind @themeRead →
  3. 03TypographyFive voices, each with exactly one job.next/fontFrauncesSynonymJetBrains MonoRead →
  4. 04Shape & surfacePaper, ink, and the space between them.Tailwind @theme radiiHairline bordersLayered surfacesRead →
  5. 05Layout & spacingFew breakpoints, few widths, one rhythm.Tailwind breakpointsmax-widthGuttersRead →
  6. 06MotionNothing moves without a reason.Framer MotionCSS transitionsLenisRead →
  7. 07ComponentsSmall pieces, loosely held together.shadcn/uiRadix UIcvaRead →
  8. 08AccessibilityMeasured contrast, and where it falls short.WCAG 2 contrastprefers-reduced-motionFocusRead →
  9. 09ThemingOne attribute flips the whole world.data-themelocalStorageInline boot scriptRead →
  10. 10Use itHand the system to the next person, or agent.DESIGN.mdDesign tokensCSS variablesRead →

How it is built

Three layers. One source of truth.

1

Primitives

Raw palette values. The only place a hex code is allowed to live.

2

Semantic

What the interface actually uses: background, primary, border. Each theme points these at primitives.

3

Component

Narrow tokens for specific widgets, built from the layer above. Change one, nothing else moves.

What it is made from

Every chapter shows its workings.

Nothing here is a screenshot. Each specimen is the real component running on the real tokens, next to the code and the reasoning that produced it.

Next.js 16
App Router. This page is a route in the portfolio, served on its own subdomain by a host rewrite.
Tailwind CSS v4
Tokens are exposed through @theme inline, so utilities like bg-primary read live CSS variables.
CSS custom properties
Three layers (primitive, semantic, component) with a single data-theme attribute for dark.
shadcn/ui + Radix
new-york style primitives, composed with class-variance-authority and tailwind-merge.
Framer Motion, CSS, Lenis
Framer Motion for entrances and state, plain CSS for hover and loaders, Lenis for smooth scroll.
next/font
Fraunces, Synonym, Amulya, Bespoke Stencil and JetBrains Mono, self-hosted and swapped in.

Passing it on

A system is only as good as its next reader.

Sooner or later someone opens the project who has never seen it. Often it is a coding assistant. It cannot guess that violet is rare, or that hex lives in one place. So the system is written down, in one file, and three small commands carry that file into any project.

  1. 1

    Write it down once

    Start from the Inkwell file: tokens, rules and what never to do, in a single DESIGN.md at the root of the project.

    npx @sanjeevsaniel/inkwell-skill template
  2. 2

    Teach the assistant

    Install the skill so a coding assistant reads that file before it touches a colour, a size or a curve.

    npx @sanjeevsaniel/inkwell-skill init
  3. 3

    Keep it honest

    Check the file against the real CSS and type scale. When the two drift apart, it says exactly where, and fails.

    npx @sanjeevsaniel/inkwell-skill check

All three come from one package, @sanjeevsaniel/inkwell-skill. The template is Inkwell's own file, so swap in your tokens before you rely on it.