Visual Design Foundations by @wshobson · Skillet
Visual Design Foundations Apply typography, color theory, spacing systems, and iconography principles to create cohesive visual designs. Use when establishing design tokens, building style guides, or improving visual hierarchy and consistency.
Just instructions. No commands, network, or file access.
Install
It’s free, and every skill you add syncs into every AI tool on your computer, instantly.
:root {
--space-1 : 0.25rem ;
--space-2 : 0.5rem ;
--space-3 : 0.75rem ;
--space-4 : 1rem ;
--space-5 : 1.25rem ;
--space-6 : 1.5rem ;
--space-8 : 2rem ;
--space-10 : 2.5rem ;
--space-12 : 3rem ;
--space-16 : 4rem ;
}
3. Color System :root {
--color-primary : #2563eb ;
--color-primary-hover : #1d4ed8 ;
--color-primary-active : #1e40af ;
--color-success : #16a34a ;
--color-warning : #ca8a04 ;
--color-error : #dc2626 ;
--color-info : #0891b2 ;
--color-gray-50 : #f9fafb ;
--color-gray-100 : #f3f4f6 ;
--color-gray-200 : #e5e7eb ;
--color-gray-300 : #d1d5db ;
--color-gray-400 : #9ca3af ;
--color-gray-500 : #6b7280 ;
--color-gray-600 : #4b5563 ;
--color-gray-700 : #374151 ;
--color-gray-800 : #1f2937 ;
--color-gray-900 : #111827 ;
}
Quick Start: Design Tokens in Tailwind
module .exports = {
theme : {
extend : {
fontFamily : {
sans : ["Inter" , "system-ui" , "sans-serif" ],
mono : ["JetBrains Mono" , "monospace" ],
},
fontSize : {
xs : ["0.75rem" , { lineHeight : "1rem" }],
sm : ["0.875rem" , { lineHeight : "1.25rem" }],
base : ["1rem" , { lineHeight : "1.5rem" }],
lg : ["1.125rem" , { lineHeight : "1.75rem" }],
xl : ["1.25rem" , { lineHeight : "1.75rem" }],
"2xl" : ["1.5rem" , { lineHeight : "2rem" }],
},
colors : {
brand : {
50 : "#eff6ff" ,
500 : "#3b82f6" ,
600 : "#2563eb" ,
700 : "#1d4ed8" ,
},
},
spacing : {
18 : "4.5rem" ,
88 : "22rem" ,
},
},
},
};
Typography Best Practices
Font Pairing
Heading: Inter / Body: Inter (single family)
Heading: Playfair Display / Body: Source Sans Pro (contrast)
Heading: Space Grotesk / Body: IBM Plex Sans (geometric)
Responsive Typography
h1 {
font-size : clamp (2rem , 5vw + 1rem , 3.5rem );
line-height : 1.1 ;
}
p {
font-size : clamp (1rem , 2vw + 0.5rem , 1.125rem );
line-height : 1.6 ;
max-width : 65ch ;
}
Font Loading
@font-face {
font-family : "Inter" ;
src : url ("/fonts/Inter.woff2" ) format ("woff2" );
font-display : swap;
font-weight : 400 700 ;
}
Color Theory
Contrast Requirements (WCAG) Element Minimum Ratio Body text 4.5:1 (AA) Large text (18px+) 3:1 (AA) UI components 3:1 (AA) Enhanced 7:1 (AAA)
Dark Mode Strategy :root {
--bg-primary : #ffffff ;
--bg-secondary : #f9fafb ;
--text-primary : #111827 ;
--text-secondary : #6b7280 ;
--border : #e5e7eb ;
}
[data-theme="dark" ] {
--bg-primary : #111827 ;
--bg-secondary : #1f2937 ;
--text-primary : #f9fafb ;
--text-secondary : #9ca3af ;
--border : #374151 ;
}
Color Accessibility
function getContrastRatio (foreground : string , background : string ): number {
const getLuminance = (hex : string ) => {
const rgb = hexToRgb (hex);
const [r, g, b] = rgb.map ((c ) => {
c = c / 255 ;
return c <= 0.03928 ? c / 12.92 : Math .pow ((c + 0.055 ) / 1.055 , 2.4 );
});
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
};
const l1 = getLuminance (foreground);
const l2 = getLuminance (background);
const lighter = Math .max (l1, l2);
const darker = Math .min (l1, l2);
return (lighter + 0.05 ) / (darker + 0.05 );
}
Spacing Guidelines
Component Spacing Card padding: 16-24px (--space-4 to --space-6)
Section gap: 32-64px (--space-8 to --space-16)
Form field gap: 16-24px (--space-4 to --space-6)
Button padding: 8-16px vertical, 16-24px horizontal
Icon-text gap: 8px (--space-2)
Visual Rhythm
.prose > * + * {
margin-top : var (--space-4 );
}
.prose > h2 + * {
margin-top : var (--space-2 );
}
.prose > * + h2 {
margin-top : var (--space-8 );
}
Iconography
Icon Sizing System :root {
--icon-xs : 12px ;
--icon-sm : 16px ;
--icon-md : 20px ;
--icon-lg : 24px ;
--icon-xl : 32px ;
}
Icon Component interface IconProps {
name : string ;
size ?: "xs" | "sm" | "md" | "lg" | "xl" ;
className ?: string ;
}
const sizeMap = {
xs : 12 ,
sm : 16 ,
md : 20 ,
lg : 24 ,
xl : 32 ,
};
export function Icon ({ name, size = "md" , className }: IconProps ) {
return (
<svg
width ={sizeMap[size]}
height ={sizeMap[size]}
className ={cn( "inline-block flex-shrink-0 ", className )}
aria-hidden ="true"
>
<use href ={ `/icons.svg #${name }`} />
</svg >
);
}
Best Practices
Establish Constraints : Limit choices to maintain consistency
Document Decisions : Create a living style guide
Test Accessibility : Verify contrast, sizing, touch targets
Use Semantic Tokens : Name by purpose, not appearance
Design Mobile-First : Start with constraints, add complexity
Maintain Vertical Rhythm : Consistent spacing creates harmony
Limit Font Weights : 2-3 weights per family is sufficient
Common Issues
Inconsistent Spacing : Not using a defined scale
Poor Contrast : Failing WCAG requirements
Font Overload : Too many families or weights
Magic Numbers : Arbitrary values instead of tokens
Missing States : Forgetting hover, focus, disabled
No Dark Mode Plan : Retrofitting is harder than planning
~2.3K tokens