Layout and spacing skill.
A free skill that teaches Claude Code, Codex, Cursor and other AI coding agents to space and align UI on purpose: a 4px spacing scale, grouping by distance, grids and layouts that hold from a 320px phone to a wide desktop.
Random spacing is the quickest way to make a page feel unfinished. This skill gives your agent one spacing scale and the reason behind each step, so it groups related things tightly, separates groups clearly and stops inventing values like 13px. It ends with a short checklist the agent runs before it hands the work back.
- Skill
wensity-layout- Plan
- Free, no account needed
- Loads when
- Building a page, section, form or dashboard, or changing spacing, grids or responsive layout
- Works in
- Claude Code, Codex, Cursor, GitHub Copilot, Windsurf, Gemini CLI, OpenCode
- Format
- Agent Skills (SKILL.md), plain files in your project
- Pack
- One of the Wensity design skills for AI coding agents
Install
Run this in your project. It finds the agents you use and puts the skill where each one looks for it.
pnpm dlx skills add wensity/skills --skill wensity-layout
npx skills add wensity/skills --skill wensity-layout
yarn dlx skills add wensity/skills --skill wensity-layout
bunx skills add wensity/skills --skill wensity-layout
Open source under MIT, with the other free skills. A star helps other developers find them.
Or add it by hand: save the file as SKILL.md in a folder named wensity-layout.
Where each agent looks for it
- Claude Code
- .claude/skills/wensity-layout/SKILL.md
- Codex, Cursor, Copilot, Windsurf, Gemini CLI, OpenCode
- .agents/skills/wensity-layout/SKILL.md
When it loads
You never call a skill by name. Your agent reads the short description at the top of every installed skill and loads this one when the work calls for it. Requests like these bring it in:
- This dashboard feels cramped and breaks on phones. Fix the layout and spacing.
- The spacing on the pricing section looks random.
- Make this settings page work on mobile.
What it covers
- The spacing scale
- One 4px scale where each step has a job, so values like 13px never show up.
- Grouping and rhythm
- Related things sit close and groups sit apart, with more space above a heading than below it, and sections that do not all share one gap.
- Alignment and containers
- One start edge per section, numbers aligned at the end, gutters that grow with the screen and text that never runs full width.
- Grids
- Card grids that fill the space they get, tracks allowed to shrink, bento grids with one gap, and subgrid for rows of cards.
- Responsive structure
- Breakpoints set by the content, layouts that restructure instead of shrinking, container queries, dvh units and safe areas.
- Tables, density and touch
- Row heights by density, sticky headers, wide tables that scroll in their own frame, and 44px touch targets.
Group a settings form by distance
One settings page, same fields, type and colours. Without the skill one gap does every job; with it each gap comes from the scale by job. Flip the switch, then drag the slider to see what the space between sections does.
Without the skill: One 16px gap does every job, so each label sits as close to the field above it as to its own input, and the three sections run together.
Key rules
- Space before boxes
- Group with distance first. A border or divider comes in only when space is not enough.
- gap for siblings
- Spacing between children is set once with gap on the parent, not with margins on each child.
- Restructure, do not shrink
- A three-column grid becomes a stack on phones, never three tiny columns.
- No horizontal page scroll
- Every layout is checked at 320px wide.
- 44px touch targets
- Anything tappable gets a 44 by 44px hit area, even when it looks smaller.
- dvh, not vh
- Full-height sections use min-h-dvh so mobile browser bars do not cut them off.
Resize from desktop to phone
Drag the edge of the frame, or focus it and use the arrow keys, to take one store dashboard from 1280px down to 320px. With the skill the layout restructures one step at a time instead of squeezing.
Overview
Last 30 days, all channels
Revenue this month
$18,420
Orders awaiting shipment
27
Returning customers
41%
Restock the Field headphones
Nine pairs left at the current pace of four a day. The supplier needs eleven days, so order this week to avoid a gap.

