Zetta v1.6

Components · Text & content

Icon

Material Symbols Outlined at weight 300, on a four-step size scale (12 / 16 / 20 / 24px). Each size pairs with its matching optical size so glyphs stay crisp. Functional icons inherit currentColor; only true identity icons take the brand lime.

Preview

Build with the skill

No package to install — hand this to your AI to generate or migrate the component in your stack.

Prompt for your AI
Apply the Zetta "Icon" component to this project using the zetta-design-md skill.

WHEN TO USE
- Migrating or fixing existing code (the common case): audit the current implementation against the `icon` spec (variants: sm, md, lg, xl) and CORRECT every deviation — replace off-spec values, don't only add new ones.
- New component: build it to the `icon` spec in this project's stack.

AUDIT & FIX (when the component already exists)
Compare it to the skill's spec and fix, don't just append: hardcoded colors/hex, off-scale radius, wrong fonts, dark/navy fills, shadows used in place of borders (or missing borders), brand lime used as a CTA or interaction (must be primary indigo), and any missing or wrong hover / focus / active / disabled / invalid state or missing 2px focus ring. Replace each with the correct Zetta token.

ALWAYS
- Pull the authoritative spec and tokens from the skill — never guess or hardcode values.
- Use this project's own component conventions and framework idioms.
- Honor the Zetta guardrails (brand = identity only, primary = interaction, shadows for overlays) and verify in Light, Dark, and Accessibility.

Anatomy & rules

  ╔══════╗
  ║  ⬡   ║  ← Material Symbol (outlined, variable font)
  ╚══════╝
  ↑ opsz axis matches rendered px size (12 / 16 / 20 / 24)
  ↑ wght = 300 (default), grad = 0

Parts:

  • Glyph — single Material Symbol rendered via variable font (@material-symbols/font-500)
  • Bounding box — square container at token size (sm: 12px, md: 16px, lg: 20px, xl: 24px)
  • Color — always currentColor (inherits from parent text color token)

Icon is non-interactive. No interactive states.

State Visual
Default Icon rendered at specified size, inherits currentColor
Decorative aria-hidden="true", no semantic role
Semantic Paired with aria-label or adjacent text

When to use

  • Communicating actions (buttons), states (status), and navigation (labels with icons).

When not to use

  • As the sole communicator of meaning — always pair with a label or aria-label.
  • Sizes outside the four-token scale — no custom pixel values.

Do

  • Always set opsz equal to the rendered size.
  • Use {colors.ink-subtle} for secondary or decorative icons.
  • Use {colors.muted} for placeholder or inactive icons.
  • Use {colors.primary} for active or selected state icons.

Don't

  • Don't use filled or rounded icon style variants.
  • Don't use raw pixel sizes — always reference a size token.
  • Don't place icons smaller than 12px (sizeMap.sm) in the UI.
  • Icons used alongside text: aria-hidden="true" — text carries the meaning.
  • Icon-only interactive elements: aria-label required on the parent button/link.
  • Decorative icons in content: aria-hidden="true".
  • Status icons in semantic context: pair with visible text label — never color or icon alone.

Keyboard

Icon is non-interactive and has no keyboard behavior. When used inside interactive elements (buttons, links), keyboard interaction is inherited from the parent.

Accessibility

Decorative icons (icon accompanies a visible text label):

  • Add aria-hidden="true" — screen readers will skip the icon and read the label.

Meaningful icons (icon communicates information without an adjacent label):

  • Add role="img" and aria-label describing what the icon communicates.
  • Example: <span role="img" aria-label="Warning"> around a warning icon in a status column.

Spec

Values and token references resolved straight from the Zetta spec.

icon-sm
size
{icons.sizeMap.sm}
opticalSize
12
icon-md
size
{icons.sizeMap.md}
opticalSize
16
icon-lg
size
{icons.sizeMap.lg}
opticalSize
20
icon-xl
size
{icons.sizeMap.xl}
opticalSize
24
icon-decorative
ariaHidden
true
icon-meaningful
role
img