$npx -y skills add dylantarre/design-system-skills --skill radius-scaleGenerates border-radius tokens from sharp to pill shapes. Use when creating corner rounding systems, button radius, card corners, or input styling. Outputs CSS, Tailwind, or JSON.
| 1 | # Radius Scale Generator |
| 2 | |
| 3 | ## Overview |
| 4 | |
| 5 | Generate consistent border-radius scales from sharp to pill-shaped. Creates harmonious rounding that scales appropriately with element size for visual consistency. |
| 6 | |
| 7 | ## When to Use |
| 8 | |
| 9 | - Setting up radius tokens for a new project |
| 10 | - Standardizing corner rounding across components |
| 11 | - Creating button/card/input styling consistency |
| 12 | - Building component-size-aware radius systems |
| 13 | |
| 14 | ## Quick Reference |
| 15 | |
| 16 | | Level | Typical Value | Use Case | |
| 17 | |-------|---------------|----------| |
| 18 | | none | 0 | Sharp corners, tables | |
| 19 | | sm | 2-4px | Subtle rounding, inputs | |
| 20 | | md | 6-8px | Buttons, cards | |
| 21 | | lg | 12-16px | Modals, large cards | |
| 22 | | xl | 20-24px | Panels, containers | |
| 23 | | 2xl | 32px+ | Feature sections | |
| 24 | | full | 9999px | Pills, avatars, badges | |
| 25 | |
| 26 | ## The Process |
| 27 | |
| 28 | 1. **Get base radius**: Default 8px (balanced starting point) |
| 29 | 2. **Get ratio**: How much each step grows (1.5-2 typical) |
| 30 | 3. **Ask steps**: How many radius values (5-7 typical) |
| 31 | 4. **Ask unit**: px or rem? |
| 32 | 5. **Ask format**: CSS, Tailwind, or JSON? |
| 33 | 6. **Include full?**: Add "full" (9999px) for pills? (default: yes) |
| 34 | 7. **Generate**: Create scale centered on base |
| 35 | |
| 36 | ## Common Scales |
| 37 | |
| 38 | | Character | Base | Ratio | Result | |
| 39 | |-----------|------|-------|--------| |
| 40 | | Subtle | 4px | 1.5 | 2, 3, 4, 6, 9, 13 | |
| 41 | | Balanced | 8px | 2 | 2, 4, 8, 16, 32 | |
| 42 | | Rounded | 12px | 1.5 | 5, 8, 12, 18, 27, 40 | |
| 43 | | Soft | 16px | 1.5 | 7, 11, 16, 24, 36, 54 | |
| 44 | |
| 45 | ## Output Formats |
| 46 | |
| 47 | **CSS Custom Properties:** |
| 48 | ```css |
| 49 | :root { |
| 50 | --radius-none: 0; |
| 51 | --radius-sm: 4px; |
| 52 | --radius-md: 8px; |
| 53 | --radius-lg: 16px; |
| 54 | --radius-xl: 24px; |
| 55 | --radius-2xl: 32px; |
| 56 | --radius-full: 9999px; |
| 57 | } |
| 58 | ``` |
| 59 | |
| 60 | **Tailwind Config:** |
| 61 | ```js |
| 62 | module.exports = { |
| 63 | theme: { |
| 64 | borderRadius: { |
| 65 | 'none': '0', |
| 66 | 'sm': '4px', |
| 67 | 'md': '8px', |
| 68 | 'lg': '16px', |
| 69 | 'xl': '24px', |
| 70 | '2xl': '32px', |
| 71 | 'full': '9999px', |
| 72 | } |
| 73 | } |
| 74 | } |
| 75 | ``` |
| 76 | |
| 77 | **JSON Tokens:** |
| 78 | ```json |
| 79 | { |
| 80 | "radius": { |
| 81 | "none": { "value": "0" }, |
| 82 | "sm": { "value": "4px" }, |
| 83 | "md": { "value": "8px" }, |
| 84 | "lg": { "value": "16px" }, |
| 85 | "xl": { "value": "24px" }, |
| 86 | "2xl": { "value": "32px" }, |
| 87 | "full": { "value": "9999px" } |
| 88 | } |
| 89 | } |
| 90 | ``` |
| 91 | |
| 92 | ## Contextual Radius |
| 93 | |
| 94 | Larger elements often need proportionally larger radius. Consider semantic tokens: |
| 95 | |
| 96 | **CSS with contextual tokens:** |
| 97 | ```css |
| 98 | :root { |
| 99 | /* Base scale */ |
| 100 | --radius-sm: 4px; |
| 101 | --radius-md: 8px; |
| 102 | --radius-lg: 16px; |
| 103 | |
| 104 | /* Semantic/contextual */ |
| 105 | --radius-button: var(--radius-md); |
| 106 | --radius-input: var(--radius-sm); |
| 107 | --radius-card: var(--radius-lg); |
| 108 | --radius-modal: var(--radius-xl); |
| 109 | --radius-badge: var(--radius-full); |
| 110 | --radius-avatar: var(--radius-full); |
| 111 | } |
| 112 | ``` |
| 113 | |
| 114 | ## Algorithm |
| 115 | |
| 116 | The scale uses exponential growth from a base: |
| 117 | |
| 118 | ``` |
| 119 | value = baseValue * (ratio ^ (step - midpoint)) |
| 120 | ``` |
| 121 | |
| 122 | For a 7-step scale with base 8px and ratio 2: |
| 123 | - Step 0 (3 below): 8 * 2^-3 = 1px |
| 124 | - Step 3 (mid): 8 * 2^0 = 8px |
| 125 | - Step 6 (3 above): 8 * 2^3 = 64px |
| 126 | |
| 127 | Values are typically rounded to clean numbers. |
| 128 | |
| 129 | ## Design Considerations |
| 130 | |
| 131 | **Consistency rule**: Inner radius = outer radius - border/padding |
| 132 | |
| 133 | ```css |
| 134 | /* Card with nested element */ |
| 135 | .card { |
| 136 | border-radius: var(--radius-lg); /* 16px */ |
| 137 | padding: 8px; |
| 138 | } |
| 139 | .card-inner { |
| 140 | border-radius: calc(var(--radius-lg) - 8px); /* 8px */ |
| 141 | } |
| 142 | ``` |
| 143 | |
| 144 | **Squircle alternative**: For iOS-style continuous curves, consider `mask-image` with SVG or libraries like `squircle.js`. |
| 145 | |
| 146 | ## Common Patterns |
| 147 | |
| 148 | | Component | Recommended Radius | |
| 149 | |-----------|-------------------| |
| 150 | | Icon buttons | sm or md | |
| 151 | | Text buttons | md | |
| 152 | | Input fields | sm or md | |
| 153 | | Cards | lg | |
| 154 | | Modals/dialogs | lg or xl | |
| 155 | | Tooltips | md | |
| 156 | | Badges/tags | full (pill) | |
| 157 | | Avatars | full (circle) | |
| 158 | | Containers | xl or 2xl | |