Semantic Coding

SkillMedia

Replace hardcoded styles with semantic design tokens (colors, typography, spacing, sizing) across a codebase. Use when refactoring inline hex colors/px values to a design system, migrating to CSS variables or Tailwind theme tokens, or enforcing token consistency.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Semantic Coding skill

What this skill tells your AI

The instructions your AI receives, as published by georgekhananaev/claude-skills-vault in .claude/skills/semantic-coding/SKILL.md and read by ahel’s review.

Scan files, replace hardcoded styles with semantic design tokens (colors, typography, spacing, sizing), edit files directly.

Refactored from semantic-colors (color-only) into a comprehensive design system skill.

Usage

/semantic-coding [path]

DO NOT TOUCH (Non-Negotiable)

  • Gradients: from-*, via-*, to-*, bg-gradient-*, linear-gradient(), radial-gradient(), conic-gradient()
  • SVG defs: <linearGradient>, <radialGradient>, <stop>, url(#...), anything inside <defs>
  • Glass morphism: rgba(255,255,255,0.0x) overlays on gradient backgrounds
  • Decorative shadows: boxShadow glow effects tied to gradient LED/orb effects
  • Animations: @keyframes, animation timing values, transform values
  • Template literals: `border-${color}-500`, dynamic class construction
  • Arbitrary values: bg-[#hex], text-[14px], p-[20px] (JIT bracket syntax)
  • Component props: Color/style values passed as non-className props (e.g., <Button color="red-500" />)
  • Token source files: globals.css, tailwind.config.*, tokens.ts, theme.ts
  • Excluded dirs: node_modules, .next, lib/generated, prisma/, dist/, __tests__/, *.test.*, *.spec.*

If a value is inside a protected context, skip and log ⚠ skipped (protected context).


Color Rules

Color Replacements

Note: Color-to-semantic mapping depends on your project's brand palette. The defaults below assume orange=brand, blue=info. If your brand uses blue/indigo/etc., map that family to brand instead and adjust accordingly.

HardcodedSemantic
text-red-*, text-rose-*text-error
text-green-*, text-emerald-*, text-teal-*text-success
text-yellow-*, text-amber-*text-warning
text-blue-*, text-cyan-*text-info
text-orange-*text-brand
text-indigo-*, text-violet-*, text-purple-*text-primary
text-pink-*, text-fuchsia-*text-accent
text-gray-*, text-slate-*, text-zinc-*, text-stone-*, text-neutral-*, text-ink-*text-muted-foreground
text-gray-900, text-slate-900, text-zinc-900text-foreground
text-white (on semantic bg)text-{bg-token}-foreground
text-blacktext-foreground
bg-red-*, bg-rose-* (shade ≥500)bg-error
bg-red-*, bg-rose-* (shade <500)bg-error/10
bg-green-*, bg-emerald-*, bg-teal-* (shade ≥500)bg-success
bg-green-*, bg-emerald-*, bg-teal-* (shade <500)bg-success/10
bg-yellow-*, bg-amber-* (shade ≥500)bg-warning
bg-yellow-*, bg-amber-* (shade <500)bg-warning/10
bg-blue-*, bg-cyan-* (shade ≥500)bg-info
bg-blue-*, bg-cyan-* (shade <500)bg-info/10
bg-orange-*bg-brand or bg-brand/10
bg-indigo-*, bg-violet-*, bg-purple-*bg-primary or bg-primary/10
bg-gray-*, bg-slate-*, bg-zinc-*, bg-stone-*, bg-neutral-*, bg-ink-*bg-muted
bg-white (page-level)bg-background
bg-white (inside card/panel)bg-card
bg-black/50 (overlay)bg-overlay
border-gray-*, border-slate-*, border-zinc-*, border-stone-*, border-neutral-*, border-ink-*border-border
border-red-*, border-rose-*border-error
border-green-*, border-emerald-*, border-teal-*border-success
border-blue-*, border-cyan-*border-info
border-yellow-*, border-amber-*border-warning
border-orange-*border-brand
border-indigo-*, border-violet-*, border-purple-*border-primary
shadow-emerald-*, shadow-green-*shadow-success
shadow-red-*shadow-error
shadow-blue-*shadow-info
ring-red-*ring-error
ring-green-*ring-success
ring-blue-*ring-info
divide-gray-*, divide-slate-*divide-border
placeholder-gray-*placeholder-muted-foreground

Foreground Pairing

BackgroundForeground
bg-primarytext-primary-foreground
bg-brandtext-brand-foreground
bg-successtext-success-foreground
bg-errortext-error-foreground
bg-warningtext-warning-foreground
bg-infotext-info-foreground

Dark Mode Override Removal

Collapse light+dark pairs into one semantic token:

- className="text-green-600 dark:text-green-400"
+ className="text-success"

- className="bg-red-100 dark:bg-red-900/20 border-red-200 dark:border-red-800"
+ className="bg-error/10 border-error"

Typography Rules

Font Family

HardcodedSemantic
font-sans (body text)font-body
font-sans (headings)font-heading
font-monofont-mono
font-seriffont-display
Inline fontFamily: 'Inter'var(--font-body)
Inline fontFamily: 'monospace'var(--font-mono)

Font Size (Text Scale)

HardcodedSemanticUse Case
text-xstext-captionLabels, hints, timestamps
text-smtext-body-smSecondary content, metadata
text-basetext-bodyBody text, paragraphs
text-lgtext-body-lgLead paragraphs, emphasis
text-xltext-heading-smSmall headings, card titles
text-2xltext-heading-mdSection headings
text-3xltext-heading-lgPage titles
text-4xl, text-5xltext-heading-xlHero headings
text-6xl, text-7xl, text-8xl, text-9xltext-displayDisplay/marketing headings
Inline fontSize: '14px'var(--text-body-sm)
Inline fontSize: '24px'var(--text-heading-md)

Font Weight

HardcodedSemanticUse Case
font-extralight (200)font-thinDecorative, display text
font-light (300)font-lightSubtle body text
font-normal (400)font-normalBody text
font-medium (500)font-mediumEmphasis, labels
font-semibold (600)font-semiboldSubheadings
font-bold (700)font-boldHeadings, CTAs
font-extrabold (800), font-black (900)font-heavyDisplay, marketing

Line Height

HardcodedSemanticUse Case
leading-noneleading-noneDisplay text, single-line
leading-tightleading-tightHeadings
leading-snugleading-snugSubheadings
leading-normalleading-normalBody text
leading-relaxedleading-relaxedLong-form content
leading-looseleading-looseLegal, fine print

Letter Spacing

HardcodedSemantic
tracking-tightertracking-heading
tracking-tighttracking-heading
tracking-normaltracking-body
tracking-widetracking-label
tracking-widertracking-label
tracking-widest + uppercasetracking-overline

Composite Typography Patterns

Match multi-class patterns before individual classes. Apply the first matching composite rule.

Hardcoded PatternSemantic
text-6xl+ font-bold/extraboldtext-display
text-4xl font-bold tracking-tighttext-heading-xl
text-3xl font-semiboldtext-title
text-2xl font-semiboldtext-subtitle
text-lg font-mediumtext-lead
text-basetext-body
text-sm text-gray-*text-muted
text-xs uppercase tracking-widetext-overline
text-xs font-mediumtext-label

Spacing Rules

Semantic Spacing Scale

HardcodedSemanticValue
p-1, m-1space-xs4px
p-2, m-2space-sm8px
p-3, m-3space-md12px
p-4, m-4space-lg16px
p-5, m-5space-xl20px
p-6, m-6space-2xl24px
p-8, m-8space-3xl32px
p-10, m-10space-4xl40px
p-12, m-12space-5xl48px

Component Spacing Patterns

ContextRecommended Token
Button paddingpx-button py-button or p-4
Card paddingp-card or p-6
Section paddingp-section or py-12 px-6
Input paddingpx-input py-input or px-4 py-2
Gap between itemsgap-sm (8px), gap-md (12px), gap-lg (16px)
Stack spacingspace-y-sm, space-y-md, space-y-lg

Sizing Rules

Width/Height

HardcodedSemanticUse Case
w-4 h-4size-icon-xsSmall icons
w-5 h-5size-icon-smDefault icons
w-6 h-6size-icon-mdMedium icons
w-8 h-8size-icon-lgLarge icons
w-10 h-10size-avatar-smSmall avatars
w-12 h-12size-avatar-mdMedium avatars
w-16 h-16size-avatar-lgLarge avatars
h-10, h-11h-inputInput/button height
max-w-smmax-w-formForm container
max-w-xlmax-w-contentContent container
max-w-5xlmax-w-pagePage container

Border Radius

HardcodedSemanticUse Case
roundedrounded-smSubtle rounding
rounded-mdrounded-baseDefault rounding
rounded-lgrounded-lgCards, modals
rounded-xlrounded-xlLarge cards
rounded-2xlrounded-2xlHero sections
rounded-fullrounded-fullPills, avatars

Shadow Rules

HardcodedSemanticUse Case
shadow-smshadow-smSubtle elevation
shadowshadow-baseDefault elevation
shadow-mdshadow-mdCards
shadow-lgshadow-lgModals, dropdowns
shadow-xlshadow-xlPopovers
shadow-2xlshadow-2xlFloating elements
shadow-successshadow-successSuccess glow
shadow-errorshadow-errorError glow

Z-Index Rules

HardcodedSemanticUse Case
z-0z-baseDefault layer
z-10z-dropdownDropdowns
z-20z-stickySticky headers
z-30z-overlayOverlays
z-40z-modalModals
z-50z-toastToasts, tooltips

Inline Style Replacements

HardcodedSemantic
style={{ color: '#111827' }}className="text-foreground"
style={{ color: '#6b7280' }}className="text-muted-foreground"
style={{ backgroundColor: '#ffffff' }}var(--color-background)
style={{ fontSize: '14px' }}var(--text-body-sm)
style={{ fontWeight: 600 }}className="font-semibold"
style={{ padding: '16px' }}className="p-4" or var(--space-lg)
style={{ borderRadius: '8px' }}var(--radius-base)

Third-Party Config Pattern

When a library requires specific values at initialization, use runtime CSS variable resolution:

function cssVar(name, fallback) {
  if (typeof window === 'undefined') return fallback;
  return getComputedStyle(document.documentElement)
    .getPropertyValue(name).trim() || fallback;
}

// Usage: cssVar('--color-brand', '#F97316')

Initialize in useEffect (not module level) so CSS variables are available.


Scoped Token Pattern

When a page has a fixed dark background that doesn't change with theme, use var() with inline fallback:

color: 'var(--status-text-muted, #a1a1aa)'

Status Mapping

StatusSemantic
DRAFTmuted
PENDING, SUBMITTEDwarning
CONFIRMED, SUCCESS, COMPLETED, PAIDsuccess
REJECTED, ERROR, CANCELLEDerror
INFO, SENT, RECEIVEDinfo

Available Tokens Reference

Colors

Text: text-foreground, text-muted-foreground, text-primary, text-primary-foreground, text-brand, text-brand-foreground, text-accent, text-success, text-success-foreground, text-warning, text-warning-foreground, text-error, text-error-foreground, text-info, text-info-foreground

Background: bg-background, bg-card, bg-muted, bg-primary, bg-brand, bg-accent, bg-success, bg-warning, bg-error, bg-info, bg-overlay

Border: border-border, border-input, border-primary, border-brand, border-success, border-error, border-warning, border-info

Ring: ring-primary, ring-success, ring-error, ring-info

Shadow: shadow-success, shadow-error, shadow-info

Misc: divide-border, placeholder-muted-foreground

Typography

Font Family: font-body, font-heading, font-mono, font-display

Font Size: text-caption, text-body-sm, text-body, text-body-lg, text-heading-sm, text-heading-md, text-heading-lg, text-heading-xl, text-display

Composite: text-title, text-subtitle, text-lead, text-muted, text-overline, text-label

Font Weight: font-thin, font-light, font-normal, font-medium, font-semibold, font-bold, font-heavy

Letter Spacing: tracking-heading, tracking-body, tracking-label, tracking-overline

Line Height: leading-none, leading-tight, leading-snug, leading-normal, leading-relaxed, leading-loose

Spacing

Padding/Margin: space-xs, space-sm, space-md, space-lg, space-xl, space-2xl, space-3xl, space-4xl, space-5xl

Component: p-card, p-section, p-input, px-button, py-button

Gap: gap-xs, gap-sm, gap-md, gap-lg, gap-xl

Stack: space-y-sm, space-y-md, space-y-lg

Sizing

Icons: size-icon-xs, size-icon-sm, size-icon-md, size-icon-lg

Avatars: size-avatar-sm, size-avatar-md, size-avatar-lg

Containers: max-w-form, max-w-content, max-w-page

Input: h-input

Effects

Radius: rounded-sm, rounded-base, rounded-lg, rounded-xl, rounded-2xl, rounded-full

Shadow: shadow-sm, shadow-base, shadow-md, shadow-lg, shadow-xl, shadow-2xl

Z-Index: z-base, z-dropdown, z-sticky, z-overlay, z-modal, z-toast


Behavior

For each .tsx, .jsx, .ts, .js file in the target path (skip excluded dirs):

  1. Read the file
  2. Find hardcoded styles (colors, fonts, sizes, spacing)
  3. Check if inside protected context (gradient/SVG-def/animation)
  4. If safe → apply matching rule and edit immediately
  5. If protected context → skip, log as ⚠ skipped

After all files are done, re-scan to verify zero remaining violations. Print summary.

Summary Format

Semantic coding refactor: N files changed, M replacements
- file.tsx: colors (5), typography (3), spacing (2)
⚠ file.tsx:42 — skipped (gradient context)
⚠ file.tsx:88 — skipped (SVG defs)

Signals

GitHub stars
28
Forks
10
Last commit
Aug 2026
Advanced
Catalog kind
skill
Gateway key
semantic-coding
Source
github.com/georgekhananaev/claude-skills-vault