算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
accelint-design-foundation【设计与创意】Use when styling components or elements with @accelint/design-foundation or @accelint/design-toolkit packages, or when users say "style this", "add styling", "theme this component", "add colors", "add spacing", "CSS modules", "setup design foundation", "@variant", or when working with .module.css files. Provides opinionated Tailwind conventions inclu…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Expert knowledge for styling with @accelint/design-foundation and @accelint/design-toolkit — opinionated Tailwind conventions that differ from vanilla implementations.
p-xxs, gap-m, m-l. Numeric classes like p-4, gap-6 work with a 1:1 relationship (p-1 = 1px, NOT 4px like vanilla Tailwind), but should only be used for rare cases where implementing non-conforming designs. The semantic scale provides design system consistency.dark:bg-gray-900 or className={theme === 'dark' ? 'bg-black' : 'bg-white'}. Use semantic color classes like bg-surface-default and fg-primary-bold that automatically adapt to light/dark themes.outline instead of border classes. Borders add to element dimensions (breaks layouts), while outlines overlay without affecting size. Elements should size consistently based on content and padding only.hover:[&>svg]:opacity-50 break the design system. Use supported React Aria variants or conditional class rendering with clsx.@layer components.l1, @layer components.l2 for cascade hierarchy. Bypassing layers causes specificity wars and makes overrides unpredictable.bg-surface-default, fg-primary-bold) in components. The utility classes (bg-*, fg-*, icon-*, outline-*) provide fallback access to domain-* and primitive-* tokens for rare cases where designs go beyond the design system, but this should be exceptional. Semantic tokens provide theming flexibility and design system consistency.@apply statement. Multiple @apply directives prevent Tailwind IDE plugins from sorting classes and identifying issues. Write @apply bg-surface-default outline-1 outline-interactive p-m; not separate @apply lines.@variant directive blocks, not attribute selectors like [data-size="small"]. Write @variant size-small { @apply p-s; } not .button[data-size="small"] { @apply p-s; }. The @variant directive automatically applies styles when the matching data attribute is present.@reference '#globals'; (if custom entrypoint exists) or @reference '@accelint/design-foundation/styles'; at the top. Without this, semantic tokens and @variant blocks are undefined, causing build errors.@accelint/postcss-tailwind-css-modules plugin is required in postcss.config.mjs. Without it, named group selectors (like group-hover/button:) and @variant selectors fail to resolve in CSS modules.@accelint/design-foundation/lib/utils instead: import { clsx } from '@accelint/design-foundation/lib/utils';. The design foundation re-exports clsx with additional type support and design system integration. Importing directly bypasses these enhancements.Apply these tests to ensure styling aligns with the design system:
@variant light and @variant dark.bg-surface-default, fg-primary-bold). Only use domain-* or primitive-* fallbacks for exceptional cases where design goes beyond the system.domain-* or primitive-* is acceptable but rare.When choosing a token, follow this decision tree:
Example: "I need text color for a primary heading"
→ Purpose: text (fg-*)
→ Hierarchy: primary with emphasis (primary-bold)
→ Result: fg-primary-bold
Example: "I need background for an interactive button in hover state"
→ Purpose: background (bg-*)
→ State: interactive hover (interactive-bold-hover)
→ Result: bg-interactive-bold-hover
xxs/xs/s/m/l/xl/xxl/oversized scale. If a value isn't in the scale, question whether it's needed or use the closest semantic value.p-1, m-12) work with 1:1 relationship (p-1 = 1px, NOT 4px), but only use for rare non-conforming design cases. Semantic scale is strongly preferred for consistency.data-color="info" with supported variants instead of arbitrary classes.className or classNames props, not custom CSS files.@accelint/postcss-tailwind-css-modules plugin is in postcss.config.mjs. Without it, named groups and @variant selectors won't work in CSS modules..module.css file must reference either '#globals' (custom entrypoint) or '@accelint/design-foundation/styles' at the top.CRITICAL: Design foundation requires specific PostCSS and CSS module configuration to work correctly.
Create or update postcss.config.mjs in project root:
export default {
plugins: {
'@tailwindcss/postcss': {},
'@accelint/postcss-tailwind-css-modules': {}, // Required for CSS modules
},
};
Why: The @accelint/postcss-tailwind-css-modules plugin fixes named group resolution in CSS module selectors (e.g., group-hover/button:) and @variant selectors. Without it, these selectors fail to resolve correctly in CSS module files.
If the project implements a custom CSS entrypoint for token/utility configuration:
{
"imports": {
"#globals": "./src/styles/globals.css"
}
}
Purpose: Allows CSS modules to reference the custom entrypoint via @reference '#globals';
Every CSS module file must include a reference directive:
/* If project has custom CSS entrypoint (defined in package.json imports): */
@reference '#globals';
@layer components.l1 {
.button {
@apply px-m py-xs;
}
}
/* If NO custom CSS entrypoint, reference design-foundation directly: */
@reference '@accelint/design-foundation/styles';
@layer components.l1 {
.button {
@apply px-m py-xs;
}
}
Why: The @reference directive imports the design system's tokens, utilities, and variant definitions. Without it, semantic tokens and @variant blocks are undefined.
If implementing custom tokens or utilities, create a CSS entrypoint (e.g., src/styles/globals.css):
/* Import design foundation base */
@import "@accelint/design-foundation/styles";
/* Add custom token overrides or utilities here */
@theme {
--custom-brand-color: #ff0000;
}
Then: Import this file as the first import in your root layout component:
import './styles/globals.css'; // First import
import { ReactNode } from 'react';
export default function RootLayout({ children }: { children: ReactNode }) {
return <html>{children}</html>;
}
This skill uses progressive disclosure to minimize context usage:
Follow the styling patterns and token usage below for consistent implementation.
Load AGENTS.md for quick reference of available tokens, spacing scale, and variant patterns.
MANDATORY loading triggers - Load these references in specific scenarios:
Setting up design foundation for the first time:
Choosing tokens or understanding token hierarchy:
Working with @variant system or component variants:
Understanding spacing scale or numeric fallbacks:
Migrating from vanilla Tailwind:
Troubleshooting build errors or setup issues:
Default approach: Component styles in CSS modules with @apply directives.
user-card.module.css:
@layer components.l1 {
/* ✅ Single @apply per rule - enables IDE plugin support */
.card {
@apply bg-surface-default outline-1 outline-interactive shadow-elevation-raised-muted p-m;
}
.header {
@apply flex items-center justify-between mb-s;
}
.title {
@apply fg-primary-bold text-body-l;
}
.content {
@apply space-y-xs mb-m;
}
.email {
@apply fg-primary-bold text-body-m;
}
.role {
@apply fg-primary-muted text-body-s;
}
.actions {
@apply flex gap-s;
}
}
/* ❌ Wrong - multiple @apply directives break IDE plugins */
/*
.card {
@apply bg-surface-default;
@apply outline-1 outline-interactive;
@apply shadow-elevation-raised-muted;
@apply p-m;
}
*/
user-card.tsx:
import styles from './user-card.module.css';
export function UserCard({ name, email, role }) {
return (
<article className={styles.card}>
<header className={styles.header}>
<h3 className={styles.title}>{name}</h3>
</header>
<div className={styles.content}>
<p className={styles.email}>{email}</p>
<p className={styles.role}>{role}</p>
</div>
</article>
);
}
Inline classes only for one-off overrides:
// ✅ Correct - CSS module + inline override for specific instance
<UserCard className="mb-xl" /> {/* One-off spacing adjustment */}
// ❌ Wrong - all styling inline
<div className="bg-surface-default outline-1 outline-interactive shadow-elevation-raised-muted p-m">
<h3 className="fg-primary-bold text-body-l">{name}</h3>
</div>
Conditional classes with clsx:
// ✅ Correct - import clsx from design foundation
import { clsx } from '@accelint/design-foundation/lib/utils';
import styles from './Button.module.css';
export function Button({ variant, isActive }) {
return (
<button className={clsx(styles.button, isActive && styles.active)}>
Click me
</button>
);
}
// ❌ Wrong - importing directly from clsx package
import clsx from 'clsx';
Background tokens (bg-*):
bg-surface-default - Primary surface (page/card background)bg-surface-raised - Raised/elevated surfacebg-interactive-bold - Primary action backgroundbg-info-muted - Info message backgroundsbg-advisory-muted - Warning message backgroundsbg-critical-muted - Error/danger message backgroundsbg-normal-muted - Success message backgroundsForeground tokens (fg-*):
fg-primary-bold - Primary text (headlines, body text)fg-primary-muted - Subtle text (captions, secondary content)fg-inverse-bold - Text on dark/colored backgroundsfg-accent-primary-bold - Interactive text/linksfg-critical-bold - Error/danger textOutline tokens (outline-*):
outline-interactive - Interactive outlines (buttons, inputs)outline-static - Static outlines (borders, dividers)outline-info-bold - Info state outlinesoutline-advisory-bold - Warning state outlinesoutline-critical-bold - Error/danger state outlinesToken fallback pattern:
// ✅ Preferred - semantic tokens
<div className="bg-surface-default fg-primary-bold">Content</div>
// ⚠️ Acceptable but rare - domain/primitive fallback for edge cases
<div className="bg-domain-brand fg-primitive-blue-500">
{/* Use only when design exceeds system */}
</div>
// ❌ Wrong - using fallbacks when semantic tokens exist
<div className="bg-primitive-neutral-100 fg-primitive-neutral-900">
{/* Should use bg-surface-default fg-primary-bold */}
</div>
Eight-step semantic scale: xxs → xs → s → m → l → xl → xxl → oversized
Think semantic meaning, not pixels. m means "medium for this context", not a specific pixel value.
CSS module usage:
.button {
@apply px-m py-xs; /* ✅ Semantic spacing - preferred */
}
.card {
@apply p-m space-y-s; /* ✅ Semantic scale for consistency */
}
/* ⚠️ Acceptable but rare - numeric fallback for edge cases */
.nonStandardLayout {
@apply p-13; /* 13px exactly - use only for non-conforming designs */
/* Note: p-1 = 1px (not 4px like vanilla Tailwind) */
}
Spacing fallback pattern:
p-m, gap-s, mb-l)Prefer outlines - they don't affect element dimensions.
/* ✅ Correct - outline doesn't impact layout */
.card {
@apply outline-1 outline-interactive;
}
/* ❌ Wrong - border adds to dimensions */
.card {
@apply border-2 border-gray-300;
}
Use borders only when:
Use data attributes for component variants:
Button.module.css:
@layer components.l1 {
.button {
@apply px-m py-xs;
}
}
@layer components.l2 {
/* ✅ Use @variant blocks for conditional styling */
.button {
@variant color-info {
@apply bg-interactive-bold fg-inverse-bold;
}
@variant color-critical {
@apply outline-2 outline-critical-bold fg-critical-bold;
}
@variant size-large {
@apply px-l py-s;
}
}
}
/* ❌ Wrong - attribute selectors */
/*
.button[data-color="primary"] {
@apply bg-interactive-bold;
}
*/
Button.tsx:
import styles from './Button.module.css';
export function Button({ children, color = 'primary', size = 'medium' }) {
return (
<button
className={styles.button}
data-color={color}
data-size={size}
>
{children}
</button>
);
}
Common variants:
data-color: info, success, warning, dangerdata-size: small, medium, largedata-state: active, disabled, loadingAlways use layers in CSS modules:
/* ✅ Correct - layered for predictable specificity */
@layer components.l1 {
.base-styles { /* Base component styles */ }
}
@layer components.l2 {
.variant-styles { /* Variant styles */ }
}
@layer components.l3 {
.state-styles { /* State styles */ }
}
/* ❌ Wrong - no layers causes specificity issues */
.component {
background: var(--bg-surface-default);
}
Layer order: l1 (base) < l2 (variants) < l3 (states)
Use className prop for overrides:
// ✅ Correct - override with inline class
<DesignToolkitButton className="mb-l">
Action
</DesignToolkitButton>
// ✅ Correct - use classNames prop for internal elements
<DesignToolkitButton classNames={{ icon: 'icon-override' }}>
Action
</DesignToolkitButton>
Cause: Missing @reference directive in CSS module.
Fix: Add @reference '#globals'; or @reference '@accelint/design-foundation/styles'; at the top of the CSS module file.
/* ✅ Correct */
@reference '@accelint/design-foundation/styles';
@layer components.l1 {
.card {
@apply bg-surface-default; /* Now defined */
}
}
Cause: Missing @reference directive or PostCSS plugin not configured.
Fix 1: Verify @reference directive exists at top of CSS module.
Fix 2: Check postcss.config.mjs includes @accelint/postcss-tailwind-css-modules plugin:
export default {
plugins: {
'@tailwindcss/postcss': {},
'@accelint/postcss-tailwind-css-modules': {}, // Add this
},
};
Cause: Missing @accelint/postcss-tailwind-css-modules plugin.
Fix: Add plugin to postcss.config.mjs (see above).
Cause: CSS entrypoint not imported or imported too late.
Fix: Ensure globals.css (or @accelint/design-foundation/styles) is the FIRST import in root layout:
// ✅ Correct order
import './styles/globals.css'; // First
import './other-styles.css';
import Component from './Component';
// ❌ Wrong order
import Component from './Component';
import './styles/globals.css'; // Too late
Cause: Missing package.json imports field or path incorrect.
Fix: Add imports to package.json:
{
"imports": {
"#globals": "./src/styles/globals.css"
}
}
Or change @reference to direct path:
@reference './styles/globals.css';
Or use design-foundation directly:
@reference '@accelint/design-foundation/styles';
var(--bg-surface-default). They can be used in custom CSS when utilities aren't sufficient, but prefer utilities.bg-*, fg-*, icon-*, outline-*) check semantic tokens first, then fall back to domain-* and primitive-* tokens. This fallback is intentional for rare cases where designs exceed the design system, but semantic tokens should be the default choice for consistency and theming.@theme static and @variant light/dark syntax is custom. Don't confuse with standard CSS media queries. Themes are applied via class/attribute on root element.className and classNames props.