RadFlow Compliance Audit
This skill audits code for RadOS design system compliance. Use it to catch and fix common AI-generated mistakes before they ship.
When to Use
- •After generating new UI code
- •When reviewing pull requests
- •When refactoring existing components
- •When onboarding code from other projects
HARD RULES (Never Break These)
These rules are absolute and must never be violated. Claude must self-audit code before submitting.
Rule 1: NEVER use raw <button> elements
// ❌ FORBIDDEN - Always use Button component
<button onClick={...} className="...">Click</button>
// ✅ REQUIRED
import { Button } from '@radflow/ui';
<Button onClick={...} variant="outline">Click</Button>
Rule 2: NEVER use raw brand color names in className
// ❌ FORBIDDEN - Direct brand color references bg-sky-blue text-sky-blue bg-sun-yellow text-sun-yellow bg-sun-red text-sun-red bg-warm-cloud bg-cream hover:bg-sun-yellow // ✅ REQUIRED - Use semantic tokens only bg-surface-primary // instead of bg-warm-cloud, bg-cream bg-surface-secondary // instead of bg-black bg-surface-tertiary // instead of bg-sun-yellow text-content-primary // instead of text-black text-content-secondary // instead of text-sun-yellow border-edge-primary // instead of border-black border-edge-focus // instead of border-sky-blue
Rule 3: NEVER hardcode hex values in TypeScript/TSX
// ❌ FORBIDDEN value: '#888888' color: '#FCE184' backgroundColor: '#0F0E0C' // ✅ REQUIRED - Use CSS variables or semantic tokens // If you need a fallback color, use a semantic token reference value: 'var(--color-content-tertiary)' // Or reference from the design system const color = baseColors.find(c => c.name === 'black')?.value
Rule 4: NEVER use opacity on brand colors, only on semantic tokens
// ❌ FORBIDDEN bg-sky-blue/20 text-sun-yellow/50 border-sun-red/30 // ✅ REQUIRED - Opacity only on semantic tokens bg-surface-tertiary/20 text-content-primary/50 border-edge-primary/30
Rule 5: ALWAYS include full interaction states on clickable elements
// ❌ FORBIDDEN - Partial interaction states <button className="hover:bg-surface-secondary"> // ✅ REQUIRED - Full interaction state set <Button variant="outline" /> // Or if custom element is absolutely necessary: className=" shadow-btn hover:-translate-y-0.5 hover:shadow-btn-hover active:translate-y-0.5 active:shadow-none focus:ring-2 focus:ring-edge-focus focus:ring-offset-2 transition-all duration-200 "
Rule 6: ALWAYS specify font family for headings and labels
// ❌ FORBIDDEN - Relying on inherited fonts <h3 className="text-lg font-semibold">Title</h3> // ✅ REQUIRED - Explicit font family <h3 className="text-lg font-semibold font-joystix">Title</h3> // Or use semantic HTML elements which have @layer base styles
Rule 7: NEVER create category/status badges with raw colors
// ❌ FORBIDDEN - Color-coded badges with brand colors
const getBadgeColor = (type) => {
switch(type) {
case 'success': return 'bg-green/20 text-green';
case 'warning': return 'bg-sun-yellow/20 text-sun-yellow';
}
}
// ✅ REQUIRED - Use semantic status tokens
const getBadgeColor = (type) => {
switch(type) {
case 'success': return 'bg-surface-success text-content-success';
case 'warning': return 'bg-surface-warning text-content-warning';
case 'error': return 'bg-surface-error text-content-error';
default: return 'bg-surface-secondary text-content-primary';
}
}
Rule 8: ALWAYS use Button component for any clickable action
// ❌ FORBIDDEN - Any of these patterns
<button>...</button>
<div onClick={...}>...</div>
<span onClick={...} className="cursor-pointer">...</span>
// ✅ REQUIRED
<Button variant="primary|secondary|outline|ghost" size="sm|md|lg">
Audit Categories
1. Component Duplication Check
Problem: AI often creates new components instead of using existing ones.
# Check what components exist ls -la /components/ui/
Common duplicates to catch:
| If you see... | Use instead |
|---|---|
MyButton, CustomButton, StyledButton | <Button> from /components/ui/Button |
MyCard, Container, Box | <Card> from /components/ui/Card |
MyInput, TextField, TextInput | <Input> from /components/ui/Input |
MyModal, Popup, Overlay | <Dialog> from /components/ui/Dialog |
Wrapper, Layout | Check if <Card> or semantic HTML works |
Fix pattern:
// Before (wrong)
function MyCustomCard({ children }) {
return <div className="bg-white rounded-lg shadow-md p-4">{children}</div>
}
// After (correct)
import Card from '@/components/ui/Card';
// Just use <Card>{children}</Card>
2. Shadow Compliance
Problem: AI defaults to Tailwind's blurred shadows.
Find violations:
// Search for these patterns: shadow-sm shadow-md shadow-lg shadow-xl shadow-2xl box-shadow:.*blur box-shadow:.*rgba.*\d+px // blur radius present
Correct shadows:
shadow-btn // 0 1px 0 0 black (buttons resting) shadow-btn-hover // 0 3px 0 0 black (buttons hover) shadow-card // 2px 2px 0 0 black (cards) shadow-card-lg // 4px 4px 0 0 black (elevated cards) shadow-card-hover // 6px 6px 0 0 black (card hover) shadow-none // remove shadow (active state)
Fix pattern:
// Before (wrong)
<div className="shadow-lg">
<div style={{ boxShadow: '0 4px 6px rgba(0,0,0,0.1)' }}>
// After (correct)
<div className="shadow-card">
3. Color Token Compliance
Problem: AI hardcodes colors instead of using semantic tokens.
Find violations:
// Search for these patterns: bg-\[# text-\[# border-\[# bg-yellow- bg-gray- text-gray- border-gray- #FCE184 #FEF8E2 #0F0E0C rgb\( rgba\(
Correct tokens:
| Wrong | Correct |
|---|---|
bg-[#FCE184], bg-yellow-400 | bg-surface-tertiary |
bg-[#FEF8E2], bg-white | bg-surface-primary or bg-surface-elevated |
bg-[#0F0E0C], bg-black | bg-surface-secondary |
text-[#0F0E0C], text-gray-900 | text-content-primary |
text-gray-500, text-gray-600 | text-content-primary/50 (use opacity) |
border-gray-300 | border-edge-primary |
border-blue-500 | border-edge-focus |
Fix pattern:
// Before (wrong) <button className="bg-[#FCE184] text-[#0F0E0C] border-gray-300"> // After (correct) <button className="bg-surface-tertiary text-content-primary border-edge-primary">
4. Border Radius Hierarchy
Problem: AI uses same radius everywhere regardless of nesting.
The rule: Each nesting level = parent radius ÷ 2
| Nesting Level | Radius | Class |
|---|---|---|
| Level 0 (Window/Modal) | 16px | rounded-lg |
| Level 1 (Card/Section) | 8px | rounded-md |
| Level 2 (Button/Input) | 4px | rounded-sm |
| Level 3 (Badge/Tag) | 2px | rounded-xs |
Find violations:
// Check for same radius at multiple nesting levels
// Example of WRONG pattern:
<Modal className="rounded-lg"> // Level 0: OK
<Card className="rounded-lg"> // Level 1: WRONG (should be rounded-md)
<Button className="rounded-lg"> // Level 2: WRONG (should be rounded-sm)
Fix pattern:
// Before (wrong - same radius everywhere)
<Dialog className="rounded-lg">
<div className="rounded-lg p-4">
<Button className="rounded-lg">Save</Button>
</div>
</Dialog>
// After (correct - cascading radius)
<Dialog className="rounded-lg">
<div className="rounded-md p-4">
<Button className="rounded-sm">Save</Button>
</div>
</Dialog>
5. Interaction States
Problem: AI forgets hover/active/focus states.
Required states for interactive elements:
// Buttons MUST have: hover:-translate-y-0.5 // lift up hover:shadow-btn-hover // deeper shadow active:translate-y-0.5 // press down active:shadow-none // no shadow when pressed focus:ring-2 // focus ring focus:ring-edge-focus // blue ring color focus:ring-offset-2 // ring offset transition-all // smooth transitions duration-200 // animation timing
Find violations:
// Search for buttons/links missing these:
<button className="..." // check for hover/active/focus
<a className="..." // check for hover states
onClick={ // interactive element needs states
Fix pattern:
// Before (wrong - no interaction states) <button className="bg-surface-tertiary border border-edge-primary rounded-sm"> // After (correct - full interaction) <button className="bg-surface-tertiary border border-edge-primary rounded-sm shadow-btn hover:-translate-y-0.5 hover:shadow-btn-hover active:translate-y-0.5 active:shadow-none focus:ring-2 focus:ring-edge-focus focus:ring-offset-2 transition-all duration-200">
6. Typography
Problem: AI uses wrong fonts or generic system fonts.
Find violations:
// Search for these patterns: font-sans font-serif font-inter font-arial font-roboto font-system
Correct fonts:
| Usage | Font | Class |
|---|---|---|
| Headings, labels, buttons | Joystix | font-joystix |
| Body text, paragraphs | Mondwest | font-mondwest |
| Code, technical | PixelCode | font-mono |
7. Gray Color Usage
Problem: AI uses gray hex values instead of black with opacity.
Rule: RadOS has NO gray. Use black at reduced opacity.
Find violations:
// Search for gray patterns:
gray-100
gray-200
gray-300
gray-400
gray-500
gray-600
gray-700
gray-800
gray-900
#[0-9a-fA-F]{6} // check if it's a gray hex
Fix pattern:
// Before (wrong) <p className="text-gray-500">Muted text</p> <div className="border-gray-300"> // After (correct) <p className="text-content-primary/50">Muted text</p> <div className="border-edge-primary/20">
8. Animation Timing
Problem: AI uses wrong easing or duration.
Find violations:
// Search for these patterns: ease-bounce ease-in-out duration-500 duration-700 duration-1000 animate-bounce spring
Correct values:
- •Easing:
ease-outonly - •Duration: 150ms (fades), 200ms (transforms), 300ms max
- •No bounce, no spring physics
Quick Audit Commands
Run these grep patterns to find violations:
# Shadow violations grep -rn "shadow-sm\|shadow-md\|shadow-lg\|shadow-xl" --include="*.tsx" # Hardcoded colors grep -rn "bg-\[#\|text-\[#\|border-\[#" --include="*.tsx" grep -rn "bg-gray-\|text-gray-\|border-gray-" --include="*.tsx" # Wrong fonts grep -rn "font-sans\|font-inter\|font-roboto" --include="*.tsx" # Missing interaction states (buttons without hover) grep -rn "<button" --include="*.tsx" | grep -v "hover:" # Gradient usage (not allowed) grep -rn "bg-gradient\|from-\|to-" --include="*.tsx"
Compliance Checklist
After auditing, verify:
- • No custom components that duplicate existing UI primitives
- • All shadows use RadOS tokens (shadow-btn, shadow-card, etc.)
- • No hardcoded hex colors or Tailwind color palette
- • Border radius follows nesting hierarchy (16→8→4→2)
- • All interactive elements have hover/active/focus states
- • Typography uses Joystix/Mondwest/PixelCode
- • No gray colors (use black with opacity)
- • Animations use ease-out, ≤300ms
- • No gradients
- • Works in both light and dark mode
Auto-Fix Suggestions
When you find violations, suggest these replacements:
| Find | Replace With |
|---|---|
shadow-md, shadow-lg | shadow-card |
shadow-sm | shadow-btn |
bg-white | bg-surface-elevated |
bg-gray-100 | bg-surface-primary |
bg-yellow-* | bg-surface-tertiary |
text-gray-* | text-content-primary + opacity |
border-gray-* | border-edge-primary + opacity |
rounded-lg (on buttons) | rounded-sm |
rounded-lg (on cards inside modals) | rounded-md |
font-sans | font-joystix or font-mondwest |
Report Format
After auditing, provide a summary:
## RadOS Compliance Report ### Summary - ✅ Passed: X checks - ⚠️ Warnings: X issues - ❌ Violations: X issues ### Violations Found 1. **Shadow Compliance** (X issues) - Line 42: `shadow-lg` → should be `shadow-card` - Line 87: `shadow-md` → should be `shadow-btn` 2. **Color Tokens** (X issues) - Line 23: `bg-[#FCE184]` → should be `bg-surface-tertiary` 3. **Radius Hierarchy** (X issues) - Line 56: Button inside card uses `rounded-lg` → should be `rounded-sm` ### Recommended Fixes [Provide specific code changes]