Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { StorybookConfig } from '@storybook-vue/nuxt'

const config = {
stories: ['../.storybook/*.mdx', '../app/**/*.stories.@(js|ts)'],
stories: ['../.storybook/*.mdx', '../app/**/*.@(mdx|stories.@(js|ts))'],
addons: [
'@storybook/addon-a11y',
'@storybook/addon-docs',
Expand Down
110 changes: 110 additions & 0 deletions app/colors.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { Meta, ColorPalette, ColorItem } from '@storybook/addon-docs/blocks'
import { theme } from '../uno.theme.ts'

<Meta title="Colors" tags={['hide-toolbar']} />

# Colors

The npmx color system is built on CSS custom properties with support for light/dark themes and multiple background variants.

Color values are defined in [uno.theme.ts](../uno.theme.ts).

## Background Colors

<ColorPalette>
<ColorItem
title="Background"
subtitle="Main background colors"
colors={Object.entries(theme.colors.bg).reduce(
(acc, [key, value]) => ({
...acc,
[key === 'DEFAULT' ? 'bg' : `bg-${key}`]: value,
}),
{},
)}
/>
</ColorPalette>

## Foreground Colors

<ColorPalette>
<ColorItem
title="Foreground"
subtitle="Text and content colors"
colors={Object.entries(theme.colors.fg).reduce(
(acc, [key, value]) => ({
...acc,
[key === 'DEFAULT' ? 'fg' : `fg-${key}`]: value,
}),
{},
)}
/>
</ColorPalette>

## Border Colors

<ColorPalette>
<ColorItem
title="Border"
subtitle="Border and separator colors"
colors={Object.entries(theme.colors.border).reduce(
(acc, [key, value]) => ({
...acc,
[key === 'DEFAULT' ? 'border' : `border-${key}`]: value,
}),
{},
)}
/>
</ColorPalette>

## Accent Colors

<ColorPalette>
<ColorItem
title="Primary Accent"
subtitle="User-settable accent color"
colors={Object.entries(theme.colors.accent).reduce(
(acc, [key, value]) => ({
...acc,
[key === 'DEFAULT' ? 'accent' : `accent-${key}`]: value,
}),
{},
)}
/>
</ColorPalette>

## Syntax Highlighting

<ColorPalette>
<ColorItem
title="Syntax"
subtitle="Code syntax highlighting colors"
colors={theme.colors.syntax}
/>
</ColorPalette>

## Badge Colors

<ColorPalette>
<ColorItem
title="Badges"
subtitle="Badge background and text colors"
colors={theme.colors.badge}
/>
</ColorPalette>

## Provider Brand Colors

<ColorPalette>
<ColorItem
title="Provider Brand Colors"
subtitle="Playground provider and framework brand colors"
colors={theme.colors.provider}
/>
</ColorPalette>

---

## Related

- [Design System Guidelines](./?path=/docs/guidelines--docs)
86 changes: 86 additions & 0 deletions app/design-system-guidelines.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Meta } from '@storybook/addon-docs/blocks'

<Meta title="Guidelines" tags={['hide-toolbar']} />

# Guidelines

## Containers

We use three container types depending on content density.

**Main Container** is the default layout container. It should be used for pages with minimal or non-text content (e.g. graphs, dashboards).

**Content Container** is used for text-heavy layouts. All long-form content must be placed inside this container. The maximum readable width is **768px**.

**Extra Container** is used for dense layouts (e.g. code, detailed views) where additional horizontal space is required.

A right sidebar (304px) may be used for secondary content when needed.

Text and input fields should not exceed **768px** in width

## Element Sizes

Interactive element sizes:

- 24 — 2xs (rare)
- 28 — xs (compact)
- 32 — sm (minimum recommended)
- 36 — md (default)
- 42 — lg
- 48 — xl
- 56 — 2xl
- 64 — 3xl

## Typography

- Base font size: **16px**
- Minimum font size: **14px** (use sparingly)

Text casing:

- **Uppercase** — for headings
- **Lowercase** — for UI elements
- **Normal** - for body content

[See Typography](./?path=/docs/tokens-typography--docs)

## Surfaces & Sections

To visually separate content blocks (grouped content, cards, settings sections), use subtle background variations:

- `bg-muted`
- `bg-subtle`

## Borders & Radius

- subtle border
- light border radius
- soft "glass-like" appearance

Only avatars should have fully circular shapes.

## Colors

- Primary surfaces: **white** (`fg`)
- Secondary or less important content: use softer, muted tones

[See Colors](./?path=/docs/tokens-colors--docs)

## Layout Stability

Interfaces must remain visually stable across screens and pages. Avoid layout shifts. If shifts are unavoidable, place elements where movement is not critical to user interaction.

## Responsiveness specifics

On smaller screens:

- Button text may be hidden (icons only)
- Keyboard shortcuts may be hidden

## General Principles

- Preserve the meaning of elements (avoid links like button, etc)
- Maintain sufficient spacing
- Keep interfaces accessible
- Prefer simple, predictable layouts
- Design components to be easy to implement and scale
166 changes: 166 additions & 0 deletions app/typography.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import { Meta, Typeset } from '@storybook/addon-docs/blocks'
import { theme } from '../uno.theme.ts'

<Meta title="Typography" tags={['hide-toolbar']} />

export const wind4FontSizes = {
'xs': '0.75rem',
'sm': '0.875rem',
'base': '1rem',
'lg': '1.125rem',
'xl': '1.25rem',
'2xl': '1.5rem',
'3xl': '1.875rem',
'4xl': '2.25rem',
'5xl': '3rem',
}

# Typography

The npmx typography system uses Geist for sans-serif text and Geist Mono for monospace code.

Typography values are defined in `uno.theme.ts`.

## Font Families

### Sans Serif — Geist

<Typeset
fontFamily={theme.font.sans}
fontSizes={[
wind4FontSizes['base'], // 16px
]}
fontWeight={400}
sampleText="The quick brown fox jumps over the lazy dog"
/>

<Typeset
fontFamily={theme.font.sans}
fontSizes={[
wind4FontSizes['5xl'], // 48px
wind4FontSizes['4xl'], // 36px
wind4FontSizes['3xl'], // 30px
wind4FontSizes['2xl'], // 24px
wind4FontSizes['xl'], // 20px
wind4FontSizes['lg'], // 18px
wind4FontSizes['base'], // 16px
wind4FontSizes['sm'], // 14px
wind4FontSizes['xs'], // 12px
theme.text['2xs'].fontSize, // 11px
theme.text['3xs'].fontSize, // 10px
theme.text['4xs'].fontSize, // 9px
theme.text['5xs'].fontSize, // 8px
]}
fontWeight={400}
sampleText="The quick brown fox jumps over the lazy dog"
/>

### Monospace — Geist Mono

Code and monospace typography scale:

<Typeset
fontFamily={theme.font.mono}
fontSizes={[
wind4FontSizes['base'], // 16px
]}
fontWeight={400}
sampleText="const greeting = 'Hello, World!';"
/>

<Typeset
fontFamily={theme.font.mono}
fontSizes={[
wind4FontSizes['5xl'], // 48px
wind4FontSizes['4xl'], // 36px
wind4FontSizes['3xl'], // 30px
wind4FontSizes['2xl'], // 24px
wind4FontSizes['xl'], // 20px
wind4FontSizes['lg'], // 18px
wind4FontSizes['base'], // 16px
wind4FontSizes['sm'], // 14px
wind4FontSizes['xs'], // 12px
theme.text['2xs'].fontSize, // 11px
theme.text['3xs'].fontSize, // 10px
theme.text['4xs'].fontSize, // 9px
theme.text['5xs'].fontSize, // 8px
]}
fontWeight={400}
sampleText="const greeting = 'Hello, World!';"
/>

## Font Sizes

The complete typography scale combines custom micro sizes (`5xs`-`2xs` from our theme) with standard Wind4 preset sizes (`xs`-`5xl`).

**Custom Micro Sizes (from `theme.text`):**

- `5xs` = {theme.text['5xs'].fontSize} (8px)
- `4xs` = {theme.text['4xs'].fontSize} (9px)
- `3xs` = {theme.text['3xs'].fontSize} (10px)
- `2xs` = {theme.text['2xs'].fontSize} (11px)

**Wind4 Standard Sizes:**

- `xs` = {wind4FontSizes['xs']} (12px)
- `sm` = {wind4FontSizes['sm']} (14px)
- `base` = {wind4FontSizes['base']} (16px)
- `lg` = {wind4FontSizes['lg']} (18px)
- `xl` = {wind4FontSizes['xl']} (20px)
- `2xl` = {wind4FontSizes['2xl']} (24px)
- `3xl` = {wind4FontSizes['3xl']} (30px)
- `4xl` = {wind4FontSizes['4xl']} (36px)
- `5xl` = {wind4FontSizes['5xl']} (48px)

## Font Weights

<Typeset
fontFamily={theme.font.sans}
fontSizes={['1rem']}
fontWeight={300}
sampleText="Light (300) — Used sparingly for decorative purposes"
/>

<Typeset
fontFamily={theme.font.sans}
fontSizes={['1rem']}
fontWeight={400}
sampleText="Regular (400) — Default weight for body text and most content"
/>

<Typeset
fontFamily={theme.font.sans}
fontSizes={['1rem']}
fontWeight={500}
sampleText="Medium (500) — Used for emphasis and section headings"
/>

<Typeset
fontFamily={theme.font.sans}
fontSizes={['1rem']}
fontWeight={600}
sampleText="Semibold (600) — Used for strong emphasis and primary actions"
/>

<Typeset
fontFamily={theme.font.sans}
fontSizes={['1rem']}
fontWeight={700}
sampleText="Bold (700) — Used for headings and important labels"
/>

## Line Height

Base line height is set to **1.6** for optimal readability. This provides comfortable spacing for multi-line text blocks while maintaining density for UI components.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use the standard hyphenated term “line-height”.

At Line 154, “Base line height” reads better as “Base line-height” in typography docs.

📝 Suggested wording tweak
-Base line height is set to **1.6** for optimal readability. This provides comfortable spacing for multi-line text blocks while maintaining density for UI components.
+Base line-height is set to **1.6** for optimal readability. This provides comfortable spacing for multi-line text blocks while maintaining density for UI components.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Base line height is set to **1.6** for optimal readability. This provides comfortable spacing for multi-line text blocks while maintaining density for UI components.
Base line-height is set to **1.6** for optimal readability. This provides comfortable spacing for multi-line text blocks while maintaining density for UI components.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no preference on this. If others feel this is a good suggestion we can change to the hyphenated "line-height" here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cylewaitforit, totally fair! The main rationale is just that line-height mirrors the CSS property name, which can make the docs feel more consistent with technical references. That said, "line height" (unhyphenated) is equally valid prose — it's a genuinely minor point. Happy to leave it as-is if there's no strong preference from the team. 🐇


🧠 Learnings used
Learnt from: cylewaitforit
Repo: npmx-dev/npmx.dev PR: 1964
File: .storybook/preview-head.html:1-6
Timestamp: 2026-03-06T17:45:06.525Z
Learning: In the npmx.dev project, the `.storybook/preview-head.html` file sets `background-color` on `.docs-story` via the `--bg` CSS custom property to fix the Autodocs canvas background. This is an intentional workaround for a known Storybook bug (storybookjs/storybook#30928) where `addon-themes` and `parameters.docs.theme` do not apply to the individual story canvas iframes in the Autodocs tab. Removing this file causes the autodocs pages to not display correctly.


## Typography Features

- **Font smoothing**: Antialiased rendering (`-webkit-font-smoothing: antialiased`) applied globally
- **Text rendering**: `optimizeLegibility` applied globally for consistent cross-browser rendering

---

## Related

- [Design System Guidelines](./?path=/docs/guidelines--docs) - See typography guidelines and usage
- [Colors](./?path=/docs/colors--docs) - View the color system
2 changes: 1 addition & 1 deletion chromatic.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
"onlyChanged": true,
"autoAcceptChanges": "main",
"exitZeroOnChanges": false,
"externals": [".storybook/**", "uno.config.ts"]
"externals": [".storybook/**", "uno.config.ts", "uno.theme.ts"]
}
Loading
Loading