From acss-kit
Generate and update CSS themes for fpkit/acss projects. Creates full light/dark palettes from seed colors using OKLCH, scaffolds brand presets, edits theme roles in place with WCAG re-validation, and extracts tokens from images or Figma designs. Use when the developer wants to create a theme, customize brand colors, or update specific role values in an existing theme.
npx claudepluginhub shawn-sandy/agentic-acss-plugins --plugin acss-kitThis skill is limited to using the following tools:
Theme generation and management for **fpkit/acss** projects. Routes between four flows depending on which slash command was invoked.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
Theme generation and management for fpkit/acss projects. Routes between four flows depending on which slash command was invoked.
Token and role conventions: see references/role-catalogue.md and the CSS Token Convention below.
OKLCH palette algorithm: see references/palette-algorithm.md.
JSON Schema and round-tripping: see references/theme-schema.md. The JSON schema is internal to the round-trip scripts (tokens_to_css.py / css_to_tokens.py); the CSS Token Convention below is the user-facing authoring format.
The authoring format for theme tokens is CSS custom properties — not JSON. Users edit light.css / dark.css / brand-*.css files directly; the JSON schema at ${CLAUDE_PLUGIN_ROOT}/assets/theme.schema.json is internal to the round-trip scripts and is not a user-facing contract. Existing CSS theme files remain byte-compatible with this convention.
assets/theme.schema.json $defs/palette declares 18 defined --color-* properties total: 15 required roles plus 3 optional roles (--color-surface-subtle, --color-text-subtle, --color-brand-accent). Names stay byte-compatible with the bundled CSS theme files — no renames, no removals, ever. Group them by purpose, matching ROLE_GROUPS in ${CLAUDE_PLUGIN_ROOT}/scripts/tokens_to_css.py:
Backgrounds
--color-background (required) — page background--color-surface (required) — card / panel surface--color-surface-raised (required) — elevated surface (modals, popovers)--color-surface-subtle (optional) — table-stripe / hover surfaceText
--color-text (required) — body text--color-text-muted (required) — secondary text--color-text-inverse (required) — text on primary background--color-text-subtle (optional) — tertiary text (timestamps, footnotes)Borders
--color-border (required) — default border--color-border-strong (required) — emphasized border (form-field focus)Brand & semantic
--color-primary (required) — brand primary--color-primary-hover (required) — primary hover state--color-success (required) — success / valid state--color-warning (required) — caution state--color-danger (required) — destructive / error state--color-info (required) — informational state--color-brand-accent (optional) — secondary brand colorFocus
--color-focus-ring (required) — focus indicator color (inputs, buttons)Full role catalog with contrast pairings is in references/role-catalogue.md.
Every theme must pass these pairings — the validator at ${CLAUDE_PLUGIN_ROOT}/scripts/validate_theme.py checks them automatically on every /theme-create, /theme-brand, /theme-update, and /theme-extract:
| Foreground | Background | Min ratio | Why |
|---|---|---|---|
--color-text | --color-background | 4.5:1 | Body text on page (WCAG 1.4.3) |
--color-text-muted | --color-background | 4.5:1 | Secondary text on page (WCAG 1.4.3) |
--color-text | --color-surface | 4.5:1 | Body text on cards/panels |
--color-text-inverse | --color-primary | 4.5:1 | Label text on primary buttons |
--color-text-inverse | --color-success | 4.5:1 | Success state buttons / badges |
--color-text-inverse | --color-danger | 4.5:1 | Destructive buttons / error chips |
--color-text-inverse | --color-warning | 4.5:1 | Warning chips / banners |
--color-text-inverse | --color-info | 4.5:1 | Info chips / banners |
--color-focus-ring | --color-background | 3:1 | Focus indicator on page (WCAG 1.4.11) |
--color-border-strong | --color-surface | 3:1 | Form-field focus border (WCAG 1.4.11) |
The validator's full pair list (10 pairs at default thresholds) is in scripts/validate_theme.py:PAIRS. Any theme that fails one of these pairings should be revised — usually by adjusting the seed color or manually tuning the OKLCH lightness on the failing role.
/theme-create and /theme-brand write light.css / dark.css / brand-*.css using the convention above. /theme-update edits role values in place.theme.tokens.json to write or maintain.tokens_to_css.py, css_to_tokens.py) remain internal. They use the JSON schema to translate between the OKLCH palette generator's output and CSS, but the JSON shape is not a user-facing contract./theme-create <hex-color> [--mode=light|dark|both]Purpose: Generate light.css and/or dark.css under src/styles/theme/ from a seed color.
${CLAUDE_PLUGIN_ROOT}/scripts/generate_palette.py <hex-color> --mode=<mode> (default both). Capture JSON stdout.
"reasons" non-empty), print the reasons and halt.src/styles/theme/ exists in the project, use it. Otherwise ask the developer where to write theme files.${CLAUDE_PLUGIN_ROOT}/scripts/tokens_to_css.py --stdin --out-dir=<dir> piping the palette JSON. This writes light.css and/or dark.css with mandatory var(--x, <fallback>) syntax.${CLAUDE_PLUGIN_ROOT}/scripts/validate_theme.py <dir>. If contrast failures are found, print them as warnings and continue — generation is complete but the developer should adjust the seed or manually tune values.references/palette-algorithm.md — OKLCH lightness targets and state-color hue offsets.references/role-catalogue.md — full role list and contrast targets./theme-brand <name> [--from=<hex-color>]Purpose: Scaffold brand-<name>.css with light and dark primary/accent overrides.
<name> is a lowercase slug (alphanumeric + hyphens). If not, suggest a corrected slug./theme-create).--from is provided:
${CLAUDE_PLUGIN_ROOT}/scripts/generate_palette.py <hex> --mode=brand. Capture brand overrides JSON.brand-<name>.css using the :root (light) and [data-theme="dark"] overrides.--from is not provided:
${CLAUDE_PLUGIN_ROOT}/assets/brand-template.css to brand-<name>.css. Instruct the developer to replace the placeholder values.${CLAUDE_PLUGIN_ROOT}/scripts/validate_theme.py <brand-file>. Report contrast results. Failures are warnings only (the brand file's primary is validated in context of the project's existing light.css background, which may not be present here).light.css and dark.css in their entry file.references/palette-algorithm.md — brand mode generation.references/role-catalogue.md — which roles are allowed in brand files./theme-update <file> <--color-role=#hex> [...]Purpose: Edit specific role values in an existing theme file and re-validate.
<file> exists and its name matches light.css, dark.css, or brand-*.css. Halt if not.--color-<role>=#<hex>.${CLAUDE_PLUGIN_ROOT}/scripts/validate_theme.py <file>.
c. If any contrast pair fails: print the failure, revert the edit for that role (restore original value), and continue with remaining roles.references/role-catalogue.md — contrast thresholds per pair./theme-extract <image-path|figma-url>Purpose: Extract brand colors from an image or Figma design and generate theme CSS.
figma.com URL → delegate to user-level figma-design-tokens skill.design-token-extractor skill.primary hex color (and optionally secondary, accent, background). Map the primary value to the seed color.${CLAUDE_PLUGIN_ROOT}/scripts/generate_palette.py <primary-hex> --mode=both. Capture JSON.secondary or accent colors, AskUserQuestion: "Should I also scaffold a brand preset using the secondary color?" If yes, run the brand flow inline.${CLAUDE_PLUGIN_ROOT}/scripts/tokens_to_css.py. Validate with ${CLAUDE_PLUGIN_ROOT}/scripts/validate_theme.py.theme.tokens.json alongside the CSS files:
${CLAUDE_PLUGIN_ROOT}/scripts/css_to_tokens.py on the written files and save the result.scripts/css_to_tokens.py.references/palette-algorithm.mdreferences/theme-schema.md — JSON output format and round-trip contract.references/role-catalogue.md| Situation | Action |
|---|---|
| Seed hex invalid | Halt with: "<value>" is not a valid hex color. Use #rrggbb or #rgb. |
generate_palette.py exits 1 | Print each reason from "reasons" array. Halt. |
| Output file already exists | Halt with list of conflicts. Proceed only with --force. |
| Contrast failure during update | Revert that specific role. Continue with remaining roles. |
| Extractor skill unavailable | Halt with: "/theme-extract requires the design-token-extractor or figma-design-tokens skill. Run: /find-skills design-token" |