# Canvas Styling Conventions

> A Claude skill from drupal-canvas/skills.

- **Type:** Skill
- **Install:** `agentstack add skill-drupal-canvas-skills-canvas-styling-conventions`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [drupal-canvas](https://agentstack.voostack.com/s/drupal-canvas)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [drupal-canvas](https://github.com/drupal-canvas)
- **Source:** https://github.com/drupal-canvas/skills/tree/main/skills/canvas-styling-conventions

## Install

```sh
agentstack add skill-drupal-canvas-skills-canvas-styling-conventions
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

## Technology stack

| Technology                           | Purpose            |
| ------------------------------------ | ------------------ |
| Tailwind CSS 4.1+                    | Styling            |
| class-variance-authority (CVA)       | Component variants |
| `clsx` + `tailwind-merge` via `cn()` | Class name merging |

Only use these dependencies for styling. Do not add third-party CSS libraries or
create new styling utilities.

## Styling conventions

- Use Tailwind's theme colors (`primary-*`, `gray-*`) defined in `global.css`.
- Avoid hardcoded color values; use theme tokens instead.
- Follow the existing focus, hover, and active state patterns from examples.

## The cn() utility

Use `cn()` to merge Tailwind classes. It combines `clsx` for conditional classes
with `tailwind-merge` to resolve conflicting utilities. Import from either
source:

```jsx
import { cn } from '@/lib/utils';
// or
import { cn } from 'drupal-canvas';
```

Example usage:

```jsx
const Button = ({ variant, className, children }) => (
  
    {children}
  
);
```

## Accept className for style customization

Every component should accept a `className` prop to allow style overrides. Pass
it to `cn()` as the last argument so consumer classes take precedence.

```jsx
const Card = ({ colorScheme, className, children }) => (
  {children}
);
```

`className` is an implementation/composition prop, not an editor prop. Do not
add `className` to `component.yml`, do not mark it as required, and do not
surface it in Canvas metadata.

## Tailwind 4 theme variables

Canvas projects use Tailwind CSS 4's `@theme` directive to define design tokens
in `global.css`. Variables defined inside `@theme { }` automatically become
available as Tailwind utility classes.

**Always check `global.css` for available design tokens.** The `@theme` block is
the source of truth for colors, fonts, breakpoints, and other design tokens.

### How theme variables map to utility classes

When you define a CSS variable in `@theme`, Tailwind 4 automatically generates
corresponding utility classes based on the variable's namespace prefix:

| CSS Variable in `@theme`    | Generated Utility Classes                                  |
| --------------------------- | ---------------------------------------------------------- |
| `--color-primary-600: #xxx` | `bg-primary-600`, `text-primary-600`, `border-primary-600` |
| `--color-gray-100: #xxx`    | `bg-gray-100`, `text-gray-100`, `border-gray-100`          |
| `--font-sans: ...`          | `font-sans`                                                |
| `--breakpoint-md: 48rem`    | `md:` responsive prefix                                    |

The pattern is: `--{namespace}-{name}` becomes `{utility}-{name}`.

### Examples

Given this definition in `global.css`:

```css
@theme {
  --color-primary-600: #1899cb;
  --color-primary-700: #1487b4;
}
```

You can use these colors with any color-accepting utility:

```jsx
// Correct

  Click me

// Wrong
Click me
```

Arbitrary values (e.g., `bg-[#xxx]`) are acceptable for rare, one-off cases
where adding a theme variable would be overkill. However, if a color appears in
multiple places or represents a brand/design system value, add it to `@theme`
instead.

### Semantic aliases

Theme variables can reference other variables to create semantic aliases:

```css
@theme {
  --color-primary-700: #1487b4;
  --color-primary-dark: var(--color-primary-700);
}
```

Both `bg-primary-700` and `bg-primary-dark` will work. Use semantic aliases when
they better express intent (e.g., `primary-dark` for a darker brand variant).

### Adding or updating theme variables

When a design requires a color, font, or other value not yet defined in the
theme, add it to the `@theme` block in `global.css` rather than hardcoding the
value in a component.

**When to add new theme variables:**

- A design introduces a new brand color or shade
- You need a semantic alias for an existing value (e.g., `--color-accent`)
- The design uses a specific spacing, font, or breakpoint value repeatedly

**When to update existing theme variables:**

- The brand colors change (update the hex values)
- Design tokens need adjustment across the system

**Example - adding a new color:**

```css
@theme {
  /* Existing tokens */
  --color-primary-600: #1899cb;

  /* New token for a success state */
  --color-success: #22c55e;
  --color-success-dark: #16a34a;
}
```

After adding, you can immediately use `bg-success`, `text-success-dark`, etc.

**Keep the theme organized.** Group related tokens together with comments
explaining their purpose. Follow the existing naming conventions in `global.css`
(e.g., numbered shades like `primary-100` through `primary-900`, semantic names
like `primary-dark`).

## Color props must use variants, not color codes

**Never create props that allow users to pass color codes** (hex values, RGB,
HSL, or any raw color strings). Instead, define a small set of human-readable
variants using CVA that map to the design tokens in `global.css`.

**Always check `global.css` for available design tokens.** The tokens defined
there (such as `primary-*`, `gray-*`, etc.) are the source of truth for color
values.

**Wrong - allowing raw color values:**

```yaml
# Wrong
props:
  properties:
    backgroundColor:
      title: Background Color
      type: string
      examples:
        - '#3b82f6'
```

```jsx
// Wrong
const Card = ({ backgroundColor }) => (
  {/* ... */}
);
```

**Correct - using CVA variants with design tokens:**

```yaml
# Correct
props:
  properties:
    colorScheme:
      title: Color Scheme
      type: string
      enum:
        - default
        - primary
        - muted
        - dark
      meta:enum:
        default: Default (White)
        primary: Primary (Blue)
        muted: Muted (Light Gray)
        dark: Dark
      examples:
        - default
```

```jsx
// Correct
import { cva } from 'class-variance-authority';

const cardVariants = cva('rounded-lg p-6', {
  variants: {
    colorScheme: {
      default: 'bg-white text-black',
      primary: 'bg-primary-600 text-white',
      muted: 'bg-gray-100 text-gray-700',
      dark: 'bg-gray-900 text-white',
    },
  },
  defaultVariants: {
    colorScheme: 'default',
  },
});

const Card = ({ colorScheme, children }) => (
  {children}
);
```

This approach ensures:

- Consistent colors across the design system
- Users select from curated, meaningful options (not arbitrary values)
- Easy theme updates by modifying `global.css` tokens
- Better accessibility through tested color combinations

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [drupal-canvas](https://github.com/drupal-canvas)
- **Source:** [drupal-canvas/skills](https://github.com/drupal-canvas/skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-drupal-canvas-skills-canvas-styling-conventions
- Seller: https://agentstack.voostack.com/s/drupal-canvas
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
