diff --git a/claude/skills/frontend-design-systems/SKILL.md b/claude/skills/frontend-design-systems/SKILL.md new file mode 100644 index 0000000..e83f885 --- /dev/null +++ b/claude/skills/frontend-design-systems/SKILL.md @@ -0,0 +1,139 @@ +--- +name: Frontend Design Systems +description: >- + This skill should be used when the user asks to "build a design system", + "create consistent UI", "define color ratios", "set up typography system", + "normalize geometry tokens", "validate visual hierarchy", "apply design + constraints", or when generating frontend UI that requires systematic + visual consistency. Augments the frontend-design skill with system-level + visual decision rules for consistency, hierarchy, and scalable UI + decision-making. +version: 0.1.0 +inspired_by: https://www.youtube.com/watch?v=eVnQFWGDEdY +--- + +# Frontend Design Systems + +## Purpose + +Augment the `frontend-design` skill with system-level visual decision rules +derived from practical graphic design heuristics. Focus on consistency, +hierarchy, and scalable UI decision-making rather than aesthetic +experimentation. + +Apply this skill *after* layout, accessibility, and interaction logic are +established by `frontend-design`. + +## Core Principle + +Design quality emerges from repeatable systems: ratios, constraints, typography +systems, geometry rules, and hierarchy validation. + +Prefer deterministic structure over stylistic improvisation. + +## Heuristics + +### 1. Color Ratio System + +Do not distribute colors evenly. Use proportional dominance: + +- 70-90% neutral base +- 10-25% supporting color +- 1-8% accent color + +Map accent color to: primary actions, alerts, focus states, brand signals. If +accent overuse occurs, reduce until hierarchy is restored. + +### 2. Typography Superfamily Strategy + +Default to a Single System: One Family, multiple Weights, Limited Width/Style +Variation. + +Express hierarchy via: size, weight, spacing, rhythm. + +Introduce additional typefaces only when semantic separation is required (e.g., +code vs marketing content). + +### 3. Geometry Consistency Rule + +All UI must inherit a shared structural language: border radius, angle logic, +stroke thickness, elevation system, spacing cadence. + +Do not introduce new geometry tokens unless: + +- Existing tokens cannot express the requirement +- Functional clarity would otherwise degrade + +Consistency > variety. + +### 4. Dual-Scale Validation + +Evaluate every interface at two levels: + +**Macro (~10% scale):** Hierarchy clarity, scanning flow, section priority. + +**Micro (~200-300% scale):** Spacing, alignment, typography precision, component +polish. + +Reject designs that succeed at only one scale. + +### 5. Constraint-First Brand Framing + +Before generating UI styles, define negative constraints. Example: + +- not playful +- not aggressive +- not corporate +- not experimental +- not premium +- not youthful + +Use constraints to filter: color choices, typography decisions, motion styles, +component density. If a design decision conflicts with constraints, discard it. + +### 6. Non-Designer Reality Bias + +Assume users: are distracted, scroll quickly, use mobile, operate under low +brightness, do not analyze details. + +Optimize for: instant comprehension, strong primary action visibility, minimal +cognitive load, clear visual hierarchy within <2 seconds. + +Design for use, not inspection. + +### 7. Repetition over Novelty + +When uncertain: repeat existing visual rules, reinforce hierarchy, reduce +variation. + +Allow novelty only after: clarity is achieved, hierarchy is stable, interaction +affordances are obvious. + +## Integration Behavior + +When layered after `frontend-design`: + +1. Convert layout decisions into visual systems: derive color ratios, apply + typography hierarchy, normalize geometry tokens. +2. Run constraint filtering before rendering UI variants. +3. Evaluate macro structure first, micro polish second. +4. Optimize for comprehension speed over stylistic uniqueness. +5. Prefer consistency, predictability, clarity, and restraint over visual + experimentation. + +## Failure Modes to Avoid + +- Evenly distributed color usage +- Mixing multiple unrelated typefaces +- Inconsistent border radii and spacing logic +- Hierarchy visible only at high zoom +- Designing for designers instead of users +- Novelty introduced without structural justification + +## Output Expectations + +UI generated with this skill should feel: intentional, cohesive, restrained, +hierarchy-driven, fast to parse, and visually consistent across components and +pages. + +Bias toward clarity and repetition until interaction goals are fully satisfied. diff --git a/siren b/siren index 0a79f28..6aa3aa0 100755 --- a/siren +++ b/siren @@ -49,6 +49,7 @@ define_settings() { STATIC_SYMLINKS["claude/settings.json"]="${HOME}/.claude/settings.json" STATIC_SYMLINKS["claude/statusline.sh"]="${HOME}/.claude/statusline.sh" _add_command_symlinks "claude" "${HOME}/.claude" + _add_skill_symlinks "claude" "${HOME}/.claude" fi # Conditionally add symlinks for Cursor. @@ -444,6 +445,32 @@ _add_command_symlinks() { done } +# Add symlinks for all skill directories (containing SKILL.md) in a skills +# directory. +# Args: $1 = source subdir (e.g., "claude"), $2 = target dir (e.g., ~/.claude) +_add_skill_symlinks() { + local source_subdir="$1" + local target_base="$2" + local skills_dir="${SCRIPT_DIR}/${source_subdir}/skills" + + if [[ ! -d "${skills_dir}" ]]; then + return + fi + + local skill_dir + for skill_dir in "${skills_dir}"/*/; do + # Skip if glob didn't match anything (returns literal pattern). + [[ -d "${skill_dir}" ]] || continue + + # Only treat directories containing SKILL.md as skills. + if [[ -f "${skill_dir}/SKILL.md" ]]; then + local skill_name + skill_name="$(basename "${skill_dir}")" + STATIC_SYMLINKS["${source_subdir}/skills/${skill_name}"]="${target_base}/skills/${skill_name}" + fi + done +} + # Remove stale symlinks in a commands directory that point to source files that # no longer exist. # Args: $1 = source subdir (e.g., "claude"), $2 = target dir (e.g., ~/.claude) @@ -481,6 +508,44 @@ _cleanup_stale_commands() { done } +# Remove stale symlinks in a skills directory that point to source +# directories that no longer exist. Only touches symlinks pointing into our +# source tree; symlinks managed by other tools are left untouched. +# Args: $1 = source subdir (e.g., "claude"), $2 = target dir (e.g., ~/.claude) +_cleanup_stale_skills() { + local source_subdir="$1" + local target_base="$2" + local skills_dir="${target_base}/skills" + local source_dir="${SCRIPT_DIR}/${source_subdir}/skills" + + if [[ ! -d "${skills_dir}" ]]; then + return + fi + + local link + for link in "${skills_dir}"/*; do + # Skip if glob didn't match anything (returns literal pattern). + [[ -e "${link}" || -L "${link}" ]] || continue + + # Skip if not a symlink. + if [[ ! -L "${link}" ]]; then + continue + fi + + local target + target="$(readlink "${link}")" + + # Check if the symlink points to our source directory. + if [[ "${target}" == "${source_dir}/"* ]]; then + # If the target directory no longer exists, remove the symlink. + if [[ ! -e "${target}" ]]; then + info "Removing stale symlink: ${link}" + rm -f "${link}" + fi + fi + done +} + # Find the editor CLI command. # # Returns: Editor command path via `STDOUT`. @@ -1277,9 +1342,10 @@ do_config() { symlink_editor_config symlink_static_config - # Clean up stale command symlinks. + # Clean up stale command and skill symlinks. if command -v claude &>/dev/null; then _cleanup_stale_commands "claude" "${HOME}/.claude" + _cleanup_stale_skills "claude" "${HOME}/.claude" fi if [[ "${SETUP_EDITOR}" == "cursor" ]]; then _cleanup_stale_commands "cursor" "${HOME}/.cursor"