Claude Code Plugins

Community-maintained marketplace

Feedback

Icon usage patterns using Material Symbols v3. Use when adding icons to buttons, navigation, or status indicators. Covers sizing, accessibility, animations, and color integration with project tokens.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name ux-iconography
description Icon usage patterns using Material Symbols v3. Use when adding icons to buttons, navigation, or status indicators. Covers sizing, accessibility, animations, and color integration with project tokens.
allowed-tools Read, Write, Edit, Glob, Grep

UX Iconography Skill

Icon implementation patterns for UI components. This project uses Material Symbols v3 as the primary icon system.

Related Skills

  • material-symbols-v3: Complete icon API reference, variable font axes, icon names
  • ux-accessibility: ARIA requirements for icon buttons
  • ux-animation-motion: Anime.js patterns for icon animations

Icon System

Location: css/styles/icons.css

This project uses Material Symbols Outlined (variable font) from Google Fonts:

<span class="icon">home</span>
<span class="icon">settings</span>
<span class="icon">favorite</span>

See material-symbols-v3 skill for complete icon name reference.

Icon Sizing

Size Classes

<span class="icon icon--sm">info</span>   <!-- 20px -->
<span class="icon icon--md">info</span>   <!-- 24px (default) -->
<span class="icon icon--lg">info</span>   <!-- 40px -->
<span class="icon icon--xl">info</span>   <!-- 48px -->

Fluid Sizing with Utopia

Scale icons with typography tokens:

.icon-fluid {
  font-size: var(--step-1);
}

.icon-small {
  font-size: var(--step--1);
}

Fixed Container

.icon-fixed {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
}

Icon + Text Patterns

Inline with Label

<button class="btn-icon-text">
  <span class="icon" aria-hidden="true">menu_book</span>
  <span class="label">Word Phase</span>
</button>
.btn-icon-text {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
}

.btn-icon-text .icon {
  flex-shrink: 0;
}

Icon-Only Button

<button class="btn-icon" aria-label="Settings">
  <span class="icon" aria-hidden="true">settings</span>
</button>
.btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--min-touch-target);
  min-height: var(--min-touch-target);
  padding: var(--space-xs);
}

Trailing Icon

<a href="/next" class="link-arrow">
  Next Phase
  <span class="icon" aria-hidden="true">arrow_forward</span>
</a>

Accessibility

Always Hide Decorative Icons

<!-- Decorative: has visible label -->
<button>
  <span class="icon" aria-hidden="true">settings</span>
  Settings
</button>

<!-- Meaningful: icon-only needs label -->
<button aria-label="Settings">
  <span class="icon" aria-hidden="true">settings</span>
</button>

Screen Reader Text

<button class="btn-icon">
  <span class="icon" aria-hidden="true">settings</span>
  <span class="sr-only">Settings</span>
</button>
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  clip: rect(0, 0, 0, 0);
}

Status Icons with Text

<span class="status status-complete">
  <span class="icon" aria-hidden="true">check_circle</span>
  <span>Complete</span>
</span>

Icon Variants

Fill Style

<span class="icon icon--outlined">favorite</span>  <!-- Outline (default) -->
<span class="icon icon--filled">favorite</span>    <!-- Solid fill -->

Weight

<span class="icon icon--thin">home</span>     <!-- 100 -->
<span class="icon icon--light">home</span>    <!-- 300 -->
<span class="icon icon--regular">home</span>  <!-- 400 -->
<span class="icon icon--medium">home</span>   <!-- 500 -->
<span class="icon icon--bold">home</span>     <!-- 700 -->

Icon Color

Inherit from Parent

.icon {
  color: inherit;
}

.btn-primary .icon {
  color: var(--theme-on-primary);
}

Semantic Colors

.icon-success { color: var(--color-success); }
.icon-error { color: var(--color-error); }
.icon-warning { color: var(--color-warning); }

Phase Colors

[data-phase="word"] .icon { color: var(--color-word); }
[data-phase="collision"] .icon { color: var(--color-collision); }
[data-phase="mutation"] .icon { color: var(--color-mutation); }
[data-phase="story"] .icon { color: var(--color-story); }

Animation

CSS Transitions

.icon {
  transition: transform 0.15s ease;
}

.btn:hover .icon {
  transform: scale(1.1);
}

.btn:active .icon {
  transform: scale(0.95);
}

Wiggle Animation (Anime.js)

import { animate } from 'animejs';
import { DURATION, EASE } from '../../utils/animations.js';

animate(this._iconEl, {
  rotate: [0, -10, 10, -10, 10, 0],
  duration: DURATION.normal,
  ease: EASE.smooth
});

Celebration Bounce

import { successBounce } from '../../utils/animations.js';

successBounce(this._iconEl);
// Scale: 1 → 1.2 → 1

Status Indicators

Phase Status

.phase-icon {
  font-size: var(--step-0);
}

[data-status="complete"] .phase-icon {
  color: var(--color-success);
}

[data-status="current"] .phase-icon {
  color: var(--theme-primary);
  animation: pulse 1.5s ease-in-out infinite;
}

[data-status="locked"] .phase-icon {
  opacity: 0.5;
  filter: grayscale(0.5);
}

Progress Dots

.progress-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--theme-outline-variant);
}

.progress-dot[data-completed] {
  background: var(--color-success);
}

.progress-dot[data-current] {
  background: var(--theme-primary);
}

Loading Icons

Spinner

<span class="spinner" role="status">
  <span class="sr-only">Loading...</span>
</span>
.spinner {
  display: inline-block;
  width: 1em;
  height: 1em;
  border: 2px solid var(--theme-outline);
  border-top-color: var(--theme-primary);
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
}

@keyframes spin {
  to { rotate: 360deg; }
}

Common Game Icons

Purpose Icon Name Usage
Word phase menu_book Phase indicator
Collision phase swords Phase indicator
Mutation phase genetics Phase indicator
Story phase auto_stories Phase indicator
Complete check_circle Status indicator
Locked lock Unavailable item
Star/achievement star Rewards
Settings settings Configuration
Home home Navigation
Sound on volume_up Audio toggle
Sound off volume_off Audio toggle

High Contrast Mode

@media (forced-colors: active) {
  .icon {
    forced-color-adjust: auto;
  }
}

Best Practices

Do

  • Use aria-hidden="true" on decorative icons
  • Provide aria-label for icon-only buttons
  • Use semantic colors for status icons
  • Ensure touch targets are 44x44px minimum
  • Use .icon--filled for selected/active states

Don't

  • Use icons as the only indicator of meaning
  • Forget to hide icons from screen readers
  • Use fixed pixel sizes that don't scale
  • Animate icons excessively
  • Mix icon systems inconsistently