Carm Mascot Kit

Canonical source for Carm the beaver mascot. Animated SVG, any-color palette generation, 48 states, 19 stackable accessories. Pick a color below or grab the static SVGs.

Persona
Color #C79A80
Size 200px
States (48 total)
Accessories (19 — click to toggle, stackable)
Static SVG Assets
Usage

Quick embed (static SVG)

<img src="mascot/carm.svg" width="80" alt="Carm">

Animated (JS + CSS)

<link rel="stylesheet" href="mascot/mascot.css">
<script src="mascot/mascot.js"></script>

<div id="carm"></div>
<script>
  Mascot.create(
    document.getElementById('carm'),
    { size: 120, persona: 'carm', state: 'idle' }
  );
</script>

Change state

const el = document.querySelector('.carm');
Mascot.setState(el, 'thinking');
// later...
Mascot.setState(el, 'responding');

Switch palette

const el = document.querySelector('.carm');
Mascot.applyPalette(
  el, Mascot.PALETTES.ash
);

Custom color (any hex)

// Generate palette from any color
const pal = Mascot.generatePalette('#4CAF50');
Mascot.applyPalette(el, pal);

// Or pass color directly:
Mascot.create(container, {
  color: '#9C27B0', state: 'idle'
});

// Works with render() too:
Mascot.render({
  color: '#FF8C00', mode: 'file'
});

Add accessories

const el = document.querySelector('.carm');
Mascot.setAccessory(el, 'glasses');
Mascot.setAccessory(el, 'bowtie');
// accessories stack!

Mascot.removeAccessory(el, 'glasses');
Mascot.clearAccessories(el);

Create with accessory

Mascot.create(container, {
  size: 120,
  persona: 'carm',
  state: 'proud',
  accessory: ['crown', 'bowtie']
});

Raw SVG string

// For email templates, server-side, etc.
const svgString = Mascot.svg('email', 120);
// Returns full SVG markup as a string

CDN-style URL

https://carm-the-beaver.pages.dev/carm.svg
https://carm-the-beaver.pages.dev/ash.svg
https://carm-the-beaver.pages.dev/mascot.js
https://carm-the-beaver.pages.dev/mascot.css
Palettes
API Reference

Mascot.create(container, opts)

Inserts an animated mascot SVG into container.

opts: {
  id:      string   // gradient namespace (auto)
  size:    number   // px width/height (default 80)
  persona: string   // 'carm' | 'ash'
  state:   string   // initial state (default 'idle')
}

Returns the SVG element.

Mascot.setState(svgEl, state)

Transitions mascot to a new state.
Handles class management and
one-shot animation replay.

Base: idle, listening, thinking,
      responding, greeting, error,
      planning, reviewing, debugging,
      testing, deploying, concerned,
      awaiting-input, reconnecting

Escalations: thinking-deep,
  thinking-fast, thinking-sweat,
  thinking-tired, thinking-asleep,
  idle-bored, idle-asleep,
  listening-long, listening-wow,
  debugging-stumped, reviewing-intense,
  testing-long, awaiting-input-timeout,
  reconnecting-flaky

Mascot.applyPalette(svgEl, pal)

Recolors all SVG elements to match
the given palette object.

Built-in: Mascot.PALETTES.carm
          Mascot.PALETTES.ash

Custom palettes: pass any object with
the same keys (face, gill, bot, etc.)

Mascot.generatePalette(hex)

Given any hex color (e.g. '#4CAF50'),
generates a full palette.

The input color becomes the identity
hue (fur). Everything else derives
mathematically from it.

Bright inputs: proportional S/L scale.
Dark inputs (<45% L): contrast-aware
remap — input = darkest, rest fans
lighter.

Returns a palette object compatible
with applyPalette().

Mascot.svg(id, size)

Returns raw SVG markup as a string.
Useful for server-side rendering,
email templates, or injecting
into non-DOM contexts.

id namespaces gradient IDs to avoid
conflicts with multiple instances.