skills/i-harden/SKILL.md
Use when the user says: "production hardening", "handle edge cases in UI", "make it resilient", "improve onboarding", "empty states", "first-run experience". Improve interface resilience, error states, onboarding flows, and edge cases.
npx skillsauth add NodeJSmith/Claudefiles i-hardenInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Strengthen interfaces against edge cases, errors, internationalization issues, and real-world usage scenarios that break idealized designs.
Read ~/.claude/skills/i-frontend-design/SKILL.md for design principles, anti-patterns, and the Context Gathering Protocol. Follow the protocol before proceeding — if no design context exists yet, you MUST run /i-teach-impeccable first.
Identify weaknesses and edge cases:
Test with extreme inputs:
Test error scenarios:
Test internationalization:
CRITICAL: Designs that only work with perfect data aren't production-ready. Harden against reality.
After analyzing the current state, present your proposed changes to the user:
Then STOP and confirm before implementing:
AskUserQuestion:
question: "Here's what I propose. How would you like to proceed?"
header: "Confirm"
options:
- label: "Implement"
description: "Looks good — go ahead and make these changes."
- label: "Refine scope"
description: "I want to adjust what's included before you start."
- label: "Challenge this first"
description: "I'll run /mine.challenge against your proposal before we proceed."
- label: "Stop here"
description: "Don't implement anything. The proposal is in this conversation only."
If "Implement" → proceed to implementation below. If "Refine scope" → ask what to change, update proposal, re-confirm.
<!-- CHALLENGE-CALLER -->If "Challenge this first" → invoke /mine.challenge inline against the proposal, read findings, revise proposal, re-present this gate.
If "Stop here" → end the skill.
Systematically improve resilience:
Long text handling:
/* Single line with ellipsis */
.truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Multi-line with clamp */
.line-clamp {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
/* Allow wrapping */
.wrap {
word-wrap: break-word;
overflow-wrap: break-word;
hyphens: auto;
}
Flex/Grid overflow:
/* Prevent flex items from overflowing */
.flex-item {
min-width: 0; /* Allow shrinking below content size */
overflow: hidden;
}
/* Prevent grid items from overflowing */
.grid-item {
min-width: 0;
min-height: 0;
}
Responsive text sizing:
clamp() for fluid typographyText expansion:
// ❌ Bad: Assumes short English text
<button className="w-24">Submit</button>
// ✅ Good: Adapts to content
<button className="px-4 py-2">Submit</button>
RTL (Right-to-Left) support:
/* Use logical properties */
margin-inline-start: 1rem; /* Not margin-left */
padding-inline: 1rem; /* Not padding-left/right */
border-inline-end: 1px solid; /* Not border-right */
/* Or use dir attribute */
[dir="rtl"] .arrow { transform: scaleX(-1); }
Character set support:
Date/Time formatting:
// ✅ Use Intl API for proper formatting
new Intl.DateTimeFormat('en-US').format(date); // 1/15/2024
new Intl.DateTimeFormat('de-DE').format(date); // 15.1.2024
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(1234.56); // $1,234.56
Pluralization:
// ❌ Bad: Assumes English pluralization
`${count} item${count !== 1 ? 's' : ''}`
// ✅ Good: Use proper i18n library
t('items', { count }) // Handles complex plural rules
Network errors:
// Error states with recovery
{error && (
<ErrorMessage>
<p>Failed to load data. {error.message}</p>
<button onClick={retry}>Try again</button>
</ErrorMessage>
)}
Form validation errors:
API errors:
Graceful degradation:
Empty states:
Loading states:
Large datasets:
Concurrent operations:
Permission states:
Browser compatibility:
Production-ready features work for first-time users, not just power users. Design the paths that get new users to value:
Empty states: Every zero-data screen needs:
Empty state types to handle:
First-run experience: Get users to their "aha moment" as quickly as possible.
Feature discovery: Teach features when users need them, not upfront.
NEVER:
Client-side validation:
Server-side validation: Out of scope for UI hardening. Ensure your backend validates all inputs independently — never rely on client-side validation alone.
Constraint handling:
<!-- Set clear constraints -->
<input
type="text"
maxlength="100"
pattern="[A-Za-z0-9]+"
required
aria-describedby="username-hint"
/>
<small id="username-hint">
Letters and numbers only, up to 100 characters
</small>
Keyboard navigation:
Screen reader support:
Motion sensitivity:
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
High contrast mode:
Slow connections:
Memory leaks:
Throttling & Debouncing:
// Debounce search input
const debouncedSearch = debounce(handleSearch, 300);
// Throttle scroll handler
const throttledScroll = throttle(handleScroll, 100);
Manual testing:
Automated testing: Out of scope for UI hardening. For automated test coverage, consult your project's testing framework and conventions.
IMPORTANT: Hardening is about expecting the unexpected. Real users will do things you never imagined.
NEVER:
Test thoroughly with edge cases:
Remember: 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.
After implementation, summarize in conversation:
development
Use when the user says: "document how X works", "write up how this works", "durable explanation", "explain this for the docs", "document this subsystem". Writes a durable, architectural-altitude explanation that survives code churn.
development
Use when picking up a fresh session after /clear, a stop, or an unanswered AskUserQuestion. Reconstructs the prior session's intent from its transcript tail and surfaces any unresolved decision; user-invoked only — for a hand-written end-of-day handoff use /mine-good-morning instead.
development
Use when the user says: "what did we discuss", "continue where we left off", "remember when", "as I mentioned", "you suggested", "we decided", "search my conversations", "find the conversation where", "what did we work on", or uses implicit signals like past-tense references, possessives without context, or assumptive questions. Direct search over past Claude Code sessions via cass.
tools
Use when the user says: "what context do I have", "relevant history for this task", "what have we done related to this". Also usable proactively when starting work that likely has prior history. Assembles a structured context brief from past session history via cass, scoped to the current task and workspace.