AgentStack
SKILL verified MIT Self-run

Angora Design System Audit

skill-aysnc-labs-angora-angora-design-system-audit · by Aysnc-Labs

Review any component (`src/components/`), design-system page, layout specimen, or site page (`src/pages/*.astro`) against Angora's design rules — semantic token usage (no raw palette classes), `data-component` attributes, landmark vs content classification, heading ownership, flow spacing, container queries, accessibility extras not caught by `pnpm test:a11y`, and anti-patterns from `src/system.m…

No reviews yet
0 installs
11 views
0.0% view→install

Install

$ agentstack add skill-aysnc-labs-angora-angora-design-system-audit

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Angora Design System Audit? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Audit: $ARGUMENTS

Before you start

  1. Read src/system.md — intent, accessibility standard, anti-patterns, decisions log.
  2. Read src/styles/global.css — the token definitions you're validating against.
  3. Read [design-principles.md](../docs/design-principles.md) — the full set of design principles informing this review.
  4. Read [tailwind-conventions.md](../docs/tailwind-conventions.md) — Tailwind v4 syntax rules to validate against.
  5. Determine the audit scope — is the target a component (src/components/), a design system page (src/pages/design-system/), a layout (src/pages/design-system/layouts/), or a site page (src/pages/*.astro)? Some rules only apply to specific scopes (marked below). Layouts are full-page compositions — audit them like site pages (Page Rules apply) but note they use placeholder content, so skip SEO checks.

Then validate the target against the rules below.

Hard Rules (always enforced)

Tokens & Scoping

| Rule | Check | |------|-------| | Token compliance | No arbitrary values. All styling via Tailwind utility classes referencing theme tokens | | Semantic token enforcement | No raw palette utility classes. Components and pages must use only semantic token classes (bg-background, bg-card, text-foreground, text-muted-foreground, border-border, bg-primary, etc.). Grep for violations: bg-gray-*, text-gray-*, border-gray-*, bg-white, text-white, bg-black, text-black, bg-primary-[0-9], text-primary-[0-9], border-primary-[0-9] (raw scale references). The primitive palette lives outside @theme so these classes shouldn't exist — but inline styles, arbitrary values (bg-[#...], text-[var(--gray-*)]), and accidental palette references still need catching. Exception: style guide page (index.astro) uses inline style attributes with var(--gray-50) etc. for palette swatches — this is intentional | | Pixel translation | No hard-coded pixel values in components. User-provided pixel values should map to the nearest theme token (e.g., "32px" → spacing-8 / p-8). If no token fits, use rem for sizing and em for prose-relative spacing. Flag any arbitrary [Xpx] values | | Scoping | Component styles via Tailwind classes on elements. No global CSS selectors in component files | | No true black | Never #000, rgb(0,0,0), or black. Use semantic tokens (text-foreground, bg-foreground) which resolve to near-black | | No generated colors | No color-mix(), lighten(), darken(), or rgba() for text on colored backgrounds. All colors from semantic tokens or explicit palette values |

Component Contracts

| Rule | Check | |------|-------| | Component naming | Component names must follow the generic UI pattern, not a use case. Flag components named after their content (e.g., FAQ instead of Accordion, Testimonials instead of Carousel). The name should be reusable | | data-component with flow attributes | Every component's root element has data-component="Name" (PascalCase). Sub-components too (data-component="CardBody"). Attribute appears first in the attribute list. Landmark components also set flow participation attributes (data-seamless, data-full-width) on their root element | | Landmark components | Landmark components (Hero, Footer, Nav) live on their own without a Section. They render their own semantic element (`, , ) with data-component and flow attributes. Flag landmarks wrapped in | | Content components | Content components render a @container wrapper div as their root so container queries work anywhere. They do NOT compose Section internally. Flag content components that import or render Section internally | | Heading ownership | Content components must not accept a heading or title prop — a parent provides the section heading. Content headings that are part of internal layout are fine as sub-components | | No outer vertical margin | Landmark and content components never set margin-top/margin-bottom on their outermost element. That's the flow context's (section-flow/prose-flow) job. Flag any mt-/mb-/my-* on a component's root | | Content props on composite shells | Composite shells must have zero content props — content flows exclusively through sub-components. Flag any string or array prop on a composite shell that represents displayable content (headings, descriptions, legal text, nav links). Even "simple" string props must be sub-components. Landmarks are not exempt | | No visual content via props | Visual content flows via children and sub-components, never as props. Flag any prop that passes markup or rendered content (named slots used to pass styled markup into the shell where a sub-component should be used instead). The shell's only job is layout and behavior — content ownership belongs to sub-components | | Images as | All imagery uses elements with object-fit: cover where needed. No CSS background-image for content images (heroes, cards, full-bleed sections). Position with absolute inset-0 inside a relative container for backdrops | | States | All components interactive by default (pseudo-class variants for hover:, active:, focus-visible: + transitions). Form state` prop only for non-interactive states (error, success, disabled). Composites: own variants only, child primitives in default state |

ARIA & Accessibility

Contrast ratios and ARIA labeling are covered by the automated a11y test suite (pnpm test:a11y). When dark mode exists, tests run against both /view/light/* and /view/dark/* routes — each mode must independently meet AA. The audit focuses on what automated testing can't catch:

| Rule | Check | |------|-------| | Target sizes | Interactive targets ≥ 44px. Check at narrow widths too | | Color independence | Don't rely on color alone to convey meaning — always a secondary indicator (icon, text, border, pattern) | | EAA extras (manual) | If standard is EAA: verify text spacing override tolerance, 200% text resize. (lang and reflow are covered by the a11y test) | | Dark mode contrast | If dark mode exists: verify semantic token pairs provide sufficient contrast in both modes. Check that --color-*-foreground has ≥ 4.5:1 contrast against its paired --color-* in both light and dark values. The a11y test catches most issues, but token-level mismatches (e.g., light primary text on light primary bg) need manual verification when new tokens are added |

Semantic HTML

| Rule | Check | |------|-------| | Semantic elements | Content uses semantic elements (section, nav, h1h6, p, a, button, input, figure, blockquote, ul/ol, footer). No ` where a semantic element fits | | Heading hierarchy | Heading levels don't skip (no h1h3). Components accept an as` prop or similar for heading level flexibility |

Responsive

| Rule | Check | |------|-------| | Container query syntax | Responsive variants use @sm:, @md:, @lg:, @xl: (container queries). No @media / no viewport-based sm:/md:/lg: in component markup. Only exception: design-system.css (tooling) | | Responsive behavior | Component actually adapts at narrow (~320px), medium (~768px), and wide (~1280px) container widths. Check: multi-column layouts stack to single column; text doesn't overflow or clip; interactive targets stay ≥ 44px; images/media scale without breaking aspect ratio; spacing reduces proportionally at narrow widths | | @container ancestor | Content components provide their own @container wrapper. Section provides @container on its root ` element. For inline content inside Section, Section's @container is sufficient. Flag content components that use container query variants (@sm:, @md:, @lg:) but don't have their own @container` wrapper |

Design Rules (always enforced, require judgment)

Hierarchy

| Rule | Check | |------|-------| | Three-tier emphasis | Clear primary/secondary/tertiary emphasis using size + weight + color together | | Three-tier text color | Exactly three text color tiers: text-foreground (or text-card-foreground) for primary content, text-muted-foreground for secondary/tertiary. Flag any raw grey class usage — semantic tokens enforce the correct tiers. If a third visual tier is needed, use font size or weight rather than an additional color | | Font weight discipline | Only two weights: normal (font-normal/font-medium, 400–500) and bold (font-semibold/font-bold, 600–700). Flag font-thin, font-extralight, font-light (under 400) | | Label treatment | Labels should be de-emphasized (smaller, lighter, thinner). Combine labels and values when possible ("12 left in stock" not "In stock: 12") | | Grey on colored backgrounds | No grey text on colored backgrounds. On primary/destructive/colored surfaces, use the paired -foreground token (e.g., text-primary-foreground on bg-primary). Never use opacity-based text on colored backgrounds — it looks washed out |

Spacing

| Rule | Check | |------|-------| | Proximity grouping | Related elements closer together, groups further apart. No ambiguous spacing where the relationship between elements is unclear | | Generous whitespace | Err on the side of generous whitespace. Flag areas that feel cramped — especially padding inside cards, space between section heading and content |

Typography

| Rule | Check | |------|-------| | Line length | 45–75 characters. Use max-w-[Xch] (prefer ch units) on text containers. Constrain paragraphs independently if container has full-width elements | | Line height | Proportional to font size: 1.5–1.75 for body text, 1.0–1.2 for display/heading text. Wider content may need up to 2.0 | | text-wrap: balance | Headings (h1h4, display text) should have text-wrap: balance to prevent orphan lines. The prose utility applies this automatically | | text-wrap: pretty | Body text (p, li, blockquote) should have text-wrap: pretty to prevent single-word last lines. The prose utility applies this automatically | | Letter-spacing | Headlines should tighten tracking (tracking-tight or tracking-tighter). Small uppercase UI text (badges, eyebrows, nav labels under text-lg) should widen (tracking-wide). Display-size uppercase text (text-xl and above) keeps normal tracking — the large size already provides legibility. See system.md Conventions for the full letter-spacing policy | | Center-align limits | Center-aligned text only for very short blocks (1–3 lines). Body copy and longer text must be left-aligned. Flag centered paragraphs | | Tabular numbers | Numbers in tables, stats, and vertically-aligned contexts should use tabular-nums (font-variant-numeric: tabular-nums) |

Color

| Rule | Check | |------|-------| | Meaning, not decoration | Color communicates meaning. Greys for structure, color for emphasis and action | | Semantic color usage | Red for errors/destructive, yellow/amber for warnings, green for success. Don't repurpose semantic colors for decoration |

Depth

| Rule | Check | |------|-------| | Consistent application | Similar elements at the same elevation. Light source from above. In dark mode, tonal elevation (lighter surface = higher) conveys depth — shadows have reduced visibility | | Shadow interaction | Interactive elevated elements: hover increases shadow (lift), active decreases shadow (press). Flag elevated buttons/cards without shadow transitions | | Fewer borders | Prefer box shadows, different background colors, or extra spacing over borders for visual separation. Flag heavy border usage where a subtler technique would work |

Page Rules (site pages and layouts — src/pages/*.astro and src/pages/design-system/layouts/)

Skip this section when auditing components or design system specimen pages.

| Rule | Check | |------|-------| | Flow context | Pages use ` for inter-section spacing. Posts/articles use | | Manual typography in content zones | Flag manual typography classes on , , inside content zones — prose handles these. Only flag inside section-flow or prose-flow zones where ambient prose applies | | Blockquote prose protection | Blockquotes inside prose zones need protection via data-component (prose targets blockquote:not([data-component])) or explicit counter-declarations (border-l-0 pl-0 not-italic) | | List prose protection | UI lists (navigation, tags, non-content lists) inside prose zones must have list-none p-0 to override prose's list styles. Content lists that should have bullets need no override | | Landmark vs content wrapping | Landmark components (Hero, Footer, Nav) live on their own in section-flow — don't wrap them in . Content components sit inside | | Section component | Content sections on the page use the Section component. No raw elements with manual padding for content sections | | Seamless usage | Sections with background colors/images use (or the landmark's flow attributes). Adjacent seamless sections should butt up (0 gap) | | Background rhythm | Page has visual rhythm — some variation in section backgrounds (alternating light/dark, or strategic use of color). Flag a page where every section is the same plain background | | Composition purity — single file | Design system layout directories (src/pages/design-system/layouts/) must contain only one .astro file. Flag extra files | | Composition purity — zero classes | In layouts and site pages, no Tailwind utility classes on raw HTML elements. Only section-flow on is allowed. If a needs a class, a component is missing | | Composition purity — no client code | Flag inline tags in layouts and site pages. Use Preact islands via components instead | | Composition drift | When auditing a layout that has a corresponding site page (or vice versa), check for structural divergence — different section order, missing/extra sections, different component usage. Copy differences are expected (placeholder vs real content). Structural differences are a bug | | SEO | Site pages (not layouts) have , . Template-driven pages wire SEO from table fields (metatitle, metadescription`). Flag missing OG tags on public-facing pages |

Soft Rules

  • Anti-pattern violations — anything listed in system.md Anti-Patterns section.
  • Pattern consistency — does this component follow the conventions established by existing components? Read 2–3 peers to compare.
  • Personality alignment (swap test) — could you swap this component's styling for the most generic version and the design wouldn't feel different? If yes, it's defaulting — flag it.
  • Prose utilityprose is applied at the ` level as an ambient typography baseline. Its descendant selectors use :where() for low specificity, so any Tailwind class on a component naturally overrides it. The only local prose usage is for nested content zones that need their own vertical rhythm. Components (cards, heroes) should NOT use prose — they own their spacing explicitly via gap-*` classes.
  • Finishing touches — are there opportunities to supercharge defaults? Custom list bullets, styled blockquotes, accent borders, subtle background decoration. Don't mandate these, but suggest where they'd elevate the work.

Output

Report all violations with: file path, line number, rule category, rule name, and suggested fix.

Severity levels:

  • Error — hard rule violation. Must fix.
  • Warning — design rule violation. Should fix — explain why.
  • Info — soft rule suggestion. Propose, don't mandate.

Group findings by file, then by severity. Fix all errors and warnings before showing components to the user.

Source & license

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

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

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.