mirror of
https://github.com/mblode/agent-skills.git
synced 2026-09-14 13:43:59 +08:00
first commit
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "mblode-agent-skills",
|
||||
"owner": {
|
||||
"name": "mblode"
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"name": "mblode-agent-skills",
|
||||
"source": ".",
|
||||
"description": "Design and frontend workflow skills for Claude Code."
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "mblode-agent-skills",
|
||||
"version": "0.1.0",
|
||||
"description": "Design and frontend workflow skills for Claude Code.",
|
||||
"repository": "https://github.com/mblode/agent-skills",
|
||||
"license": "MIT",
|
||||
"keywords": ["skills", "design", "frontend", "ui", "workflow"]
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
# OS
|
||||
.DS_Store
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Node (if used locally)
|
||||
node_modules/
|
||||
|
||||
# Env
|
||||
.env
|
||||
.env.*
|
||||
@@ -0,0 +1,35 @@
|
||||
# Repository Guidelines
|
||||
|
||||
## Project Structure & Module Organization
|
||||
- `skills/` holds each skill in its own folder (kebab-case). Each skill has a `SKILL.md` file with YAML frontmatter (`name`, `description`) and Markdown guidance.
|
||||
- Some skills include reference files alongside the `SKILL.md`, e.g. `skills/frontend-standards/typescript-patterns.md` or `skills/frontend-design/aesthetic-direction.md`.
|
||||
- Top-level files: `README.md` (overview and install docs) and `install.sh` (installer script).
|
||||
|
||||
## Build, Test, and Development Commands
|
||||
This repo has no build system; the main workflow is installing the skills bundle.
|
||||
|
||||
```bash
|
||||
./install.sh # install to $CODEX_HOME/skills or ~/.claude/skills
|
||||
./install.sh --dest /path # explicit destination
|
||||
DEST=/path ./install.sh # env-based destination
|
||||
```
|
||||
|
||||
Manual copy is also supported:
|
||||
|
||||
```bash
|
||||
cp -R skills/* /path/to/skills/
|
||||
```
|
||||
|
||||
## Coding Style & Naming Conventions
|
||||
- Files are Markdown-first. Keep `SKILL.md` concise with clear headings and short bullet points.
|
||||
- Use YAML frontmatter at the top of every `SKILL.md` with `name` and `description` fields.
|
||||
- Prefer kebab-case for folder and reference file names (`frontend-standards`, `react-patterns.md`).
|
||||
- When detail is needed, add a focused reference file rather than expanding `SKILL.md`.
|
||||
|
||||
## Testing Guidelines
|
||||
There is no automated test suite. Smoke-check changes by running `./install.sh` and confirming the target folder contains the updated skill files.
|
||||
|
||||
## Commit & Pull Request Guidelines
|
||||
- Commit messages are short, imperative, and sentence case (e.g., “Update install URL and copyright”).
|
||||
- PRs should include a brief summary, list of skills changed/added, and any README updates (especially when adding a new skill).
|
||||
- If you add new reference files, note how they are used by the corresponding `SKILL.md`.
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Matthew Blode
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,43 @@
|
||||
# Design skills
|
||||
|
||||
A minimal set of skills for high-quality UI and frontend work.
|
||||
|
||||
## Install
|
||||
|
||||
### Claude Code
|
||||
|
||||
Install via plugin marketplace:
|
||||
|
||||
```
|
||||
/plugin marketplace add mblode/agent-skills
|
||||
/plugin install mblode-agent-skills@mblode-agent-skills
|
||||
```
|
||||
|
||||
Restart Claude Code to pick up new skills.
|
||||
|
||||
For project scope without plugins, copy `skills/` into `.claude/skills`. For personal scope, copy into `~/.claude/skills`.
|
||||
|
||||
### Codex
|
||||
|
||||
Use the built-in installer for a single skill:
|
||||
|
||||
```
|
||||
$skill-installer https://github.com/mblode/agent-skills/tree/main/skills/design-principles
|
||||
```
|
||||
|
||||
For project scope, copy `skills/` into `.codex/skills`. For personal scope, copy into `$CODEX_HOME/skills` (or `~/.codex/skills`). Restart Codex to pick up new skills.
|
||||
|
||||
## Skills included
|
||||
|
||||
- design-principles
|
||||
- frontend-design
|
||||
- craft-checklist
|
||||
- animation-guidelines
|
||||
- frontend-standards
|
||||
- fullstack-architecture
|
||||
- repository-workflow
|
||||
- flawless-typography
|
||||
|
||||
## Contributing
|
||||
|
||||
Edit the files in `skills/`. Keep `SKILL.md` concise and use reference files for detail.
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
name: animation-guidelines
|
||||
description: Motion standards for UI interactions. Use when implementing animations, hover states, transitions, or motion design.
|
||||
---
|
||||
|
||||
# Animation Guidelines
|
||||
|
||||
Apply consistent motion rules for UI interactions.
|
||||
|
||||
## Core rules
|
||||
- Animate to clarify cause/effect or add deliberate delight.
|
||||
- Keep interactions fast (200-300ms; up to 1s only for illustrative motion).
|
||||
- Prefer CSS; use WAAPI or JS only when needed.
|
||||
- Make animations interruptible and input-driven.
|
||||
- Honor `prefers-reduced-motion` (reduce or disable).
|
||||
|
||||
## What to animate
|
||||
- Only `transform` and `opacity`.
|
||||
- Never animate layout properties; never use `transition: all`.
|
||||
- Avoid blur > 20px.
|
||||
- Disable transitions during theme switches.
|
||||
|
||||
## Spatial and sequencing
|
||||
- Set `transform-origin` at the trigger point.
|
||||
- For dialogs/menus, start around `scale(0.85-0.9)`; avoid `scale(0)`.
|
||||
- Stagger reveals <= 50ms.
|
||||
|
||||
## Easing defaults
|
||||
- Enter/hover: `cubic-bezier(0.22, 1, 0.36, 1)`.
|
||||
- Move: `cubic-bezier(0.25, 1, 0.5, 1)`.
|
||||
- Simple hover color/opacity: `200ms ease`.
|
||||
|
||||
## Accessibility
|
||||
- If `transform` is used, disable it in `prefers-reduced-motion`.
|
||||
|
||||
## Performance
|
||||
- Pause looping animations off-screen.
|
||||
- Toggle `will-change` only during heavy motion and only for `transform`/`opacity`.
|
||||
- Prefer `transform` over positional props in animation libraries.
|
||||
|
||||
## Reference
|
||||
- See `animation-examples.md` for code snippets, easing tables, and motion recipes.
|
||||
@@ -0,0 +1,247 @@
|
||||
# Animation Examples and Reference
|
||||
|
||||
Use these snippets and references when implementing rules from `animation-guidelines`.
|
||||
|
||||
## Contents
|
||||
- Principles examples
|
||||
- What to animate examples
|
||||
- Spatial rules and stagger
|
||||
- Easing reference
|
||||
- Hover transitions
|
||||
- Accessibility and reduced motion
|
||||
- Origin-aware animations
|
||||
- Performance recipes
|
||||
|
||||
## Principles examples
|
||||
```css
|
||||
/* Panel.module.css */
|
||||
.panel {
|
||||
transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1),
|
||||
opacity 220ms cubic-bezier(0.22, 1, 0.36, 1);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.panel {
|
||||
transition-duration: 1ms;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
// app/components/Panel.tsx
|
||||
"use client";
|
||||
import { motion } from "framer-motion";
|
||||
import styles from "./Panel.module.css";
|
||||
|
||||
export function Panel() {
|
||||
return (
|
||||
<motion.div
|
||||
className={styles.panel}
|
||||
whileHover={{ scale: 1.02 }}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
transition={{ duration: 0.2, ease: [0.22, 1, 0.36, 1] }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## What to animate examples
|
||||
```css
|
||||
/* Toast.module.css */
|
||||
.toast {
|
||||
transform: translate3d(0, 6px, 0);
|
||||
opacity: 0;
|
||||
transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1),
|
||||
opacity 220ms cubic-bezier(0.22, 1, 0.36, 1);
|
||||
}
|
||||
.toast[data-open="true"] {
|
||||
transform: translate3d(0, 0, 0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Disable transitions during theme switch */
|
||||
[data-theme-switching="true"] * {
|
||||
transition: none !important;
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
// app/components/Toast.tsx
|
||||
"use client";
|
||||
import clsx from "clsx";
|
||||
import styles from "./Toast.module.css";
|
||||
|
||||
export function Toast({ open }: { open: boolean }) {
|
||||
return (
|
||||
<div className={clsx(styles.toast)} data-open={open}>
|
||||
Saved
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Spatial rules and stagger
|
||||
```css
|
||||
/* Menu.module.css */
|
||||
.menu {
|
||||
transform-origin: top right;
|
||||
transform: scale(0.88);
|
||||
opacity: 0;
|
||||
transition: transform 200ms cubic-bezier(0.22, 1, 0.36, 1),
|
||||
opacity 200ms cubic-bezier(0.22, 1, 0.36, 1);
|
||||
}
|
||||
.menu[data-open="true"] {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.list > * {
|
||||
animation: fade-in 220ms cubic-bezier(0.22, 1, 0.36, 1) both;
|
||||
}
|
||||
.list > *:nth-child(2) { animation-delay: 50ms; }
|
||||
.list > *:nth-child(3) { animation-delay: 100ms; }
|
||||
```
|
||||
|
||||
```tsx
|
||||
const listVariants = {
|
||||
show: { transition: { staggerChildren: 0.05 } },
|
||||
};
|
||||
```
|
||||
|
||||
## Easing reference
|
||||
- Default to `ease-out` for most animations.
|
||||
- Do not use built-in easings unless it is `ease` or `linear`.
|
||||
- Enter: `cubic-bezier(0.22, 1, 0.36, 1)` (ease-out).
|
||||
- Move: `cubic-bezier(0.25, 1, 0.5, 1)` (ease-in-out).
|
||||
- `ease-in` (avoid; feels slow):
|
||||
- `ease-in-quad`: `cubic-bezier(.55, .085, .68, .53)`
|
||||
- `ease-in-cubic`: `cubic-bezier(.550, .055, .675, .19)`
|
||||
- `ease-in-quart`: `cubic-bezier(.895, .03, .685, .22)`
|
||||
- `ease-in-quint`: `cubic-bezier(.755, .05, .855, .06)`
|
||||
- `ease-in-expo`: `cubic-bezier(.95, .05, .795, .035)`
|
||||
- `ease-in-circ`: `cubic-bezier(.6, .04, .98, .335)`
|
||||
- `ease-out` (entering/interactions):
|
||||
- `ease-out-quad`: `cubic-bezier(.25, .46, .45, .94)`
|
||||
- `ease-out-cubic`: `cubic-bezier(.215, .61, .355, 1)`
|
||||
- `ease-out-quart`: `cubic-bezier(.165, .84, .44, 1)`
|
||||
- `ease-out-quint`: `cubic-bezier(.23, 1, .32, 1)`
|
||||
- `ease-out-expo`: `cubic-bezier(.19, 1, .22, 1)`
|
||||
- `ease-out-circ`: `cubic-bezier(.075, .82, .165, 1)`
|
||||
- `ease-in-out` (moving within screen):
|
||||
- `ease-in-out-quad`: `cubic-bezier(.455, .03, .515, .955)`
|
||||
- `ease-in-out-cubic`: `cubic-bezier(.645, .045, .355, 1)`
|
||||
- `ease-in-out-quart`: `cubic-bezier(.77, 0, .175, 1)`
|
||||
- `ease-in-out-quint`: `cubic-bezier(.86, 0, .07, 1)`
|
||||
- `ease-in-out-expo`: `cubic-bezier(1, 0, 0, 1)`
|
||||
- `ease-in-out-circ`: `cubic-bezier(.785, .135, .15, .86)`
|
||||
|
||||
### Drawer example
|
||||
```css
|
||||
.drawer {
|
||||
transition: transform 240ms cubic-bezier(0.25, 1, 0.5, 1);
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
<motion.aside
|
||||
initial={{ transform: "translate3d(100%, 0, 0)" }}
|
||||
animate={{ transform: "translate3d(0, 0, 0)" }}
|
||||
exit={{ transform: "translate3d(100%, 0, 0)" }}
|
||||
transition={{ duration: 0.24, ease: [0.25, 1, 0.5, 1] }}
|
||||
/>
|
||||
```
|
||||
|
||||
## Hover transitions
|
||||
- Use `ease` with `200ms` for simple hover transitions (`color`, `background-color`, `opacity`).
|
||||
- For complex hover motion, follow the easing rules above.
|
||||
- Disable hover transitions on touch devices via `@media (hover: hover) and (pointer: fine)`.
|
||||
|
||||
```css
|
||||
/* Link.module.css */
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
.link {
|
||||
transition: color 200ms ease, opacity 200ms ease;
|
||||
}
|
||||
.link:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Accessibility and reduced motion
|
||||
- If `transform` is used, disable it in `prefers-reduced-motion`.
|
||||
|
||||
```css
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.menu,
|
||||
.toast {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
"use client";
|
||||
import { motion, useReducedMotion } from "framer-motion";
|
||||
|
||||
export function AnimatedCard() {
|
||||
const reduceMotion = useReducedMotion();
|
||||
return (
|
||||
<motion.div
|
||||
animate={reduceMotion ? { opacity: 1 } : { opacity: 1, scale: 1 }}
|
||||
initial={reduceMotion ? { opacity: 1 } : { opacity: 0, scale: 0.98 }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Origin-aware animations
|
||||
- Elements should animate from the trigger; adjust `transform-origin` to the trigger position.
|
||||
|
||||
```css
|
||||
.popover[data-side="top"] { transform-origin: bottom center; }
|
||||
.popover[data-side="bottom"] { transform-origin: top center; }
|
||||
.popover[data-side="left"] { transform-origin: center right; }
|
||||
.popover[data-side="right"] { transform-origin: center left; }
|
||||
```
|
||||
|
||||
## Performance recipes
|
||||
- Pause looping animations off-screen.
|
||||
- Do not animate drag gestures using CSS variables.
|
||||
- Toggle `will-change` only during heavy animations.
|
||||
- Only use `will-change` for `transform`, `opacity`, `clipPath`, `filter`.
|
||||
- In Motion/Framer Motion, prefer `transform` over `x`/`y`.
|
||||
- Use springs by default; avoid bouncy springs unless dragging.
|
||||
|
||||
```css
|
||||
.animating {
|
||||
will-change: transform, opacity;
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
<motion.div
|
||||
animate={{ transform: "translate3d(0, 0, 0)" }}
|
||||
transition={{ type: "spring", stiffness: 500, damping: 40 }}
|
||||
/>
|
||||
```
|
||||
|
||||
```js
|
||||
// app/hooks/usePauseOffscreen.ts
|
||||
"use client";
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
export function usePauseOffscreen<T extends HTMLElement>() {
|
||||
const ref = useRef<T | null>(null);
|
||||
useEffect(() => {
|
||||
const el = ref.current;
|
||||
if (!el) return;
|
||||
const io = new IntersectionObserver(([entry]) => {
|
||||
el.style.animationPlayState = entry.isIntersecting ? "running" : "paused";
|
||||
});
|
||||
io.observe(el);
|
||||
return () => io.disconnect();
|
||||
}, []);
|
||||
return ref;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: craft-checklist
|
||||
description: Production polish checklist for UI work. Use when refining components, typography, accessibility, performance, or release readiness.
|
||||
---
|
||||
|
||||
# Craft Checklist
|
||||
|
||||
Run a final polish pass before shipping UI.
|
||||
|
||||
## Workflow
|
||||
- Apply the detailed checklist in `craft-checklist.md`.
|
||||
- Prioritize legibility, keyboard access, forms, navigation/feedback, resilience, performance, and accessibility.
|
||||
- Enforce only items relevant to the surface; avoid unnecessary polish.
|
||||
- When reviewing, cite file paths and line numbers and propose concrete fixes.
|
||||
|
||||
## Quick triage
|
||||
- Verify readable type sizes, line length, contrast, and distinct link styling.
|
||||
- Confirm keyboard access, visible focus, and hit targets >= 24px (>= 44px mobile).
|
||||
- Validate forms: labels, Enter/Cmd+Enter behavior, inline errors, no paste/typing blocks.
|
||||
- Check loading/empty/error states and avoid spinner flicker.
|
||||
- Ensure long content truncation (`min-w-0`, `line-clamp`) and safe-area handling.
|
||||
- Ensure motion follows `animation-guidelines` and respects reduced motion.
|
||||
|
||||
## Reference
|
||||
- See `craft-checklist.md` for the full checklist.
|
||||
@@ -0,0 +1,82 @@
|
||||
# Craft Checklist (Detailed)
|
||||
|
||||
Use this as a final polish pass.
|
||||
|
||||
## Legibility and typography
|
||||
- Use correct punctuation (quotes, apostrophes, dashes); use `…` for ellipsis.
|
||||
- Keep sentence case; avoid underlines except links.
|
||||
- Body size: 18-24px desktop, 14-19px mobile; line length 45-75 chars; line-height ~1.45.
|
||||
- Avoid letter-spacing on body; add slight tracking to all-caps and small labels.
|
||||
- Limit to <= 2 typefaces; weights >= 400; use `clamp()` for fluid sizes.
|
||||
- Use `font-variant-numeric: tabular-nums` for data; use monospaced or tabular numbers in tables.
|
||||
- Prevent widows/orphans; use `text-wrap: balance` or non-breaking spaces.
|
||||
- Use non-breaking spaces for glued terms (10 MB, Cmd + K, brand names).
|
||||
- Avoid pure black/white; improve contrast for links and text-on-images.
|
||||
- Avoid link hover effects that shift layout (no font-weight or size changes).
|
||||
- Enable `-webkit-font-smoothing` and `text-rendering: optimizeLegibility`.
|
||||
|
||||
## Motion
|
||||
- Validate against `animation-guidelines` (timing, easing, reduced motion, transform/opacity only).
|
||||
|
||||
## Keyboard, focus, and targets
|
||||
- Provide full keyboard support and visible focus styles.
|
||||
- Manage focus in dialogs/menus (trap, restore).
|
||||
- Hit targets >= 24px (>= 44px on mobile); if the visual target is smaller, expand the hit area.
|
||||
- Gate hover styles with `@media (hover: hover)`.
|
||||
- Never disable browser zoom (`user-scalable=no` / `maximum-scale=1`).
|
||||
- Use `touch-action: manipulation` on tap targets to prevent double-tap zoom.
|
||||
- Disable pointer events on decorative layers (glows, gradients).
|
||||
- If it looks clickable, it must be clickable; remove dead zones between items.
|
||||
- Avoid text selection during drag; use `inert` or disable selection where needed.
|
||||
|
||||
## Forms and input behavior
|
||||
- Label inputs; Enter submits; textarea uses Cmd/Ctrl+Enter.
|
||||
- Inputs must be hydration-safe (no lost focus/value after hydration).
|
||||
- Use correct `type`, `name`, `autocomplete`, and `inputmode`.
|
||||
- Disable spellcheck for emails/codes/usernames; avoid input names that trigger password managers when not needed.
|
||||
- Mobile input font size >= 16px; avoid autofocus on touch devices.
|
||||
- Do not block paste or typing; validate after input.
|
||||
- Show inline errors; focus the first error on submit.
|
||||
- Allow incomplete submission to surface validation; keep submit enabled until request starts, then disable with spinner and keep the original label.
|
||||
- Trim trailing whitespace from IME/text expansion to avoid false errors.
|
||||
- Ensure password managers and one-time codes work.
|
||||
|
||||
## Navigation and feedback
|
||||
- Use `<a>`/`<Link>` for navigation; preserve URL state; Back/Forward restores scroll.
|
||||
- Confirm destructive actions or provide undo.
|
||||
- Use polite `aria-live` for toasts/validation.
|
||||
- Add a short show-delay (150-300ms) and minimum duration (300-500ms) for spinners/skeletons to avoid flicker.
|
||||
- Use ellipsis for follow-ups and loading states (Rename…, Loading…).
|
||||
- Provide designed empty, loading, and error states.
|
||||
|
||||
## Resilience and layout
|
||||
- Use flex/grid; avoid JS measurement.
|
||||
- Respect safe areas and prevent unwanted scrollbars.
|
||||
- Use `overscroll-behavior: contain` in modals/drawers.
|
||||
- Ensure text truncation (`min-w-0`, `line-clamp`, `break-words`) and long content support.
|
||||
- Design for empty/sparse/dense states.
|
||||
- Use locale-aware formatting (`Intl.*`).
|
||||
|
||||
## Performance
|
||||
- Preload above-the-fold images and critical fonts; set explicit image dimensions.
|
||||
- Virtualize large lists.
|
||||
- Minimize re-renders; profile when needed.
|
||||
- Use `will-change` sparingly; avoid heavy blur and excessive video autoplay.
|
||||
|
||||
## Accessibility and theming
|
||||
- Prefer native semantics before ARIA.
|
||||
- Add `aria-label` to icon-only controls; mark decorative elements `aria-hidden`.
|
||||
- Do not attach tooltips to disabled controls; hover-tooltips should not contain interactive content.
|
||||
- Use `<img>` for images; HTML illustrations need an accessible name.
|
||||
- Provide redundant status cues (not color-only).
|
||||
- Provide skip link and heading hierarchy.
|
||||
- Do not animate during theme switches; set `color-scheme` and `<meta name="theme-color">`.
|
||||
- Guard hydration for date/time; `value` inputs require `onChange`.
|
||||
|
||||
## Extra polish
|
||||
- Match box-shadows and motion to high-quality references.
|
||||
- Add SEO metadata and dynamic OG images.
|
||||
- Add keyboard shortcuts where useful.
|
||||
|
||||
## Resources
|
||||
- Devouring Details, Sanding UI, Paul Graham on Taste, Typewolf checklist.
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
name: design-principles
|
||||
description: Minimal, precise design system for dashboards, admin tools, SaaS, and data-heavy UIs. Use when the UI must feel clean, crafted, and enterprise-grade.
|
||||
---
|
||||
|
||||
# Design Principles
|
||||
|
||||
## Scope
|
||||
- Use for SaaS/admin/dashboards and data-heavy tools.
|
||||
- For marketing or creative experiences, use `frontend-design`.
|
||||
|
||||
## Commit to a direction
|
||||
- Define product context, user type, and emotional goal.
|
||||
- Pick one dominant personality: precision/density, warm/approachable, trust/financial, bold/modern, utility/dev, data/analytics.
|
||||
- Choose a color foundation (warm, cool, neutral, tinted), light or dark, and a single accent.
|
||||
- Pick a layout approach: dense grid, spacious, sidebar, top nav, or split list-detail.
|
||||
- Choose typography that matches the product (system, geometric sans, humanist, mono).
|
||||
|
||||
## Core craft rules
|
||||
- Use a 4px spacing grid.
|
||||
- Keep padding symmetrical unless there is a clear visual reason.
|
||||
- Choose one radius system and use it everywhere.
|
||||
- Choose one depth strategy: borders-only, subtle shadow, layered shadow, or surface tint.
|
||||
- Keep surface treatment consistent across cards, even if internal layouts differ.
|
||||
|
||||
## Controls
|
||||
- Build custom selects/date pickers for styled UIs; avoid native styled controls.
|
||||
- For select triggers, use `inline-flex` + `white-space: nowrap`.
|
||||
|
||||
## Type and data
|
||||
- Create a clear hierarchy (headline, body, label).
|
||||
- Use tabular numbers or monospace for data tables and IDs.
|
||||
- Icons must add meaning; remove decorative icons.
|
||||
|
||||
## Color and contrast
|
||||
- Use a 4-level contrast hierarchy (primary, secondary, muted, faint).
|
||||
- Use color only for meaning (status, action).
|
||||
|
||||
## Navigation context
|
||||
- Show navigation, page location, and user/workspace context.
|
||||
- In dark mode, prefer borders over shadows; adjust semantic colors.
|
||||
|
||||
## Motion
|
||||
- Follow `animation-guidelines` and keep motion subtle for enterprise UI.
|
||||
|
||||
## Interaction baseline
|
||||
- Use `craft-checklist` for UX/a11y polish and `animation-guidelines` for motion.
|
||||
|
||||
## Anti-patterns
|
||||
- Heavy shadows, large radii on small controls, thick borders, gradients for decoration, multiple accents, glowing borders, excessive spacing, visual noise.
|
||||
|
||||
## Standard
|
||||
Aim for precise, minimal, and context-specific design.
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
name: flawless-typography
|
||||
description: Comprehensive typography checklist for UI implementation and reviews. Use when auditing or implementing typography, punctuation, type pairing, and readability.
|
||||
---
|
||||
|
||||
# Flawless Typography
|
||||
|
||||
Apply a disciplined typography audit for UI/web work.
|
||||
|
||||
## Workflow
|
||||
- Use `typography-checklist.md` as the source of truth.
|
||||
- Start with legibility: size, line length, line height, and contrast.
|
||||
- Enforce punctuation and numerals in user-facing copy.
|
||||
- Ensure real italics and required glyphs are loaded; avoid faux styles.
|
||||
- When reviewing, cite file paths and line numbers and propose concrete fixes.
|
||||
|
||||
## Quick triage
|
||||
- Replace straight quotes; use correct dashes and prime symbols.
|
||||
- Set base size and line length (45-75 chars) with line-height ~1.45.
|
||||
- Make link styling distinct and accessible.
|
||||
- Use tabular numbers for tables and data-heavy UI.
|
||||
- Avoid all-caps body; add tracking only to uppercase labels.
|
||||
- Prevent widows/orphans with `text-wrap: balance` or non-breaking spaces.
|
||||
|
||||
## Reference
|
||||
- See `typography-checklist.md` for the full checklist.
|
||||
@@ -0,0 +1,152 @@
|
||||
# Typography Checklist
|
||||
|
||||
Use this checklist to implement or review typography in UI/web work. Apply only the items that are relevant to the target surface.
|
||||
|
||||
## Contents
|
||||
- Checklist
|
||||
|
||||
## Checklist
|
||||
- [ ] Replace straight quotes/apostrophes with smart quotes; ensure UTF-8; normalize content at build/render time.
|
||||
- [ ] Enable smart quotes; treat primes as distinct; choose dash style (spaced en or unspaced em) and be consistent.
|
||||
- [ ] If em dash is too wide in the chosen face, switch to spaced en dashes for breaks.
|
||||
- [ ] Use en dash for ranges and em dash for attribution; never use double hyphens; use prime/double-prime glyphs (Unicode/entities).
|
||||
- [ ] Use multiplication sign and fraction entities; use accented characters correctly; avoid font subsetting; store accents as Unicode.
|
||||
- [ ] Ensure fonts include accents; use correct TM/RT superscripts and copyright inline; do not duplicate word + symbol.
|
||||
- [ ] Use non-breaking space between copyright symbol and year; use correct entities; use ampersands only for proper names/shorthand.
|
||||
- [ ] Use ampersands sparingly; prefer midpoints for inline separators over bars/bullets.
|
||||
- [ ] Use midpoints for horizontal list separators when appropriate.
|
||||
- [ ] Use the correct midpoint character with hair/thin spaces as needed; remove unnecessary punctuation and follow abbreviation rules.
|
||||
- [ ] Remove apostrophes from decades and periods from acronyms; choose sentence or title case for headings and apply consistently.
|
||||
- [ ] Auto-format titles per style guide; enforce single space after sentence-ending punctuation.
|
||||
- [ ] Audit copy for double spaces and remove them.
|
||||
- [ ] Ensure all sentence-ending punctuation is followed by exactly one space.
|
||||
- [ ] Use italics (not bold/all caps/quotes) for emphasis; prefer fonts with true italics for body text.
|
||||
- [ ] Limit emphasis; italicize publication titles; avoid underlines except for actual links.
|
||||
- [ ] Never underline for emphasis (print or web); use hanging punctuation only where feasible (blockquotes/display).
|
||||
- [ ] If using hanging punctuation, implement only where support exists; for web, limit to left edge and special cases.
|
||||
- [ ] Set body size first; use large desktop sizes (16-24px typical), smaller on mobile/print; adjust for x-height.
|
||||
- [ ] Avoid oversized desktop type; target mobile body 15-19px and print 10-12pt; scale headers down on mobile.
|
||||
- [ ] Keep line length 45-75 characters (66 ideal); adjust per breakpoint; avoid very long lines.
|
||||
- [ ] Measure line length including spaces; set line height around 1.45-1.5 and avoid excessive leading; use unitless values.
|
||||
- [ ] If a sans face has large x-height, add a bit more line spacing.
|
||||
- [ ] Adjust line height based on size/line length/x-height; choose body fonts with low contrast, large x-height, open apertures, large counters.
|
||||
- [ ] Prefer text-cut faces for body; avoid overly large x-height; select humanist/modern sans only if they meet legibility traits.
|
||||
- [ ] Load real regular/italic/bold/bold-italic styles to avoid faux; define `@font-face` per weight/style.
|
||||
- [ ] Ensure `@font-face` entries map the four styles to the same family with correct weights/styles.
|
||||
- [ ] Prefer true italics (not obliques); use WOFF2/variable fonts; drop least-used styles only if necessary.
|
||||
- [ ] Verify italics are true; use only regular/book/medium weights for body text.
|
||||
- [ ] Set body weight around 400-500; avoid ultra-light weights for longform; test cross-platform.
|
||||
- [ ] Use heavier weights only at large sizes; never use display faces for body copy.
|
||||
- [ ] Treat Display/Headline/etc as display-only; avoid display glyphs in body; ignore Caption cuts for web body.
|
||||
- [ ] Avoid long body text in monospaced fonts; reserve for short stylistic blocks.
|
||||
- [ ] Allow brief mono sections only; enable standard ligatures for body; keep discretionary ligatures off in body text.
|
||||
- [ ] Enable OpenType features for body: `kern`, `liga`, `clig`, `calt`.
|
||||
- [ ] Disable distracting ligatures (and in code); never letterspace body text except tiny captions or display lowercase.
|
||||
- [ ] Remember kerning vs letterspacing; add adequate padding/margins around paragraphs.
|
||||
- [ ] Ensure column padding and outer margins (including thumb space in print and mobile gutters).
|
||||
- [ ] Break long copy into readable paragraphs; avoid walls of text.
|
||||
- [ ] Use subheads/lists where useful; separate paragraphs by line breaks or indents, not both.
|
||||
- [ ] If using indents, apply only after the first paragraph (`p + p`) and size appropriately; keep paragraph spacing modest and responsive.
|
||||
- [ ] Set line height first, then adjust paragraph spacing; avoid paragraphs touching.
|
||||
- [ ] Place subheaders closer to the paragraph they introduce than to the preceding text.
|
||||
- [ ] Use extra spacing for large subheaders; avoid default center alignment except for intentional formal/large display.
|
||||
- [ ] If center-aligning text, increase line height and use sparingly.
|
||||
- [ ] Avoid justified text on the web; only justify with strong hyphenation support.
|
||||
- [ ] Never justify without hyphenation; avoid letterspacing in justification; use better hyphenation tools if required.
|
||||
- [ ] Add letterspacing to uppercase (about 0.1-0.2em) and adjust for size.
|
||||
- [ ] Increase spacing for small uppercase; avoid multi-line uppercase blocks.
|
||||
- [ ] Avoid uppercase paragraphs; do not letterspace or use optical kerning on monospaced or connected script fonts.
|
||||
- [ ] Keep spacing/kerning at metrics for mono/script; do not adjust tracking.
|
||||
- [ ] Use metrics kerning; add slight letterspacing only for tiny text; otherwise increase font size.
|
||||
- [ ] If letterspacing small text, also increase word spacing; avoid faux bold/italics by loading real styles.
|
||||
- [ ] Identify true italics; avoid faux styles in output; use real small caps when available, avoid pseudo.
|
||||
- [ ] Enable OpenType small caps via `font-feature-settings` and add slight tracking.
|
||||
- [ ] Avoid pseudo small caps; use small caps for abbreviations/subheads; manage widows/orphans with non-breaking spaces.
|
||||
- [ ] Insert non-breaking spaces in headlines/nav to prevent single-word lines; avoid overuse in paragraphs.
|
||||
- [ ] Use non-breaking spaces for short phrases/time/brands; use `white-space: nowrap` sparingly; never distort type; choose condensed/extended styles.
|
||||
- [ ] Do not stretch/squish body text; only distort logos if intentional; use condensed/extended variants instead.
|
||||
- [ ] Use tabular figures and right alignment in tables; enable `tnum` or use mono/system fonts.
|
||||
- [ ] Right-align table numbers, use commas; prefer tabular digits; use oldstyle figures in running text when available.
|
||||
- [ ] Enable `onum` for oldstyle or `lnum` for lining digits; use lining next to uppercase/UI.
|
||||
- [ ] Spell out 1-9 if desired; ensure text/background contrast (not necessarily pure black).
|
||||
- [ ] Avoid low-contrast light text; make links distinct from body text with color or underline.
|
||||
- [ ] Implement link styling with subtle underline/hover without layout shift.
|
||||
- [ ] Avoid using link color for non-links; design accessible link styles; be cautious with text over photos.
|
||||
- [ ] If using text on photos, enforce contrast (overlay or curated images) or avoid the pattern.
|
||||
- [ ] Avoid decorative hero photos that hurt readability/perf; when stacking vertical type, use uppercase.
|
||||
- [ ] Rotate vertical type clockwise and center-align; rely on built-in kerning; manually kern only for large display/logos.
|
||||
- [ ] Accept minor kerning irregularities; do not over-kern.
|
||||
- [ ] Use metrics kerning; adjust tracking before kerning; use hair/thin spaces where needed.
|
||||
- [ ] Use hair/thin spaces instead of no space or word space when spacing feels off.
|
||||
- [ ] Use ` `/` ` around em dashes/citations as needed; add horizontal padding between nav items.
|
||||
- [ ] Limit nav items; use CSS padding not spaces; indicate current nav item as selected/inactive (not others).
|
||||
- [ ] Keep selected nav readable; never gray navigable items; ensure list text does not wrap under bullets.
|
||||
- [ ] Use proper list markup (`<ul>/<ol>`); add vertical spacing for multi-line items.
|
||||
- [ ] If list item titles wrap, increase vertical padding and tighten line height so wrapped lines stay grouped.
|
||||
- [ ] Test lists with long content and narrow widths.
|
||||
- [ ] Swap display faces to text faces on small screens via media queries.
|
||||
- [ ] Identify display faces by naming; avoid for body; limit long light-on-dark text.
|
||||
- [ ] Use off-white text on dark backgrounds; reserve reversed type for appropriate contexts.
|
||||
- [ ] Edit copy for clarity; remove redundant UI text.
|
||||
- [ ] Start layout with body text; use modular scale as a guide, not a constraint.
|
||||
- [ ] Break the scale if optical fit demands it; prioritize readability over numeric purity.
|
||||
- [ ] Choose body size first; ensure strong size contrast (same or clearly different).
|
||||
- [ ] Avoid near-equal sizes; build hierarchy with weight/italics/caps/color, one axis at a time.
|
||||
- [ ] Use letterspaced caps/small caps for subheads; size caps down to avoid shouting.
|
||||
- [ ] Avoid header colors that match link colors; avoid all-italic headers; use CSS text-transform; keep heading levels shallow (h1-h3).
|
||||
- [ ] Use descriptive, skimmable headings (not generic).
|
||||
- [ ] As headings grow, reduce weight or lighten color for balance.
|
||||
- [ ] Lighten headers subtly; prefer darkened brand hues over flat gray.
|
||||
- [ ] Define and document a consistent type system; avoid random style changes; use grids but do not obsess over baseline grids.
|
||||
- [ ] Baseline grids are impractical for web; prioritize font size, line height, and line length.
|
||||
- [ ] Accept web fluidity; do not chase total control.
|
||||
- [ ] Trust your eye; vet typography frameworks; place captions/descriptions closer to the images they describe.
|
||||
- [ ] Use proximity/dividers to clarify associations; place dividers above headings, not below.
|
||||
- [ ] Remember dividers are rules; avoid underlining headings; choose hanging bullets only if they improve reading.
|
||||
- [ ] Decide between hanging vs indented bullets based on readability; indented often scans better.
|
||||
- [ ] Avoid hanging bullets on mobile; add vertical spacing between bullet items; balance layouts optically.
|
||||
- [ ] Optically center elements (slightly above true center); account for overshoot in round/pointed shapes.
|
||||
- [ ] Limit to two typefaces (body + display) unless you can manage a complex system.
|
||||
- [ ] If using more faces, enforce strict system; consider superfamilies for easy pairing.
|
||||
- [ ] Prefer serif/sans pairs from the same superfamily; use example list only as a starting point.
|
||||
- [ ] Avoid pairing two sans-serifs unless they are the same genre; serif + sans is safer.
|
||||
- [ ] Avoid pairing two serifs; if necessary, use strong contrast or the same family.
|
||||
- [ ] Avoid mixing modern and old-style serifs; pairing by the same designer can help.
|
||||
- [ ] Pair typefaces that harmonize or contrast strongly; avoid "almost the same" pairs.
|
||||
- [ ] Judge harmony by handwritten vs constructed feel; compare stress angles and skeletons.
|
||||
- [ ] Match stress direction to find harmony (e.g., vertical stress pairs).
|
||||
- [ ] Geometric sans pairs well with modern/rational serifs; ensure text legibility at small sizes.
|
||||
- [ ] Avoid geometric sans with old-style serif; pair grotesques/gothics with transitional serifs for classic feel.
|
||||
- [ ] Understand grotesque/grotesk/gothic naming; pair neo-grotesques with slab serifs.
|
||||
- [ ] Neo-grotesques are weak for body; slabs can be good; pair humanist sans with old-style serifs.
|
||||
- [ ] Humanist serif/sans share calligraphic traits; pair neo-humanist sans with contemporary serifs for screens.
|
||||
- [ ] Neo-humanist + contemporary serif are highly readable; treat pairing rules as guidance, not law.
|
||||
- [ ] Know rules before breaking them; pick UI fonts with distinct l/I/1 glyphs.
|
||||
- [ ] Check ambiguous glyphs (I/l/1); consider serifs for UI; use condensed faces for headlines when space is tight.
|
||||
- [ ] Use condensed/extra-condensed for headlines to control line breaks; avoid condensed for body.
|
||||
- [ ] Condensed faces can work for tight UI labels; when swapping fonts, re-tune size/line/spacing/padding.
|
||||
- [ ] If fonts are metrically compatible, swaps are easier; define strong fallback font stacks.
|
||||
- [ ] Test fallbacks and missing glyphs; ensure accent support; avoid empty glyph boxes.
|
||||
- [ ] Include likely-installed fallbacks; avoid over-subsetting; choose quality fonts.
|
||||
- [ ] Evaluate font quality via kerning/word samples; prefer reputable sources; do not use pirated fonts.
|
||||
- [ ] License fonts properly (especially web); buy full families or use open-source; use large type as a design element.
|
||||
- [ ] Use huge type to showcase fonts; scale down on small screens; begin brand capitalization decisions.
|
||||
- [ ] Pick a consistent brand capitalization (prefer single-word with initial cap); avoid all caps/lowercase in running text.
|
||||
- [ ] Avoid .com in brand names; use mid-word caps only if needed; enforce consistency everywhere.
|
||||
- [ ] Choose logo typeface based on the specific letters in the name; favor distinctive glyphs you actually use.
|
||||
- [ ] Use swashes/discretionary ligatures/stylistic alternates in logos sparingly for memorability.
|
||||
- [ ] Look for swashes in italics or separate files; use display cut for headlines when available.
|
||||
- [ ] Use display cuts only at large sizes; enable discretionary ligatures/swashes for headlines, not body.
|
||||
- [ ] Enable headline OpenType features: `kern`, `liga`, `clig`, `calt`, `dlig`, `swsh`.
|
||||
- [ ] Enable swashes on specific letters if needed; tighten line height and tracking for large headlines.
|
||||
- [ ] Use negative leading only when safe; test multi-line headlines; display cuts may need less tracking.
|
||||
- [ ] Break the grid intentionally with oversized type/images/quotes while keeping overall structure.
|
||||
- [ ] Allow grid deviations when useful; add a lead/lede paragraph with larger or distinct styling.
|
||||
- [ ] Leads can be short; start articles with initial small caps or drop caps where appropriate.
|
||||
- [ ] Implement small caps or drop caps (CSS `initial-letter` in Safari or JS fallback); use whitespace as a design element.
|
||||
- [ ] Give typography room to breathe; use color to create brand and hierarchy.
|
||||
- [ ] Use color intentionally with sufficient contrast; subtle tints can be distinctive.
|
||||
- [ ] Avoid pure black/white; use slightly tinted blacks/whites to reduce glare.
|
||||
- [ ] Tint blacks/whites with brand hue but keep contrast adequate.
|
||||
- [ ] Keep type consistent across web/print/app; license fonts for each medium; make body text distinctive to brand.
|
||||
- [ ] Experiment beyond default fonts/colors; aim for recognizable body-text identity.
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
name: frontend-design
|
||||
description: Build distinctive, brand-forward UI for marketing pages, creative sites, and experiential interfaces. Use when the user asks for a strong aesthetic point of view.
|
||||
---
|
||||
|
||||
# Frontend Design
|
||||
|
||||
Deliver working code with a clear aesthetic point of view. Avoid generic AI aesthetics.
|
||||
|
||||
## Scope
|
||||
- Use for marketing sites, brand pages, and creative experiences.
|
||||
- For dashboards/admin/SaaS, use `design-principles` instead.
|
||||
|
||||
## Decide the direction (before coding)
|
||||
- Identify purpose, audience, and constraints.
|
||||
- Choose a bold tone (minimal, maximal, retro, editorial, brutalist, organic, luxury, etc).
|
||||
- Define a single memorable signature detail.
|
||||
- Match implementation complexity to the chosen direction.
|
||||
|
||||
## Non-negotiables (UX baseline)
|
||||
- Full keyboard support, visible focus, and focus management in dialogs/menus.
|
||||
- Hit targets >= 24px (>= 44px on mobile); hover styles only on hover-capable devices.
|
||||
- Never disable browser zoom; use `touch-action: manipulation` for tap targets.
|
||||
- Forms: labels wired to inputs; Enter submits; textarea uses Cmd/Ctrl+Enter; validate after input; errors inline; focus first error.
|
||||
- Do not block paste or typing; keep submit enabled until request starts, then disable with spinner.
|
||||
- Correct `type`, `name`, `autocomplete`, `inputmode`; disable spellcheck only when appropriate.
|
||||
- Use links for navigation; URL reflects state; Back/Forward restores scroll.
|
||||
- Respect safe areas; avoid unwanted scrollbars; prefer flex/grid over JS measurement.
|
||||
- Handle long content and empty/error states; use `min-w-0` for truncation.
|
||||
- Locale-aware formatting (`Intl.*`); use `…` and non-breaking spaces where needed.
|
||||
- Preload above-the-fold images; set image dimensions; virtualize large lists; preload/subset fonts.
|
||||
- Theme: `color-scheme` and `<meta name="theme-color">` match.
|
||||
- Hydration: inputs with `value` must have `onChange`; guard date/time rendering.
|
||||
|
||||
## Aesthetic rules
|
||||
- Typography: choose distinctive fonts (not Inter/Roboto/Arial/system). Weight >= 400. Use `clamp()`; tabular nums for data; enable font smoothing and legibility.
|
||||
- Color: commit to a palette with CSS variables; avoid pure black/white; use one sharp accent.
|
||||
- Composition: use asymmetry, contrast, and negative space intentionally.
|
||||
- Backgrounds: build atmosphere with gradients/noise/patterns, not flat fills.
|
||||
- Interaction details: set `pointer-events: none` on decorative layers; allow text selection by default and use `user-select: none` only on drag handles or non-text UI chrome.
|
||||
|
||||
## Motion
|
||||
- Follow `animation-guidelines` for timing, easing, and reduced-motion behavior.
|
||||
|
||||
## Avoid AI slop
|
||||
- Do not reuse the same font stack, purple gradients, or default layouts.
|
||||
- Vary fonts, palettes, spacing systems, and visual language per project.
|
||||
- Make every decision context-specific and intentional.
|
||||
|
||||
## Reference
|
||||
- See `aesthetic-direction.md` for deeper guidance and examples.
|
||||
@@ -0,0 +1,48 @@
|
||||
# Aesthetic Direction
|
||||
|
||||
Goal: make the UI look human-designed, not AI-default.
|
||||
|
||||
## AI slop signals
|
||||
- Default fonts (Inter/Roboto/Arial/system).
|
||||
- Purple-on-white gradients and generic cards.
|
||||
- Predictable layouts and repeated component patterns.
|
||||
- Excess glow and unnecessary complexity.
|
||||
|
||||
## Philosophy
|
||||
- Delete aggressively; clarity over decoration.
|
||||
- Restraint plus hierarchy beats noise.
|
||||
|
||||
## Study references
|
||||
- Linear, Stripe, Notion, Raycast, ElevenLabs, Zed.
|
||||
|
||||
## Tools (table stakes)
|
||||
- shadcn/ui, Tailwind CSS, Motion, React, Biome/Ultracite.
|
||||
|
||||
## Copy to learn (not to ship)
|
||||
- Find a tasteful UI.
|
||||
- Replicate it precisely (layout, type, spacing, motion).
|
||||
- Inspect code and measure values.
|
||||
- Iterate until it matches; then adapt to your context.
|
||||
|
||||
## Upgrade choices
|
||||
- Icon sets: Phosphor, Heroicons, Tabler.
|
||||
- Typography sources: Typewolf, Fonts In Use, commercial foundries.
|
||||
- Animation study: animations.dev, devouringdetails.com.
|
||||
|
||||
## Extra polish
|
||||
- Match box-shadows to references.
|
||||
- Dark-mode aware SVG favicon.
|
||||
- Dynamic OG images and SEO metadata.
|
||||
- Intentional hover/active states and loading/error/empty states.
|
||||
|
||||
## Craft baseline (non-negotiable)
|
||||
- Full keyboard support; visible focus rings; manage focus in dialogs/menus.
|
||||
- Hit targets >= 24px (>= 44px on mobile); hover styles gated by `@media (hover: hover)`.
|
||||
- Forms: labels wired to inputs; Enter submits; textarea uses Cmd/Ctrl+Enter; keep submit enabled until request starts, then disable with spinner.
|
||||
- Never block paste/typing; inline errors; focus first error; inputs with `value` include `onChange`.
|
||||
- Follow `animation-guidelines` for motion rules and reduced-motion behavior.
|
||||
- Respect safe areas; handle long content with truncation; design empty/error states.
|
||||
- Locale-aware formatting (`Intl.*`); use `…` and non-breaking spaces for glued terms.
|
||||
|
||||
## Standard
|
||||
Distinctive, contextual, refined, and memorable.
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
name: frontend-standards
|
||||
description: Production frontend standards for React/TypeScript/Next.js. Use when reviewing, refactoring, or writing frontend code, especially forms, state, hooks/components, and type safety.
|
||||
---
|
||||
|
||||
# Frontend Standards
|
||||
|
||||
Use this as the baseline for all frontend code. Fix violations.
|
||||
|
||||
## Core rules
|
||||
- Keep a single source of truth for any data or state.
|
||||
- Enforce type safety: no `any`, no `as` casting, no ts-ignore.
|
||||
- Use React Hook Form for every form. No manual form state.
|
||||
- Use proto types as the contract; do not duplicate API types.
|
||||
- Components render; hooks own data fetching and business logic.
|
||||
|
||||
## Critical anti-patterns
|
||||
- Duplicate state or syncing state via `useEffect`.
|
||||
- API calls or business logic inside components.
|
||||
- `zodResolver(schema as any)` or other type escapes.
|
||||
- Form object in dependency arrays (use only formState fields).
|
||||
|
||||
## References
|
||||
- See `typescript-patterns.md` for TypeScript and proto guidance.
|
||||
- See `react-patterns.md` for forms, hooks, and state.
|
||||
|
||||
## Quick checks
|
||||
- Remove `console.*`, `debugger`, commented code, unused imports.
|
||||
- Use `useId` for IDs; avoid hardcoded IDs.
|
||||
- Zod v4 + `createZodResolver`.
|
||||
- React Query/Connect Query owns server state; RHF owns form state; `useState` only for UI.
|
||||
|
||||
## Reliability & data fetching (required)
|
||||
- Optimistic updates must snapshot previous cache state and rollback on error.
|
||||
- Only optimistic-update for operations with a safe rollback; avoid for destructive actions unless server supports undo.
|
||||
- Retries are only for idempotent requests. Use exponential backoff with full jitter and cap attempts/time.
|
||||
- Always use `AbortController` for in-flight requests to prevent race conditions on unmount or rapid input.
|
||||
|
||||
## Cache & invalidation (required)
|
||||
- React Query/Connect Query is the source of truth for server state; never copy server data into `useState`.
|
||||
- Mutations must invalidate or update only the affected queries; do not refetch everything.
|
||||
- `setQueryData` is allowed only for optimistic updates or small, scoped edits.
|
||||
|
||||
## Performance & UX (required)
|
||||
- Lazy-load heavy UI (charts, editors, modals) with dynamic import and suspense fallback.
|
||||
- Reserve image sizes to avoid layout shift; use `next/image` when applicable.
|
||||
- Enforce bundle budgets in CI (document the budgets in the repo).
|
||||
|
||||
## Observability (required)
|
||||
- Add error boundaries at route/layout level; report exceptions to Sentry (or project standard).
|
||||
- Tag client errors with `userId`/`orgId` and `release` (commit/semantic version), scrub PII.
|
||||
|
||||
## Web interface guidelines (mandatory UX baseline)
|
||||
- Full keyboard support; visible focus rings (`:focus-visible`/`:focus-within`); manage focus in dialogs/menus.
|
||||
- Hit targets >= 24px (>= 44px on mobile); hover styles gated by `@media (hover: hover)`; `touch-action: manipulation`.
|
||||
- Forms: labels wired to inputs; Enter submits; textarea uses Cmd/Ctrl+Enter; keep submit enabled until request starts, then disable with spinner.
|
||||
- Never block paste/typing; inline errors; focus first error; inputs with `value` include `onChange`.
|
||||
- Navigation uses `<a>`/`<Link>`; URL reflects state; Back/Forward restores scroll position.
|
||||
- If showing a spinner/skeleton, add a short show-delay (150-300ms); confirm destructive actions or provide Undo.
|
||||
- Follow `animation-guidelines` for motion rules.
|
||||
- Respect safe areas; avoid unwanted scrollbars; handle long content with truncation (`min-w-0`).
|
||||
- Theming: `color-scheme: dark` on `<html>` for dark themes; `<meta name="theme-color">` matches background.
|
||||
|
||||
## Required structure (per feature)
|
||||
```
|
||||
components/<feature>/
|
||||
*.tsx
|
||||
hooks/ # feature hooks only
|
||||
types/ # schemas + UI types
|
||||
utils/
|
||||
proto-mappers.ts # proto -> UI transforms
|
||||
constants.ts
|
||||
```
|
||||
|
||||
## Naming
|
||||
- Files: kebab-case. Components: PascalCase. Functions: camelCase. Constants: UPPER_SNAKE_CASE.
|
||||
|
||||
Every file should be ready to ship.
|
||||
@@ -0,0 +1,61 @@
|
||||
# React Patterns
|
||||
|
||||
## Forms
|
||||
- React Hook Form is required for all forms; no `useState` for form fields.
|
||||
- Use Zod v4 + `createZodResolver` from `@/lib/utils/zod-resolver`.
|
||||
- Define schemas in `types/index.ts`.
|
||||
- Keep Zod for client-side validation; backend validation is separate.
|
||||
- Use `form.watch`/`setValue`; do not duplicate state.
|
||||
- Keep submit enabled until request starts; then disable with spinner and keep the label.
|
||||
- Enter submits; in `<textarea>`, use Cmd/Ctrl+Enter.
|
||||
- Never block paste or typing; validate after input; allow incomplete submit to surface errors.
|
||||
- Errors inline next to fields; focus the first error on submit.
|
||||
- Labels wired to inputs; set `autocomplete`, meaningful `name`, correct `type` + `inputmode`.
|
||||
- Disable spellcheck only for emails/codes/usernames; avoid reserved names that trigger password managers.
|
||||
- Trim trailing whitespace from text expansion; inputs with `value` must have `onChange`.
|
||||
- Inputs must not lose focus or value after hydration.
|
||||
|
||||
## RHF dependencies
|
||||
- Do not add `form` to deps. Methods are stable.
|
||||
- Only depend on `form.formState.*` when needed.
|
||||
|
||||
## State ownership
|
||||
- Form state: RHF. Server state: React Query/Connect Query. UI state: `useState`. Global: MobX only when necessary.
|
||||
- Red flags: syncing state with `useEffect`, storing server data in `useState`.
|
||||
|
||||
## Components vs hooks
|
||||
- Components: render only, minimal UI state, call hooks.
|
||||
- Hooks: API calls, business logic, side effects, and mapping.
|
||||
|
||||
## Hook layout
|
||||
- `hooks/use-*-data.ts`: fetching.
|
||||
- `hooks/use-*-logic.ts`: business logic.
|
||||
- `hooks/use-*-state.ts`: complex UI state.
|
||||
|
||||
## API client
|
||||
- Use ConnectRPC + `@connectrpc/connect-query`; no raw fetch on client.
|
||||
- Use `useQuery` for reads, `useMutation` for writes.
|
||||
- Invalidate with `createConnectQueryKey` and the exact key.
|
||||
- Handle `ConnectError` with user-facing messages.
|
||||
- No direct DB/server imports in client.
|
||||
|
||||
## Interaction basics
|
||||
- Full keyboard support per WAI-ARIA APG; visible focus rings (`:focus-visible`/`:focus-within`).
|
||||
- Hit targets >= 24px (>= 44px on mobile); hover styles gated by `@media (hover: hover)`.
|
||||
- Use `<a>`/`<Link>` for navigation; URL reflects state; Back/Forward restores scroll.
|
||||
- Respect safe areas and avoid unwanted scrollbars; use `min-w-0` for truncation.
|
||||
|
||||
## Performance
|
||||
- Memoize only when profiling shows benefit.
|
||||
- Virtualize long lists.
|
||||
- Use stable keys; avoid index keys.
|
||||
- Keep `useEffect` deps correct; clean up.
|
||||
|
||||
## Next.js
|
||||
- Use `next/link` for internal nav.
|
||||
- Default to Server Components; add "use client" only when required.
|
||||
- Prefer server `page.tsx` wrappers that render client children.
|
||||
- Add `loading.tsx`/`error.tsx` for key routes.
|
||||
|
||||
## Final check
|
||||
- No duplicate state, no manual form state, no logic in components, no `form` in deps.
|
||||
@@ -0,0 +1,31 @@
|
||||
# TypeScript Patterns
|
||||
|
||||
## Hygiene
|
||||
- Eliminate `any`, `as any`, `// @ts-ignore`, and `// @ts-expect-error`.
|
||||
- Add explicit types where not obvious (props, events, generics).
|
||||
- Prefer `type` over `interface`.
|
||||
- One component per file; use arrow components.
|
||||
- Return types: allow inference or use `React.ReactElement` (server components: `Promise<React.ReactElement>`).
|
||||
|
||||
## Proto types
|
||||
- Import proto-generated types directly; do not duplicate API response types.
|
||||
- Extend proto only for UI needs; keep UI types feature-scoped.
|
||||
- Use mappers for transformations; avoid `as` casting.
|
||||
- Normalize timestamps to `Date` in mappers.
|
||||
|
||||
## Organization
|
||||
- `types/index.ts`: Zod schemas + inferred types.
|
||||
- `types/common.ts`: shared enums/interfaces.
|
||||
- `types/<domain>.ts`: feature UI types.
|
||||
- `utils/proto-mappers.ts`: all proto -> UI mapping.
|
||||
|
||||
## Imports
|
||||
- Order: React/Next, third-party, internal, relative, styles.
|
||||
- Use absolute aliases when available.
|
||||
- Import from `./types`, not `./types/index`.
|
||||
- Components do not import proto types directly; hooks/mappers do.
|
||||
|
||||
## Patterns
|
||||
- Use proper event types (`React.MouseEvent`, `React.ChangeEvent`).
|
||||
- Always type `useState` when null/undefined is possible.
|
||||
- Use `createZodResolver` instead of `zodResolver(schema as any)`.
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
name: fullstack-architecture
|
||||
description: Architecture patterns for TypeScript full-stack apps (backend context, ConnectRPC, DAOs, and frontend integration). Use when setting up projects or implementing backend services and middleware.
|
||||
---
|
||||
|
||||
# Full-Stack Architecture
|
||||
|
||||
## Stack (typical)
|
||||
- Turborepo + npm workspaces.
|
||||
- Next.js App Router + React.
|
||||
- ConnectRPC + protobuf types.
|
||||
- Prisma + Postgres.
|
||||
- Supabase (auth/storage), Stripe (payments).
|
||||
- Biome + Vitest.
|
||||
|
||||
## Workflow
|
||||
- Use `repository-workflow` for frontend-first development and TDD process.
|
||||
|
||||
## Frontend UX baseline
|
||||
- Use `craft-checklist` for UI polish and `animation-guidelines` for motion.
|
||||
- Use `frontend-standards` for forms, hooks, and type safety.
|
||||
|
||||
## Backend request context
|
||||
- Use AsyncLocalStorage-backed `RequestContext`.
|
||||
- Initialize context in every entrypoint (RPC, HTTP, jobs, CLI).
|
||||
- Access via `getContext()`; no explicit context params.
|
||||
- Loggers read context automatically.
|
||||
|
||||
## ConnectRPC middleware rules
|
||||
- Define a route policy for every method.
|
||||
- Use shared middleware for auth, errors, logging, and context.
|
||||
- No manual auth calls inside handlers.
|
||||
- No try/catch for business logic; let error middleware handle.
|
||||
- Use auth helpers (`requireUserAuth`, `requireStaffAuth`, `requireVenueAccess`, `getAuthContext`).
|
||||
- Register services via `registerServiceWithPolicies`.
|
||||
|
||||
## File organization
|
||||
- Handlers: transport only.
|
||||
- Services: business orchestration.
|
||||
- DAOs: DB access only; class-based methods with explicit types.
|
||||
- Mappers: DB/Proto/Domain transforms.
|
||||
- Constants/types: module-level.
|
||||
- Audit log all Create/Update/Delete in DAOs.
|
||||
|
||||
## Frontend architecture
|
||||
- Server Components by default; "use client" only when needed.
|
||||
- TanStack/Connect Query for server state; MobX only for global client state.
|
||||
- Form rules live in `frontend-standards`.
|
||||
|
||||
## Testing
|
||||
- Unit tests: parallel, no DB, mocks only.
|
||||
- Integration/E2E: parallel with dynamic IDs.
|
||||
- Frontend tests: Vitest/jsdom as needed.
|
||||
|
||||
## Conventions
|
||||
- Prefer `type` over `interface`.
|
||||
- Use `import type` for types.
|
||||
- Biome: 2-space indent, double quotes, semicolons, 100 char width.
|
||||
|
||||
## Shared packages
|
||||
- `packages/proto` for API contracts.
|
||||
- `packages/ui` for shared components.
|
||||
- `packages/icons` for icon set.
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
name: repository-workflow
|
||||
description: Development workflow and repo conventions. Use when starting new projects, organizing modules, or establishing patterns for frontend, backend, and testing.
|
||||
---
|
||||
|
||||
# Repository Workflow
|
||||
|
||||
## Principles
|
||||
- Build frontend first: mock UI -> proto contract -> backend (TDD) -> integrate.
|
||||
- Exception: unblocker infra (auth/middleware/schema) can come first.
|
||||
- For backend context/middleware rules, use `fullstack-architecture`.
|
||||
|
||||
## Monorepo shape (example)
|
||||
- apps/: api, web, admin (adapt names to product domains)
|
||||
- packages/: shared, ui, icons, auth
|
||||
|
||||
## Backend module pattern
|
||||
- Handler: transport only.
|
||||
- Service: business orchestration.
|
||||
- DAO: DB access only (class with explicit methods).
|
||||
- Mapper: DB/Proto/Domain transforms.
|
||||
- Constants/types: module-level.
|
||||
|
||||
DAO rules
|
||||
- Explicit input/return types.
|
||||
- Prisma select const pattern for DRY types.
|
||||
- Audit log all Create/Update/Delete.
|
||||
|
||||
## Commands (common)
|
||||
- `npm run dev` / `npm run dev --workspace=<pkg>`
|
||||
- `npm run build`, `npm run lint`, `npm run check-types`
|
||||
- `npm run test --workspace=<pkg>`, `npm run test:coverage --workspace=<pkg>`
|
||||
- `npm run codegen --workspace=packages/proto`
|
||||
- `npm run migrate:dev --workspace=apps/api`
|
||||
|
||||
## Stack defaults (adjust per project)
|
||||
- Next.js, React, Tailwind.
|
||||
- Fastify/Express, Prisma, Postgres.
|
||||
- Supabase or Clerk for auth; Vercel for frontend deploy.
|
||||
|
||||
## Frontend UX baseline
|
||||
- Use `craft-checklist` for UI polish and `animation-guidelines` for motion.
|
||||
|
||||
## Style rules
|
||||
- Files: kebab-case; components: PascalCase; functions: camelCase; constants: UPPER_SNAKE_CASE.
|
||||
- Prefer `type` over `interface`.
|
||||
- Forbid `any`, `as any`, and `@ts-ignore`.
|
||||
- Remove all `console.*` and `debugger`.
|
||||
|
||||
## Testing
|
||||
- Backend TDD required: Red -> Green -> Refactor.
|
||||
- Unit tests: no DB; run in parallel; mock dependencies.
|
||||
- Integration/E2E: parallel with dynamic IDs.
|
||||
|
||||
## Commits and PRs
|
||||
- Commit subjects in imperative mood.
|
||||
- PRs: green lint/type/tests, document migrations, add UI screenshots.
|
||||
|
||||
## Production readiness (priority order)
|
||||
- Security: rotate secrets, CORS, rate limits, headers, dependency scanning.
|
||||
- Architecture: modular services, auth/error middleware, strict typing.
|
||||
- Infra: integration tests, health checks, automated deploys.
|
||||
- Observability: tracing, audit logs, alerting.
|
||||
Reference in New Issue
Block a user