SKILL.md

  1---
  2name: harden
  3description: "Make interfaces production-ready: error handling, empty states, onboarding flows, i18n, text overflow, and edge case management. Use when the user asks to harden, make production-ready, handle edge cases, add error states, design empty states, improve onboarding, or fix overflow and i18n issues."
  4argument-hint: "[target]"
  5user-invocable: true
  6---
  7
  8Strengthen interfaces against edge cases, errors, internationalization issues, and real-world usage scenarios that break idealized designs.
  9
 10## Assess Hardening Needs
 11
 12Identify weaknesses and edge cases:
 13
 141. **Test with extreme inputs**:
 15   - Very long text (names, descriptions, titles)
 16   - Very short text (empty, single character)
 17   - Special characters (emoji, RTL text, accents)
 18   - Large numbers (millions, billions)
 19   - Many items (1000+ list items, 50+ options)
 20   - No data (empty states)
 21
 222. **Test error scenarios**:
 23   - Network failures (offline, slow, timeout)
 24   - API errors (400, 401, 403, 404, 500)
 25   - Validation errors
 26   - Permission errors
 27   - Rate limiting
 28   - Concurrent operations
 29
 303. **Test internationalization**:
 31   - Long translations (German is often 30% longer than English)
 32   - RTL languages (Arabic, Hebrew)
 33   - Character sets (Chinese, Japanese, Korean, emoji)
 34   - Date/time formats
 35   - Number formats (1,000 vs 1.000)
 36   - Currency symbols
 37
 38**CRITICAL**: Designs that only work with perfect data aren't production-ready. Harden against reality.
 39
 40## Hardening Dimensions
 41
 42Systematically improve resilience:
 43
 44### Text Overflow & Wrapping
 45
 46**Long text handling**:
 47```css
 48/* Single line with ellipsis */
 49.truncate {
 50  overflow: hidden;
 51  text-overflow: ellipsis;
 52  white-space: nowrap;
 53}
 54
 55/* Multi-line with clamp */
 56.line-clamp {
 57  display: -webkit-box;
 58  -webkit-line-clamp: 3;
 59  -webkit-box-orient: vertical;
 60  overflow: hidden;
 61}
 62
 63/* Allow wrapping */
 64.wrap {
 65  word-wrap: break-word;
 66  overflow-wrap: break-word;
 67  hyphens: auto;
 68}
 69```
 70
 71**Flex/Grid overflow**:
 72```css
 73/* Prevent flex items from overflowing */
 74.flex-item {
 75  min-width: 0; /* Allow shrinking below content size */
 76  overflow: hidden;
 77}
 78
 79/* Prevent grid items from overflowing */
 80.grid-item {
 81  min-width: 0;
 82  min-height: 0;
 83}
 84```
 85
 86**Responsive text sizing**:
 87- Use `clamp()` for fluid typography
 88- Set minimum readable sizes (14px on mobile)
 89- Test text scaling (zoom to 200%)
 90- Ensure containers expand with text
 91
 92### Internationalization (i18n)
 93
 94**Text expansion**:
 95- Add 30-40% space budget for translations
 96- Use flexbox/grid that adapts to content
 97- Test with longest language (usually German)
 98- Avoid fixed widths on text containers
 99
