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