Recent orders
| Order | Customer | Status | Total |
|---|---|---|---|
| #4821 | Aisha Mensah | Shipped | $249.00 |
| #4820 | Tomás Herrera | Packing | $89.00 |
| #4819 | Lena Fischer | Shipped | $1,120.00 |
Without the skill: At 390px nothing restructures: the sidebar keeps its 200px and each stat column is about 42px wide, so labels break mid-word.
The full skill
This is the whole skill, exactly as your agent reads it. Change anything you like once it is in your project: it is a plain file.
Layout is how a page tells people what matters and what belongs together, before they read a word. Good layout comes from three habits: a fixed spacing scale, grouping by distance, and one alignment system. This skill sets all three up and covers responsive structure.
If the project already has a spacing scale and container widths, use them.
1. The spacing scale
Use a 4px base. Every margin, padding and gap comes from this list:
| Token | px | Typical use |
|---|---|---|
| 1 | 4 | icon to label, tight inline gaps |
| 2 | 8 | inside a control, between a label and its input |
| 3 | 12 | between items in a dense list, button padding y |
| 4 | 16 | card padding (compact), gap between related controls, mobile page gutter |
| 5 | 20 | button padding x (large) |
| 6 | 24 | card padding, gap between form fields |
| 8 | 32 | between groups inside a section |
| 10 | 40 | between a section heading and its content (large) |
| 12 | 48 | section padding on mobile |
| 16 | 64 | between sections in an app, section padding on tablet |
| 20 | 80 | |
| 24 | 96 | section padding on desktop marketing pages |
| 32 | 128 | hero padding, the space around one big statement |
Tailwind's default scale already follows a 4px base (p-4 is 16px), so use
its steps and do not invent p-[13px]. Odd values are allowed only for
optical corrections you checked in the render (an icon that looks off by 1px).
2. Group by distance
The single most important layout rule: space inside a group is smaller than space between groups. A label sits 8px from its input; the next field sits 24px away. A card's title sits 8px above its text; the next card sits 24px away. When inner and outer spacing are equal, everything floats apart and nothing reads as a group.
- Aim for a ratio of about 1 to 2 or 1 to 3 between inner and outer gaps.
- More space above a heading than below it. The heading belongs to the content after it. Typical: 48px above a section heading, 16px below.
- Spacing before boxes. Group with distance first. Add a border, divider or background only when distance is not enough (dense tables, toolbars, content on busy backgrounds). A box around every group makes a page heavy.
- Use
gapfor siblings (flex gap-4,grid gap-6) instead of margins on children. It keeps spacing in one place and avoids stray margin at the ends of a list.
3. Rhythm, not sameness
A page where every section has 96px padding, a centered heading and a grid of three items has no rhythm. Vary density on purpose:
- Alternate dense sections (feature grids, tables, logos) with open ones (one statement, one large image).
- Let important sections take more space. Space is how you spend attention.
- Repeat a layout only when the content is truly the same kind of thing.
4. Alignment
- One start edge. Headings, paragraphs, buttons and images in a section share the same starting line. Most "something looks off" complaints are two edges a few pixels apart.
- Align to the start by default (
text-align: start, which is left in English and right in Arabic or Hebrew). Center only short, standalone content: a hero headline, a single CTA block, an empty state. Forms, tables, lists and long text align to the start. - Align numbers to the end in tables and stat columns.
- Align to text, not boxes. An icon next to a label aligns with the
label's cap height or center, not the top of the line box. In flex rows,
items-centerfor single lines;items-startplus a small top margin on the icon for multi-line text. - Optical adjustments: play icons, arrows and round shapes look off center when centered mathematically. Nudge by 1 to 2px after you see it.
5. Containers and widths
| Container | Max width | Use |
|---|---|---|
| Prose | 65ch (about 640 to 720px) | articles, docs, long paragraphs |
| Narrow | 560 to 640px | forms, sign-in, focused tasks, a centered hero statement |
| Content | 1120 to 1280px | most marketing sections and app pages |
| Wide | 1440 to 1600px | dashboards, galleries, editors |
| Full bleed | 100% | backgrounds, images, product shots that should touch the edges |
- Page gutter: 16px on phones, 24px on tablets, 32 to 48px on desktop. Keep it consistent: one gutter value per breakpoint for the whole site.
- Separate background from content width. A section's background can run full bleed while its content stays in the content container.
- Do not let text run full width on wide screens. Images and grids can grow; paragraphs cannot.
6. Grids
- 12 columns for marketing layouts gives you halves, thirds, quarters and asymmetric splits (7 and 5, 8 and 4). Asymmetric splits look more designed than 6 and 6.
- Auto-filling grids for cards so the column count follows the space:
.cards { display: grid; gap: 24px; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); }
The min(100%, 280px) stops overflow on screens narrower than 280px.
auto-fill keeps card width steady when there are only one or two cards;
auto-fit stretches the few cards to fill the row. Pick on purpose.
- Let flexible tracks shrink. Grid and flex children refuse to shrink
below their content by default, which is why long text or a wide table
overflows a dashboard. Use
minmax(0, 1fr)for flexible tracks andmin-width: 0(Tailwindmin-w-0) on flex children that hold text:
.app-shell { display: grid; grid-template-columns: 16rem minmax(0, 1fr); }.row > .text { min-width: 0; }
- Equal heights only for equal content. Cards in one row stretch to the tallest by default in grid. Fine for a set of plans; wrong when one card is clearly the featured one.
- Bento grids: vary tile sizes by importance, keep one gap value, and give every tile a real piece of content. Empty decorative tiles look like a template.
- Use subgrid (
grid-template-rows: subgrid) when cards in a row need their titles, bodies and buttons to line up with each other.
7. Responsive structure
Design mobile first, then add structure as space grows.
- Breakpoints follow content, not devices. Add one where the layout
starts to look wrong. Tailwind's
sm 640,md 768,lg 1024,xl 1280are fine defaults. - Restructure, do not just shrink. On mobile, a three-column feature grid becomes one column, side-by-side text and image stack with the image second (or first if it carries the message), a table becomes a list of cards or scrolls horizontally inside its own container, a sidebar becomes a drawer.
- Container queries for components that appear in different widths (a card in a sidebar and in a main column):
.card-wrap { container-type: inline-size; }@container (min-width: 480px) { .card { grid-template-columns: 160px 1fr; } }
In Tailwind v4: @container on the parent and @md:grid-cols-2 on the child.
- Scale spacing with the screen. Section padding: 48px mobile, 64px tablet, 96px desktop. Gaps can step from 16 to 24 to 32.
- Viewport height: use
min-h-dvh(or100dvh), noth-screen(100vh), for full-height layouts.100vhis taller than the visible area on mobile browsers with a toolbar, so content hides under it. - Safe areas on phones with notches:
padding-bottom: env(safe-area-inset-bottom)on fixed bottom bars, withviewport-fit=coverin the viewport meta tag. - Right-to-left languages: use logical properties (
margin-inline-start,padding-inline,inset-inline-end; Tailwindms-*,pe-*,start-*) instead of left and right, and test withdir="rtl". Mirror directional icons (back arrows, chevrons), not logos or every icon. - No horizontal page scroll, ever. Check at 320px. The usual causes are a
fixed width, a long word or URL, a
w-screenelement (which includes the scrollbar width), or a negative margin.
8. Tables
- Header row in the label role, sticky (
position: sticky; top: 0) when the table scrolls, on a tinted surface or with a stronger bottom border. - Row height by density: 36px compact, 44px default, 52px comfortable. Offer a toggle when users differ.
- Rows separated by hairline dividers or by zebra tint, not both.
- Numbers end-aligned with
tabular-nums; text start-aligned; status and actions in the last columns. - Wide tables on mobile: scroll horizontally inside their own container
(
overflow-x: auto) with the first column sticky, or switch to a stacked card per row. Never let a table push the page sideways. - Empty, loading and error states live inside the table frame, keeping the header so the user knows what will appear.
9. Density
Match density to how often the screen is used:
- Marketing and onboarding: open. Few items per screen, generous space, large type.
- Daily-use app screens: compact. Rows of 36 to 44px, 8 to 12px gaps, 14px text. People who use a screen every day want to see more at once.
- Tables and data tools: dense, with a density toggle if users differ.
- Do not mix densities within one panel.
10. Touch targets and hit areas
- 44 by 44px target for anything tappable on touch screens, even if the visible icon is 16px. (WCAG 2.2 AA requires at least 24 by 24px; 44 is the comfortable size.) Grow the hit area with padding, or with an invisible pseudo-element centered on the control so the layout does not change:
.icon-btn { position: relative; }.icon-btn::before {content: ""; position: absolute; left: 50%; top: 50%;width: max(100%, 44px); height: max(100%, 44px);transform: translate(-50%, -50%);}
- At least 8px between separate tap targets so a thumb does not hit two.
11. Layering
Keep a small z-index scale and use only these values:
:root { --z-dropdown: 10; --z-sticky: 20; --z-overlay: 30; --z-modal: 40; --z-toast: 50; --z-tooltip: 60; }
Native <dialog> opened with showModal() and elements with the popover
attribute render in the browser's top layer, above every z-index, so they
need none. z-index: 9999 means the stacking is not understood. Fix the stacking
context (often a stray transform, filter or isolation on a parent)
instead of raising the number.
12. Sticky and fixed elements
- Sticky headers: keep them short (56 to 64px), and give them a background (solid or blurred) only once the page scrolls under them, so the top of the page stays clean.
- Add
scroll-margin-topequal to the header height on anchored headings so in-page links do not land under the header. - Fixed bottom bars on mobile need the safe-area padding above and must not cover the last content on the page; pad the page bottom by the bar's height.
13. Check before you finish
- Every spacing value is on the 4px scale.
- Space inside groups is clearly smaller than space between them.
- More space above headings than below.
- One start edge per section; numbers end-aligned in tables.
- Flexible tracks use
minmax(0, 1fr); text children can shrink. - Paragraphs capped at about 65ch, even on wide screens.
- Layout restructures on mobile instead of just shrinking.
- No horizontal scroll at 320px; full-height sections use
dvh. - Touch targets at least 44px (never under 24px).
- z-index values come from the scale.
- Squint test: the most important thing and the groups are clear with the details blurred.
Works well with
Typography
FreeFonts, a role-based type scale, line height, tracking, measure, line breaks, numbers and font loading.
Dashboard and app UI
ProApp shells, data tables, settings, dashboards, charts, detail panels, command menus and keyboard shortcuts.
Accessibility and UI states
ProEvery interaction and data state, plus keyboard, touch, zoom, forced colors and screen readers.