بنقرة واحدة
styling-material
UI polish patterns for typography, visual design, layout, and dark mode
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
UI polish patterns for typography, visual design, layout, and dark mode
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Creative direction for AI image generation — distill a codebase's FEEL canon (taste tokens, TDRs, persona files) into prompt-ready material vocabulary, map product architecture to scene systems, and enforce visual discipline across banner sets and scene stacks.
Analyze feedback logs to detect design preference patterns. Auto-contributes HIGH confidence patterns upstream.
Motion design and animation patterns for UI based on Emil Kowalski's principles
Touch, keyboard, and form interaction patterns for accessible UI
Design physics system for UI interactions - sync strategies, timing, confirmations
Convert vague "feel" feedback into specific actionable fixes via decomposition questions
| name | styling-material |
| description | UI polish patterns for typography, visual design, layout, and dark mode |
| user-invocable | true |
| allowed-tools | Read, Write, Glob, Grep, Edit |
UI polish patterns for typography, visual design, layout, and dark mode. Transform functional interfaces into polished, professional experiences.
/style
This skill provides guidance on the finishing touches that elevate UI from functional to refined. Use it when:
Always apply antialiased font smoothing:
body {
-webkit-font-smoothing: antialiased;
}
Subset fonts based on content to minimize file size. Only include characters you actually use.
// next.config.js - Next.js automatic subsetting
import { Inter } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
display: 'swap',
});
Define weights as CSS variables for global control:
:root {
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
}
Never change font weight on hover or selected states:
/* Bad - causes layout shift */
.tab:hover {
font-weight: 600;
}
/* Good - consistent weight, change color instead */
.tab {
font-weight: 500;
}
.tab.selected {
color: var(--color-primary);
}
Use tabular numbers for changing values:
.counter,
.price,
.timer {
font-variant-numeric: tabular-nums;
}
Use text-wrap: balance on headings for better line breaks:
h1, h2, h3 {
text-wrap: balance;
}
Larger text needs tighter spacing; smaller text needs looser:
// Pair font sizes with optimal letter spacing in a Text component
const letterSpacing = {
xs: '0.02em', // Looser for small text
sm: '0.01em',
base: '0',
lg: '-0.01em',
xl: '-0.02em', // Tighter for large text
'2xl': '-0.025em',
};
Use proper typographic characters:
| Instead of | Use |
|---|---|
... | … (ellipsis) |
' | ' (curly apostrophe) |
" | " " (curly quotes) |
Use shadows instead of borders for better blending:
/* Instead of: border: 1px solid rgba(0, 0, 0, 0.08) */
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.08);
Benefits:
Use 0.5px borders on retina displays:
:root {
--border-hairline: 1px;
@media only screen and (min-device-pixel-ratio: 2),
only screen and (min-resolution: 192dpi) {
--border-hairline: 0.5px;
}
}
.divider {
border-bottom: var(--border-hairline) solid var(--gray-6);
}
Use eased gradients over linear for smoother transitions:
/* Linear - visible banding */
background: linear-gradient(to bottom, black, transparent);
/* Eased - smoother */
background: linear-gradient(
to bottom,
hsl(0 0% 0% / 1) 0%,
hsl(0 0% 0% / 0.738) 19%,
hsl(0 0% 0% / 0.541) 34%,
hsl(0 0% 0% / 0.382) 47%,
hsl(0 0% 0% / 0.278) 56.5%,
hsl(0 0% 0% / 0.194) 65%,
hsl(0 0% 0% / 0.126) 73%,
hsl(0 0% 0% / 0.075) 80.2%,
hsl(0 0% 0% / 0.042) 86.1%,
hsl(0 0% 0% / 0.021) 91%,
hsl(0 0% 0% / 0.008) 95.2%,
hsl(0 0% 0% / 0.002) 98.2%,
transparent 100%
);
Tool: https://larsenwork.com/easing-gradients/
Prefer mask-image for fades - works better with varying content:
.fade-bottom {
mask-image: linear-gradient(to bottom, black 80%, transparent);
}
Only customize scrollbars in smaller elements, not page-level:
.code-block::-webkit-scrollbar {
width: 8px;
height: 8px;
}
.code-block::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.2);
border-radius: 4px;
}
Keep focus outline colors neutral (grey, black, white). Custom colors often clash.
Use a fixed scale, avoid arbitrary values:
:root {
--z-dropdown: 100;
--z-modal: 200;
--z-tooltip: 300;
--z-toast: 400;
}
Better approach: Avoid z-index when possible:
.card {
isolation: isolate; /* Creates new stacking context */
}
Account for device notches and home indicators:
.footer {
padding-bottom: env(safe-area-inset-bottom);
}
.sidebar {
padding-left: env(safe-area-inset-left);
}
Ensure proper space above anchored elements:
[id] {
scroll-margin-top: 80px; /* Height of sticky header */
}
Use hardcoded dimensions for dynamic elements:
// Skeleton loaders
<div className="h-[200px] w-full animate-pulse bg-gray-200" />
// Image placeholders
<div className="aspect-video relative">
<Image fill src={src} alt={alt} />
</div>
Truncate text in grid cells:
.grid-cell-text {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
Use numerical scale for easy theme switching:
:root {
--gray-1: #fafafa;
--gray-2: #f5f5f5;
--gray-3: #e5e5e5;
/* ... */
--gray-11: #262626;
--gray-12: #171717;
}
[data-theme="dark"] {
--gray-1: #171717;
--gray-2: #1f1f1f;
--gray-3: #262626;
/* ... */
--gray-11: #e5e5e5;
--gray-12: #fafafa;
}
Use CSS variables instead of manual dark mode overrides:
/* Good - variables flip automatically */
.button {
background: var(--gray-12);
color: var(--gray-1);
}
/* Avoid - manual dark mode everywhere */
.button {
@apply bg-gray-900 dark:bg-gray-100;
}
Benefits:
Decorative elements should not capture events:
.decorative-bg,
.gradient-overlay,
.noise-texture {
pointer-events: none;
}
Code illustrations should not be selectable:
.illustration {
user-select: none;
}
Ensure no flash of content on refresh:
// Store state in localStorage
const [theme, setTheme] = useState(() => {
if (typeof window !== 'undefined') {
return localStorage.getItem('theme') || 'light';
}
return 'light';
});
// Apply before render with script in <head>
<script dangerouslySetInnerHTML={{
__html: `
(function() {
const theme = localStorage.getItem('theme') || 'light';
document.documentElement.setAttribute('data-theme', theme);
})();
`
}} />
| Don't | Do Instead |
|---|---|
| Change font-weight on hover | Change color or opacity |
| Use linear gradients with solid colors | Use eased gradients |
| Apply fade to scrollable content | Let content scroll naturally |
| Replace page scrollbars | Only customize in small elements |
Use z-index: 9999 | Use a fixed z-index scale |
Use Tailwind dark: everywhere | Flip CSS variables |
| Custom colored focus outlines | Use grey/black/white outlines |
TYPOGRAPHY:
├── -webkit-font-smoothing: antialiased
├── font-variant-numeric: tabular-nums (for numbers)
├── text-wrap: balance (for headings)
└── Never change font-weight on hover
BORDERS:
├── box-shadow: 0 0 0 1px rgba(0,0,0,0.08) (instead of border)
└── --border-hairline: 0.5px (on retina)
LAYOUT:
├── env(safe-area-inset-*) for notches
├── scroll-margin-top for sticky headers
├── isolation: isolate (avoid z-index)
└── Hardcode dimensions for dynamic elements
DARK MODE:
├── Numerical color scale (gray-1 to gray-12)
├── Flip variables in [data-theme="dark"]
└── Avoid Tailwind dark: modifier
DECORATIVE:
├── pointer-events: none
└── user-select: none
Typography:
├── [ ] Antialiased font smoothing applied
├── [ ] Tabular nums for dynamic numbers
├── [ ] No font-weight changes on hover
└── [ ] Fonts properly subset
Visual:
├── [ ] Shadows used instead of borders where appropriate
├── [ ] Eased gradients for color transitions
├── [ ] Proper typographic characters (curly quotes, ellipsis)
└── [ ] Masks for fading content
Layout:
├── [ ] Z-index scale defined
├── [ ] Safe areas accounted for
├── [ ] Scroll margins set
└── [ ] No layout shift from dynamic content
Dark Mode:
├── [ ] CSS variable system for colors
├── [ ] Variables flip on theme change
├── [ ] No flash on refresh
└── [ ] Minimal use of dark: modifier