100```jsx
101// ❌ Bad: Assumes short English text
102<button className="w-24">Submit</button>
103
104// ✅ Good: Adapts to content
105<button className="px-4 py-2">Submit</button>
106```
107
108**RTL (Right-to-Left) support**:
109```css
110/* Use logical properties */
111margin-inline-start: 1rem; /* Not margin-left */
112padding-inline: 1rem; /* Not padding-left/right */
113border-inline-end: 1px solid; /* Not border-right */
114
115/* Or use dir attribute */
116[dir="rtl"] .arrow { transform: scaleX(-1); }
117```
118
119**Character set support**:
120- Use UTF-8 encoding everywhere
121- Test with Chinese/Japanese/Korean (CJK) characters
122- Test with emoji (they can be 2-4 bytes)
123- Handle different scripts (Latin, Cyrillic, Arabic, etc.)
124
125**Date/Time formatting**:
126```javascript
127// ✅ Use Intl API for proper formatting
128new Intl.DateTimeFormat('en-US').format(date); // 1/15/2024
129new Intl.DateTimeFormat('de-DE').format(date); // 15.1.2024
130
131new Intl.NumberFormat('en-US', { 
132  style: 'currency', 
133  currency: 'USD' 
134}).format(1234.56); // $1,234.56
135```
136
137**Pluralization**:
138```javascript
139// ❌ Bad: Assumes English pluralization
140`${count} item${count !== 1 ? 's' : ''}`
141
142// ✅ Good: Use proper i18n library
143t('items', { count }) // Handles complex plural rules
144```
145
146### Error Handling
147
148**Network errors**:
149- Show clear error messages
150- Provide retry button
151- Explain what happened
152- Offer offline mode (if applicable)
153- Handle timeout scenarios
154
155```jsx
156// Error states with recovery
157{error && (
158  <ErrorMessage>
159    <p>Failed to load data. {error.message}</p>
160    <button onClick={retry}>Try again</button>
161  </ErrorMessage>
162)}
163```
164
165**Form validation errors**:
166- Inline errors near fields
167- Clear, specific messages
168- Suggest corrections
169- Don't block submission unnecessarily
170- Preserve user input on error
171
172**API errors**:
173- Handle each status code appropriately
174  - 400: Show validation errors
175  - 401: Redirect to login
176  - 403: Show permission error
177  - 404: Show not found state
178  - 429: Show rate limit message
179  - 500: Show generic error, offer support
180
181**Graceful degradation**:
182- Core functionality works without JavaScript
183- Images have alt text
184- Progressive enhancement
185- Fallbacks for unsupported features
186
187### Edge Cases & Boundary Conditions
188
189**Empty states**:
190- No items in list
191- No search results
192- No notifications
193- No data to display
194- Provide clear next action
195
196**Loading states**:
197- Initial load
198- Pagination load
199- Refresh
200- Show what's loading ("Loading your projects...")
201- Time estimates for long operations
202
203**Large datasets**:
204- Pagination or virtual scrolling
205- Search/filter capabilities
206- Performance optimization
207- Don't load all 10,000 items at once
208
209**Concurrent operations**:
210- Prevent double-submission (disable button while loading)
211- Handle race conditions
212- Optimistic updates with rollback
213- Conflict resolution
214
215**Permission states**:
216- No permission to view
217- No permission to edit
218- Read-only mode
219- Clear explanation of why
220
221**Browser compatibility**:
222- Polyfills for modern features
223- Fallbacks for unsupported CSS
224- Feature detection (not browser detection)
225- Test in target browsers
226
227### Onboarding & First-Run Experience
228
229Production-ready features work for first-time users, not just power users. Design the paths that get new users to value:
230
231**Empty states**: Every zero-data screen needs:
232- What will appear here (description or illustration)
233- Why it matters to the user
234- Clear CTA to create the first item or start from a template
235- Visual interest (not just blank space with "No items yet")
236
237Empty state types to handle:
238- **First use**: emphasize value, provide templates
239- **User cleared**: light touch, easy to recreate
240- **No results**: suggest a different query, offer to clear filters
241- **No permissions**: explain why, how to get access
242
243**First-run experience**: Get users to their "aha moment" as quickly as possible.
244- Show, don't tell -- working examples over descriptions
245- Progressive disclosure -- teach one thing at a time, not everything upfront
246- Make onboarding optional -- let experienced users skip
247- Provide smart defaults so required setup is minimal
248
249**Feature discovery**: Teach features when users need them, not upfront.
250- Contextual tooltips at point of use (brief, dismissable, one-time)
251- Badges or indicators on new or unused features
252- Celebrate activation events quietly (a toast, not a modal)
253
254**NEVER**:
255- Force long onboarding before users can touch the product
256- Show the same tooltip repeatedly (track and respect dismissals)
257- Block the entire UI during a guided tour
258- Create separate tutorial modes disconnected from the real product
259- Design empty states that just say "No items" with no next action
260
261### Input Validation & Sanitization
262
263**Client-side validation**:
264- Required fields
265- Format validation (email, phone, URL)
266- Length limits
267- Pattern matching
268- Custom validation rules
269
270**Server-side validation** (always):
271- Never trust client-side only
272- Validate and sanitize all inputs
273- Protect against injection attacks
274- Rate limiting
275
276**Constraint handling**:
277```html
278<!-- Set clear constraints -->
279<input 
280  type="text"
281  maxlength="100"
282  pattern="[A-Za-z0-9]+"
283  required
284  aria-describedby="username-hint"
285/>
286<small id="username-hint">
287  Letters and numbers only, up to 100 characters
288</small>
289```
290
291### Accessibility Resilience
292
293**Keyboard navigation**:
294- All functionality accessible via keyboard
295- Logical tab order
296- Focus management in modals
297- Skip links for long content
298
299**Screen reader support**:
300- Proper ARIA labels
301- Announce dynamic changes (live regions)
302- Descriptive alt text
303- Semantic HTML
304
305**Motion sensitivity**:
306```css
307@media (prefers-reduced-motion: reduce) {
308  * {
309    animation-duration: 0.01ms !important;
310    animation-iteration-count: 1 !important;
311    transition-duration: 0.01ms !important;
312  }
313}
314```
315
316**High contrast mode**:
317- Test in Windows high contrast mode
318- Don't rely only on color
319- Provide alternative visual cues
320
321### Performance Resilience
322
323**Slow connections**:
324- Progressive image loading
325- Skeleton screens
326- Optimistic UI updates
327- Offline support (service workers)
328
329**Memory leaks**:
330- Clean up event listeners
331- Cancel subscriptions
332- Clear timers/intervals
333- Abort pending requests on unmount
334
335**Throttling & Debouncing**:
336```javascript
337// Debounce search input
338const debouncedSearch = debounce(handleSearch, 300);
339
340// Throttle scroll handler
341const throttledScroll = throttle(handleScroll, 100);
342```
343
344## Testing Strategies
345
346**Manual testing**:
347- Test with extreme data (very long, very short, empty)
348- Test in different languages
349- Test offline
350- Test slow connection (throttle to 3G)
351- Test with screen reader
352- Test keyboard-only navigation
353- Test on old browsers
354
355**Automated testing**:
356- Unit tests for edge cases
357- Integration tests for error scenarios
358- E2E tests for critical paths
359- Visual regression tests
360- Accessibility tests (axe, WAVE)
361
362**IMPORTANT**: Hardening is about expecting the unexpected. Real users will do things you never imagined.
363
364**NEVER**:
365- Assume perfect input (validate everything)
366- Ignore internationalization (design for global)
367- Leave error messages generic ("Error occurred")
368- Forget offline scenarios
369- Trust client-side validation alone
370- Use fixed widths for text
371- Assume English-length text
372- Block entire interface when one component errors
373
374## Verify Hardening
375
376Test thoroughly with edge cases:
377
378- **Long text**: Try names with 100+ characters
379- **Emoji**: Use emoji in all text fields
380- **RTL**: Test with Arabic or Hebrew
381- **CJK**: Test with Chinese/Japanese/Korean
382- **Network issues**: Disable internet, throttle connection
383- **Large datasets**: Test with 1000+ items
384- **Concurrent actions**: Click submit 10 times rapidly
385- **Errors**: Force API errors, test all error states
386- **Empty**: Remove all data, test empty states
387
388Remember: You're hardening for production reality, not demo perfection. Expect users to input weird data, lose connection mid-flow, and use your product in unexpected ways. Build resilience into every component.
389