Help us improve
Share bugs, ideas, or general feedback.
From duskmoon-ui
Use the DuskMoon CSS Art Elements (`<el-dm-art-*>` web components). Use when adding pure CSS art animations to web pages — atom, moon, sun, plasma-ball, gemini-input, synthwave-starfield, and more. Covers all 15 CSS art packages, registration patterns, size variants, and the @layer stripping technique required for Shadow DOM compatibility.
npx claudepluginhub gsmlg-dev/code-agent --plugin duskmoon-uiHow this skill is triggered — by the user, by Claude, or both
Slash command
/duskmoon-ui:duskmoon-art-elementsThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
15 pure CSS art custom elements built on `@duskmoon-dev/el-base`. Each element renders a self-contained CSS animation — no JavaScript logic, no external images.
Creates animated backgrounds with gradient flows, particle systems, mesh gradients, aurora effects, wave patterns, and dynamic textures for hero sections, landing pages, and interfaces.
Provides pre-built animated React components from Magic UI (Tailwind/Framer Motion/shadcn-ui) and React Bits for landing pages, dashboards, and interactive UIs.
Builds complex Claude.ai HTML artifacts with React, TypeScript, Tailwind CSS, and shadcn/ui. Provides init and bundling scripts for multi-component apps with state and routing.
Share bugs, ideas, or general feedback.
15 pure CSS art custom elements built on @duskmoon-dev/el-base. Each element renders a self-contained CSS animation — no JavaScript logic, no external images.
# Individual art element
bun add @duskmoon-dev/el-art-atom
# All art elements at once
bun add @duskmoon-dev/art-elements
// Option 1: Explicit (tree-shakable)
import { register } from '@duskmoon-dev/el-art-atom';
register();
// Option 2: Side-effect auto-register
import '@duskmoon-dev/el-art-atom/register';
// Option 3: Register all CSS art elements
import { registerAllArts } from '@duskmoon-dev/art-elements';
registerAllArts();
<el-dm-art-atom></el-dm-art-atom>
<el-dm-art-atom size="lg"></el-dm-art-atom>
<el-dm-art-moon variant="crescent" glow></el-dm-art-moon>
<el-dm-art-sun variant="sunset" rays></el-dm-art-sun>
<el-dm-art-plasma-ball size="xl"></el-dm-art-plasma-ball>
<el-dm-art-synthwave-starfield size="lg" paused></el-dm-art-synthwave-starfield>
<el-dm-art-gemini-input placeholder="Ask me anything..."></el-dm-art-gemini-input>
<el-dm-art-gemini-input size="lg"></el-dm-art-gemini-input>
All CSS art elements are display: inline-block by default. Most support size:
| Property | Type | Default | Description |
|---|---|---|---|
size | String | 'md' | Size variant — maps to art-{name}-{size} CSS class (sm, md, lg) |
Element-specific properties:
| Element | Extra Properties |
|---|---|
el-dm-art-moon | variant (String), glow (Boolean) |
el-dm-art-mountain | variant (String) |
el-dm-art-sun | variant (String), rays (Boolean) |
el-dm-art-snow | count (Number), unicode (Boolean), fall (Boolean) |
el-dm-art-circular-gallery | title (String), count (Number) |
el-dm-art-synthwave-starfield | paused (Boolean) |
el-dm-art-gemini-input | placeholder (String) |
CSS art elements import raw CSS from @duskmoon-dev/css-art and strip the @layer css-art { ... } wrapper before injecting into Shadow DOM:
import rawCss from '@duskmoon-dev/css-art/dist/art/{name}.css' with { type: 'text' };
const layerMatch = rawCss.match(/@layer\s+css-art\s*\{([\s\S]*)\}\s*$/);
const coreCss = layerMatch ? layerMatch[1] : rawCss;
This is required because @layer inside Shadow DOM does not interact with the document's layer order.
Some art pieces (e.g. gemini-input) also have @property declarations outside the layer — these are preserved by the stripping regex since they appear before the @layer block and are not matched.