diff --git a/README.md b/README.md index e51e108..9eb6cdc 100644 --- a/README.md +++ b/README.md @@ -103,14 +103,14 @@ Thank you to the authors and contributors who shared the skills this collection uses and adapts: - [Matt Pocock](https://github.com/mattpocock/skills) — engineering and productivity skills, including the Standards and Spec review rules. -- [Emil Kowalski](https://github.com/emilkowalski/skills) — animation and design engineering skills. +- [Emil Kowalski](https://github.com/emilkowalski/skills) — animation, motion and gesture behavior, typography and materials, interface access/input, and interface-review guidance. - [Jakub Antalík’s transitions.dev](https://github.com/Jakubantalik/transitions.dev) — motion pattern references and tuning guidance used by `animate`. - [Dietrich Gebert’s Ponytail](https://github.com/DietrichGebert/ponytail) — simplicity and code review rules. - [Cursor](https://github.com/cursor/plugins) — the Thermo Nuclear Code Quality Review. -- [Anthropic’s skills](https://github.com/anthropics/skills) — the Frontend Web Design skill. +- [Anthropic’s skills](https://github.com/anthropics/skills) — art-direction guidance used by `ui-design`. - [Anthropic’s Claude Plugins Community](https://github.com/anthropics/claude-plugins-community) — the `eli5` skill. - [GitHub’s gh-stack](https://github.com/github/gh-stack) — the stacked PR skill. -- [s0xDk](https://github.com/s0xDk/refactoring-ui-skill) — the Refactoring UI skill, based on Adam Wathan and Steve Schoger’s work. +- [s0xDk](https://github.com/s0xDk/refactoring-ui-skill) — web-system guidance used by `ui-design`, based on Adam Wathan and Steve Schoger’s work. - [React Doctor](https://github.com/millionco/react-doctor) — the React diagnostics skill. - [Vercel’s agent-skills](https://github.com/vercel-labs/agent-skills/tree/main/skills/react-best-practices) — the React Best Practices skill, originally created by [Shu Ding](https://x.com/shuding). - [Charles Wiltgen’s Axiom haptics guide](https://github.com/CharlesWiltgen/Axiom/blob/dd3334734ecd01afab28b0ac22c49d4b5b2e5857/.claude-plugin/plugins/axiom/skills/axiom-media/skills/haptics.md) — inspiration for our locally written iOS haptics skill; no upstream prose or code copied. diff --git a/SOURCES.md b/SOURCES.md index 55d531d..ccf8982 100644 --- a/SOURCES.md +++ b/SOURCES.md @@ -17,6 +17,8 @@ Local-only skills need just an origin note. ## animate - [emilkowalski/skills](https://github.com/emilkowalski/skills/tree/d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7/skills/animate) — `skills/animate/SKILL.md` and `RECIPES.md`; reference import commit `d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7`. The original parent-skill import baseline remains unknown. MIT notice in `licenses/emilkowalski-animate.txt`. +- [emilkowalski/skills / skills/emil-design-eng](https://github.com/emilkowalski/skills/tree/d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7/skills/emil-design-eng) — press feedback and measured rendering guidance; content verified against commit `d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7`, while the earlier local import baseline remains unknown. +- [emilkowalski/skills / skills/apple-design](https://github.com/emilkowalski/skills/tree/d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7/skills/apple-design) — gesture-intent guidance; content verified against commit `d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7`, while the earlier local import baseline remains unknown. - [Jakubantalik/transitions.dev](https://github.com/Jakubantalik/transitions.dev/tree/598d3d6ad89dabb4bdf742fd2e887ca53914a888/skills) — `skills/transitions-dev/` and `skills/transitions-polish/`; commit `598d3d6ad89dabb4bdf742fd2e887ca53914a888`. No license file found in this revision; see `THIRD_PARTY_NOTICES.md`. - One automatically discoverable cross-platform skill owns motion decisions, @@ -47,10 +49,14 @@ Local-only skills need just an origin note. scroll-reveal, drag-to-dismiss, crossfade, and programmatic-animation guides. Prose gives local use criteria and checks. Code examples remain except for the drag dismissal test, which uses recent signed velocity toward the exit - instead of absolute whole-gesture average speed. Curve defaults live beside - examples that use them. Unsupported performance guarantees are omitted. + instead of absolute whole-gesture average speed. Drag dismissal also preserves + an intent threshold and an explicit browser pan-axis contract before claiming + direction, and shared web guidance keeps press feedback separate from valid + action commitment. Curve defaults live beside examples that use them. + Unsupported performance guarantees are omitted. - `references/implementation.md` covers shared lifecycle, access, token, and - rendering checks. `references/tuning.md` adapts the polish scale and rules, + measured rendering checks, including inherited custom-property scope. + `references/tuning.md` adapts the polish scale and rules, scopes scans to the request, treats blur and values as choices, and counts stagger delay from the last item's zero-based index. Toast close guidance uses the pattern's 250ms starting point. Per-pattern variable blocks replace @@ -81,15 +87,6 @@ Local-only skills need just an origin note. - [mattpocock/skills / skills/engineering/codebase-design](https://github.com/mattpocock/skills/tree/6acc160e4e0cd062dbbbd7a1b26ae92855edf07e/skills/engineering/codebase-design) — v1.2.3, commit `6acc160e4e0cd062dbbbd7a1b26ae92855edf07e`. -## design-eng - -- [emilkowalski/skills](https://github.com/emilkowalski/skills) — `skills/emil-design-eng`; commit: unknown. -- [emilkowalski/skills](https://github.com/emilkowalski/skills) — `skills/apple-design`; commit: unknown. - -Combines both upstream sources in one skill. Invocation is -manual-only: `disable-model-invocation: true` and -`allow_implicit_invocation: false`. - ## diagnosing-bugs - [mattpocock/skills / skills/engineering/diagnosing-bugs](https://github.com/mattpocock/skills/tree/6acc160e4e0cd062dbbbd7a1b26ae92855edf07e/skills/engineering/diagnosing-bugs) — v1.2.3, commit `6acc160e4e0cd062dbbbd7a1b26ae92855edf07e`. @@ -106,15 +103,6 @@ manual-only: `disable-model-invocation: true` and - [anthropics/claude-plugins-community / eli5/skills/eli5](https://github.com/anthropics/claude-plugins-community/tree/f4c9452f5ca091f1be7064d9faab1b001ea21645/eli5/skills/eli5) — commit `f4c9452f5ca091f1be7064d9faab1b001ea21645`. -## frontend-web-design - -- [anthropics/skills / skills/frontend-design](https://github.com/anthropics/skills/tree/34040c9c568585f6929bedeaad110ad08f079624/skills/frontend-design) — commit `34040c9c568585f6929bedeaad110ad08f079624`. - -Renamed to `frontend-web-design`, with a web-only description. Removes the -AI-default calibration list and guidance tied to it, while keeping the rule to -follow the brief. Omits the license frontmatter field and license file. The rest -of the upstream wording remains. Automatic discovery stays enabled. - ## goal-bee - Local: `skills/goal-bee` (SreeStack). @@ -175,17 +163,29 @@ only on request. ## swiftui - Local: `skills/swiftui` (SreeStack). +- [emilkowalski/skills / skills/emil-design-eng](https://github.com/emilkowalski/skills/tree/d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7/skills/emil-design-eng) — component-behavior and access guidance redistributed from the retired local `design-eng` adaptation; content verified against commit `d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7`, while the earlier local import baseline remains unknown. Includes focused guidance for current platform materials and Liquid Glass rather -than keeping a separate visual-effect skill. +than keeping a separate visual-effect skill. Redistributed behavior and access +guidance is folded into the normal SwiftUI workflow; automatic invocation +remains framework- and task-based. ## uikit - Local: `skills/uikit` (SreeStack). +- [emilkowalski/skills / skills/emil-design-eng](https://github.com/emilkowalski/skills/tree/d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7/skills/emil-design-eng) — component-behavior and access guidance redistributed from the retired local `design-eng` adaptation; content verified against commit `d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7`, while the earlier local import baseline remains unknown. + +Redistributed behavior and access guidance is folded into the normal UIKit +workflow; automatic invocation remains framework- and task-based. ## manual-verify - Local: `skills/manual-verify` (SreeStack). +- [emilkowalski/skills / skills/emil-design-eng](https://github.com/emilkowalski/skills/tree/d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7/skills/emil-design-eng) — interface-review criteria; content verified against commit `d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7`, while the earlier local import baseline remains unknown. +- [emilkowalski/skills / skills/apple-design](https://github.com/emilkowalski/skills/tree/d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7/skills/apple-design) — contrast and reduced-transparency review criteria; content verified against commit `d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7`, while the earlier local import baseline remains unknown. + +Imported criteria apply to evidence-based interface audits. Automatic +invocation remains limited to hands-on verification where it adds confidence. ## post-merge-cleanup @@ -232,9 +232,25 @@ changes" commit gate and the `/doctor` remote playbook. The example command is the full verbose scan. The flag table includes `--base` and `--include-untracked` for partial scopes. Automatic discovery stays enabled. -## refactoring-ui-skill - -- [s0xDk/refactoring-ui-skill / SKILL.md](https://github.com/s0xDk/refactoring-ui-skill/blob/main/SKILL.md) — imported revision: unknown. +## ui-design + +- [s0xDk/refactoring-ui-skill](https://github.com/s0xDk/refactoring-ui-skill) — imported revision: unknown; its `SKILL.md`, reference write-ups, and CSS tokens are adapted into the local entrypoint, web references, and token asset. +- [anthropics/skills / skills/frontend-design](https://github.com/anthropics/skills/tree/34040c9c568585f6929bedeaad110ad08f079624/skills/frontend-design) — art-direction calibration and critique; commit `34040c9c568585f6929bedeaad110ad08f079624`. +- [emilkowalski/skills / skills/emil-design-eng](https://github.com/emilkowalski/skills/tree/d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7/skills/emil-design-eng) — web typography, component behavior, and access guidance; content verified against commit `d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7` while the earlier local import baseline remains unknown. +- [emilkowalski/skills / skills/apple-design](https://github.com/emilkowalski/skills/tree/d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7/skills/apple-design) — typography, materials, press activation and cancellation, contrast, and reduced-transparency guidance; content verified against commit `d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7`, while the earlier local import baseline remains unknown. + +The automatically discoverable skill owns cross-platform visual hierarchy, +system decisions, and art direction plus browser component behavior and +accessibility. It routes web visual work to adapted Refactoring UI references +and an optional CSS token asset, browser interaction work to a focused behavior +reference, and SwiftUI or UIKit visual work to Apple-platform guidance grounded +in current Apple documentation. Native structure, behavior, and accessibility +remain with `swiftui` and `uikit`; motion remains with `animate`. Inherited +numeric recipes are contextual fallback heuristics rather than requirements. +The art-direction reference preserves Anthropic's subject-matter grounding, +generated-design tells, two-pass self-critique, restraint guidance, and Chanel +editing mnemonic while removing CSS implementation and general copywriting +material. ## research diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index d12e42b..37dfd4e 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -9,14 +9,14 @@ material keeps the terms listed below; the root license does not replace them. | --- | --- | --- | | Rudrank Riyam | app-store-connect usage and workflow guides | [MIT](licenses/rudrankriyam-app-store-connect-cli-skills.txt) | | Matt Pocock | Skills and Standards/Spec review references listed in SOURCES.md | [MIT](licenses/mattpocock-skills.txt) | -| Emil Kowalski | animate and design-eng | [animate MIT](licenses/emilkowalski-animate.txt), [design-eng MIT](skills/design-eng/LICENSE.md) | +| Emil Kowalski | animate; motion and gesture behavior; typography and materials; interface access/input and review guidance | [animate MIT](licenses/emilkowalski-animate.txt), [design engineering MIT](licenses/emilkowalski-design-eng.txt) | | Jakub Antalík / transitions.dev | animate pattern references and tuning guidance | Unresolved: no license file found at the recorded revision | | Dietrich Gebert / Ponytail | review-fix-loop/references/ponytail.md | [MIT](licenses/DietrichGebert-ponytail.txt) | | Cursor | review-fix-loop/references/thermo.md | [MIT](licenses/cursor-plugins.txt) | -| Anthropic skills | frontend-web-design | [Upstream Apache-2.0](https://github.com/anthropics/skills/blob/34040c9c568585f6929bedeaad110ad08f079624/skills/frontend-design/LICENSE.txt) | +| Anthropic skills | ui-design art-direction guidance | [Apache-2.0](licenses/anthropics-frontend-design.txt) ([upstream](https://github.com/anthropics/skills/blob/34040c9c568585f6929bedeaad110ad08f079624/skills/frontend-design/LICENSE.txt)) | | Anthropic Claude Plugins Community | eli5 | [Apache-2.0](licenses/anthropics-claude-plugins-community.txt) | | GitHub gh-stack | gh-stack | [MIT](licenses/github-gh-stack.txt) | -| s0xDk / s13k | refactoring-ui-skill | [MIT and scope note](skills/refactoring-ui-skill/LICENSE) | +| s0xDk / s13k | ui-design skill, web references, and token asset | [MIT and scope note](licenses/s0xdk-refactoring-ui-skill.txt) | | Million Software | react-doctor | [Modified MIT](licenses/millionco-react-doctor.txt) | | Vercel Labs | react-best-practices | Unresolved: upstream repo README and skill frontmatter claim MIT; no license file found at the recorded revision | @@ -31,8 +31,10 @@ products or services. Do not describe it as plain MIT. Its terms still apply alo the root license. The original parent-skill import baseline for animate remains unknown; its -reference imports have recorded revisions in SOURCES.md. The imported revisions -for design-eng and refactoring-ui-skill remain unknown. Bundled notices do not -resolve those source-history gaps. +reference imports have recorded revisions in SOURCES.md. The redistributed +design engineering guidance is tied there to commit `d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7`, +while its earlier local import baseline remains unknown. The imported revision +for s0xDk/refactoring-ui-skill also remains unknown. Bundled notices do not resolve +those source-history gaps. Linked API docs, component catalogs, and other live references sit beside the guidance they support; links alone are not bundled copies. diff --git a/licenses/anthropics-frontend-design.txt b/licenses/anthropics-frontend-design.txt new file mode 100644 index 0000000..f433b1a --- /dev/null +++ b/licenses/anthropics-frontend-design.txt @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/skills/design-eng/LICENSE.md b/licenses/emilkowalski-design-eng.txt similarity index 100% rename from skills/design-eng/LICENSE.md rename to licenses/emilkowalski-design-eng.txt diff --git a/skills/refactoring-ui-skill/LICENSE b/licenses/s0xdk-refactoring-ui-skill.txt similarity index 74% rename from skills/refactoring-ui-skill/LICENSE rename to licenses/s0xdk-refactoring-ui-skill.txt index fae8e8c..5618292 100644 --- a/skills/refactoring-ui-skill/LICENSE +++ b/licenses/s0xdk-refactoring-ui-skill.txt @@ -1,3 +1,14 @@ +SreeStack scope note + +The upstream text below applies to the s0xDk/s13k material adapted into +skills/ui-design/SKILL.md; skills/ui-design/references/diagnose.md, systems.md, +techniques.md, and web.md; and skills/ui-design/assets/tokens.css. In its final paragraph, +“this repository” means the upstream refactoring-ui-skill repository. It does +not claim coverage of SreeStack's combined ui-design skill or material +from other sources. + +Upstream license and scope note (verbatim) + MIT License Copyright (c) 2026 s13k diff --git a/scripts/check_skills.py b/scripts/check_skills.py index 3532598..aade28a 100644 --- a/scripts/check_skills.py +++ b/scripts/check_skills.py @@ -1,4 +1,4 @@ -"""Check required skill fields, source entries, and inline local Markdown links.""" +"""Check required skill fields, source entries, and local Markdown targets.""" from pathlib import Path import re @@ -6,6 +6,7 @@ import sys from urllib.parse import unquote, urlsplit +from markdown_it import MarkdownIt import yaml ROOT = Path(__file__).resolve().parents[1] @@ -26,6 +27,7 @@ errors.append(f"skills/{folder.name}: missing SKILL.md") continue text = skill.read_text() + source_name = folder.name frontmatter = re.match(r"\A---\n(.*?)\n---(?:\n|$)", text, re.S) if not frontmatter: errors.append(f"{skill.relative_to(ROOT)}: missing frontmatter") @@ -39,15 +41,34 @@ value = metadata.get(field) if isinstance(metadata, dict) else None if not isinstance(value, str) or not value.strip(): errors.append(f"{skill.relative_to(ROOT)}: missing or empty {field}") - if f"\n## {folder.name}\n" not in sources: - errors.append(f"skills/{folder.name}: missing SOURCES.md entry") + name = metadata.get("name") if isinstance(metadata, dict) else None + if isinstance(name, str) and name.strip(): + source_name = name.strip() + if source_name != folder.name: + errors.append( + f"{skill.relative_to(ROOT)}: name {source_name!r} " + f"does not match folder {folder.name!r}" + ) + if f"\n## {source_name}\n" not in sources: + errors.append( + f"skills/{folder.name}: missing SOURCES.md entry for {source_name}" + ) +markdown = MarkdownIt() for path in files: if path.suffix.lower() != ".md" or not path.is_file(): continue - text = re.sub(r"```.*?```|~~~.*?~~~", "", path.read_text(), flags=re.S) - text = re.sub(r"(`+).*?\1", "", text, flags=re.S) - for target in re.findall(r"\]\(([^\s)]+)\)", text): + tokens = markdown.parse(path.read_text()) + targets = [] + for token in tokens: + for child in token.children or []: + if child.type == "link_open": + targets.append(child.attrGet("href")) + elif child.type == "image": + targets.append(child.attrGet("src")) + for target in targets: + if target is None: + continue link = urlsplit(target) if link.scheme or link.netloc or not link.path or link.path.startswith("/"): continue @@ -57,4 +78,4 @@ if errors: print("\n".join(errors), file=sys.stderr) sys.exit(1) -print(f"Checked {len(skills)} skills and inline local Markdown links.") +print(f"Checked {len(skills)} skills and local Markdown targets.") diff --git a/scripts/requirements-checks.txt b/scripts/requirements-checks.txt index f62ce0c..35ffd6a 100644 --- a/scripts/requirements-checks.txt +++ b/scripts/requirements-checks.txt @@ -1 +1,2 @@ PyYAML==6.0.3 +markdown-it-py==4.0.0 diff --git a/skills/animate/SKILL.md b/skills/animate/SKILL.md index d477dd4..a4f1ce0 100644 --- a/skills/animate/SKILL.md +++ b/skills/animate/SKILL.md @@ -7,6 +7,10 @@ description: "Design, implement, and tune web, SwiftUI, and UIKit interface moti Build the requested motion on its real platform. An instant state change is a valid result when motion would add delay without meaning. +For an authorized build or fix, implement and test the workflow below. For a +plan or review, leave the product unchanged and report the proposed motion or +instant alternative, exact changes, and checks the implementation must pass. + ## Process 1. Inspect the real interaction, nearby motion, design tokens, target platform and supported versions, input methods, use rate, state changes, and runnable surface. Finish when every animated element in scope has this evidence. @@ -51,7 +55,9 @@ Keep content steady while someone reads or acts on it. Decorative motion must no ## Handoff -Deliver the implemented result first. When the gate rejects motion, deliver the instant or static alternative instead. Then state: +For a build, deliver the implemented result first. When the gate rejects motion, +deliver the instant or static alternative instead. For a plan or review, deliver +the proposal or findings without editing the product. Then state: - The motion gate result and purpose. - The platform mechanism and reduced-motion behavior. diff --git a/skills/animate/references/implementation.md b/skills/animate/references/implementation.md index 6b2b432..c7734cb 100644 --- a/skills/animate/references/implementation.md +++ b/skills/animate/references/implementation.md @@ -12,6 +12,9 @@ Read the full selected pattern, then implement it within the project’s compone ## Tokens and rendering - Each pattern includes its variables. Map them to existing project tokens and keep theme overrides. Add only the values the interaction needs. Scope tokens to avoid collisions across patterns. +- Watch inherited custom properties in large subtrees. When measurement shows + that changing one restyles many descendants, update the narrowest owning + element or state hook instead. - Preserve required structure when adapting selectors. Measure size when a pattern depends on height or width; recheck after content or font changes. - Measure layout, paint, blur, masks, and large surfaces on target browsers. CSS or WAAPI alone does not guarantee compositor execution. Keep `will-change` only where measurement supports it; remove permanent hints when they do not help. - Treat library-specific hooks, including Base UI state attributes and Motion options, as examples. Check the installed API before use. diff --git a/skills/animate/references/patterns/drag-to-dismiss.md b/skills/animate/references/patterns/drag-to-dismiss.md index 5f9a6f2..630f35c 100644 --- a/skills/animate/references/patterns/drag-to-dismiss.md +++ b/skills/animate/references/patterns/drag-to-dismiss.md @@ -4,13 +4,31 @@ Use for a draggable drawer, toast, or sheet whose motion can reverse while held. ## Track the active pointer -- Capture one pointer, retain its grab offset, and ignore other pointers until release or cancellation. -- Handle `pointercancel` and release capture on teardown. A second touch must not take over the drag. +- Define the gesture's axis contract on the target and relevant ancestor chain + before the gesture starts. A horizontal dismissal inside vertically scrolling + content should allow `touch-action: pan-y pinch-zoom`; use the corresponding + perpendicular pan value with `pinch-zoom` for a vertical dismissal inside a + horizontal scroller. When scrolling and dismissal need the same axis, provide + a dedicated handle or an explicit boundary policy instead of making both claim + the whole surface. +- Track one initial pointer and ignore additional pointers. Wait for a small, + tunable movement threshold before committing to a direction. Keep plausible + directions unresolved until intent is clear. Record the grab offset on pointer + down even when capture must wait. +- If no browser scroll can compete, capture the initial pointer on pointer down. + Otherwise capture it only once dismissal wins. If perpendicular scrolling + wins, leave the pointer to the browser and clear local gesture state. Do not + use `touch-action: none` or cancel the browser's default behavior while + scrolling remains a valid outcome. +- Handle `pointercancel` as browser or system takeover: release capture and clear + the pressed or drag state without committing dismissal. Release capture on + teardown. A second touch must not take over the drag. - Write the dragged element's transform directly. Limit high-frequency style updates to the moving element. - Apply rising resistance beyond bounds. Preserve the intended dismissal direction. ```js -element.style.transform = `translateY(${distance}px)`; +// Choose X or Y from the axis contract; distance is signed toward dismissal. +element.style.transform = `translate${axis}(${distance}px)`; ``` ## Release and settle diff --git a/skills/animate/references/web.md b/skills/animate/references/web.md index a7adaf4..bf2c2f7 100644 --- a/skills/animate/references/web.md +++ b/skills/animate/references/web.md @@ -37,12 +37,19 @@ Extend current tokens before adding new curves or times. Add a library only when - Use transitions for state changes that must retarget and springs for gesture-driven values. - Start an interruption from the live on-screen value, not the previous target. - Carry release velocity into gesture motion and project it toward the likely resting point. -- Keep dragged content attached to the pointer, preserve the grab offset, and capture the pointer through the gesture. +- For a drag without competing browser scrolling, capture the active pointer on + pointer down, preserve its grab offset, and keep the content attached through + the gesture. When drag intent competes with scrolling, declare the browser's + allowed pan axis and defer capture until the drag wins. Follow + [drag to dismiss](patterns/drag-to-dismiss.md) for arbitration and cancellation. - Apply rising resistance past a drag boundary rather than a hard stop. - Enter and exit along paths that preserve spatial meaning. Tune their times separately when the system response should be faster. ## Access and input +- For motion on a web control, use `ui-design` for the action's activation, + cancellation, pointer, and keyboard contract. This skill owns the moving + feedback's timing and interruption. - Honor `prefers-reduced-motion`. Replace large movement, zoom, parallax, and bounce with a short fade, color change, or instant state change. - Gate hover-only motion with `@media (hover: hover) and (pointer: fine)`. - Keep controls usable while decorative motion runs. diff --git a/skills/design-eng/SKILL.md b/skills/design-eng/SKILL.md deleted file mode 100644 index d536b2c..0000000 --- a/skills/design-eng/SKILL.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -name: design-eng -description: Design engineering. Use when planning, building, or reviewing - interface polish, component behavior, motion, gestures, visual hierarchy, - materials, typography, or accessibility. -disable-model-invocation: true -license: LICENSE.md ---- - -# Design engineering - -Use this process to plan, build, or review interface craft. Match the product's own design system before applying any default below. - -## Process - -1. Inspect the real interface. Record its purpose, hierarchy, states, content, input methods, use rate, type, surfaces, nearby patterns, and access behavior. Finish when every component in scope has this evidence. -2. Decide what the interface must communicate and which feedback, motion, material, or type choices serve that goal. Frequent and keyboard-led actions should usually feel instant. -3. Choose the component behavior and visual rules below. Extend the product's current tokens and patterns before adding new ones. -4. For an authorized build or fix, implement the smallest change that solves the full interaction, including edge states. For planning or review, keep the product unchanged and specify the exact change instead. -5. For a build or review, test the relevant path: enter, exit, interruption, repeated input, keyboard, pointer and touch use, focus order, semantics, announced status, text scaling, reduced motion, and a busy page. For a plan, name the exact checks the implementation must pass. Slow motion when needed to find bad origins, abrupt stops, or properties that drift out of sync. -6. Report each issue with its location, current behavior, exact change, and reason. Rank changes by user impact. - -Completion depends on the task: - -- A plan is done when every component in scope has an exact change and test plan. -- A review is done when every applicable check has evidence and every finding has a clear fix. -- A build is done when the implemented result passes the applicable checks on its real surface. - -## Foundations - -- Start with purpose and hierarchy. The most important action or content should be the easiest to find and understand. -- Put controls near what they affect. Use familiar placement and behavior unless testing proves a new pattern works better. -- Give immediate, continuous feedback while input is active. Show status, completion, warning, and error states at the point where they matter. -- Prefer strong defaults over many options. Handle loading, empty, error, overflow, interruption, and repeated input inside the component. -- Keep related components consistent in spacing, shape, type, color, motion, and control behavior. -- Use delight as the result of clarity, response, and craft rather than as decoration added at the end. - -## Motion decisions - -### Frequency and purpose - -| Use rate | Default | -| --- | --- | -| Very frequent or keyboard-led | Instant | -| Frequent, such as hover or list movement | None or very short | -| Occasional, such as a modal, drawer, or toast | Standard UI motion | -| Rare, explanatory, or celebratory | More room for delight | - -Motion needs a job: show where an item came from, mark a state change, confirm input, explain a feature, or keep a change from feeling abrupt. Remove motion that adds delay without doing one of these jobs. - -### Curves and time - -- Enter or exit: start with a strong ease-out so the interface responds at once. -- Move or morph on screen: start with ease-in-out. -- Hover or color change: start with ease. -- Constant motion: use linear. -- UI motion should usually finish within 300ms. Start near 100–160ms for press feedback, 125–200ms for tooltips and small popovers, 150–250ms for menus, and 200–500ms for large panels. -- Tune enter and exit on their own. The system's response on exit often benefits from a shorter time. -- Use the product's curves. If none exist, strong starting points are `cubic-bezier(0.23, 1, 0.32, 1)` for ease-out and `cubic-bezier(0.77, 0, 0.175, 1)` for ease-in-out. - -Treat these values as test points, not laws. Content, distance, size, and product tone change what feels right. - -## Component and gesture behavior - -- Give pressable controls quick feedback. A small active scale, often `0.97`, works when it fits the control and does not shift layout. -- Start press feedback on pointer-down; commit on a valid release or click. Cancel when the pointer leaves the allowed target or the press becomes a drag. Keep keyboard feedback equally clear and immediate. -- Enter near the final size, such as `scale(0.95)` with opacity, instead of growing from `scale(0)`. -- Set a popover's transform origin to its trigger. Keep an unanchored modal centered. -- Delay the first tooltip enough to avoid stray activation, then show nearby tooltips at once while the user explores the group. -- Stagger only rare, decorative entrances. Keep gaps short and leave controls usable during the sequence. -- Keep dragged content attached to the pointer and preserve the point where the user grabbed it. Capture the pointer through the full gesture. -- Use a small movement threshold before committing a gesture direction. Ignore extra touch points until the gesture ends. -- For drag dismissal and snapping, consider both distance and release speed. Project momentum toward the likely resting point instead of using the release position alone. -- Apply rising resistance past a boundary instead of a hard stop. -- Start an interrupted animation from its live on-screen value and carry velocity into the new target. Springs suit gestures and other interruptible motion; keep bounce slight unless play is part of the product. - -## Materials and hierarchy - -- Use surface treatment to explain structure: solid surfaces for primary content, raised or translucent surfaces for controls that float above it, and scrims for blocking tasks. -- Match separation to the surface. Prefer a restrained mix of background, border, shadow, and blur over stacking every effect. -- Keep text and controls legible over translucent or busy backgrounds. Avoid stacking light translucent layers where contrast collapses. -- Dim the background for a modal task. Keep a parallel, non-blocking panel connected to the main flow without a heavy scrim. -- Make surface weight fit size and role. Large panels may need stronger separation than chips or small controls. - -## Typography - -- Use the product's type scale first. Build hierarchy with size, weight, line height, spacing, and contrast as one system. -- Tune tracking for the typeface, size, and writing system. Avoid one letter-spacing value across all text. -- Use tighter line height for large headings and more room for body text. Check long copy, localization, and dense data. -- Prefer fonts with the needed weights, symbols, scripts, and optical sizing. Use `font-optical-sizing: auto` when the face supports it. -- Let text and layout scale together with relative units. Test the user's larger text setting instead of treating overflow as an edge case. - -## Implementation rules - -- Prefer `transform` and `opacity` for smooth visual motion. Measure before accepting layout-heavy animation. -- Name each transitioned property. `transition: all` hides cost and can animate later changes by mistake. -- Use transitions for state changes that must retarget. Use keyframes for fixed sequences or loops. Use the Web Animations API when code needs direct control without a motion library. -- Use percentages when travel should track the element's own size. -- Watch inherited CSS variables in large trees: changing one can restyle many children. Update the target element directly when measurement shows this cost. - -## Access and input - -- Honor `prefers-reduced-motion`. Keep useful fades or color changes, and remove or cut large movement, zoom, parallax, and other motion that may cause harm. -- Honor reduced-transparency and increased-contrast preferences where the platform exposes them. Replace blur with a more solid surface and preserve clear boundaries. -- Prefer native elements and semantics. Give controls clear names, roles, values, and states; associate form labels, help, and errors with their fields. -- Keep focus visible and ordered by the task. Every action should work from the keyboard without trapping focus. -- Announce async status, validation, and errors when sighted users can see them but focus does not move. -- Gate hover-only effects with `@media (hover: hover) and (pointer: fine)`. -- Keep input and state changes available while decorative motion runs. -- Test touch and drag work on a real device when possible. Check changed semantics and announcements with a screen reader. - -## Review checks - -Check every item that applies: - -- Purpose, hierarchy, labels, and control placement are clear. -- Loading, empty, error, overflow, and interruption states work. -- Keyboard, pointer, touch, focus, screen-reader, and larger-text paths work. -- Motion has a purpose, suits its use rate, and handles rapid repeat and reversal. -- Curves, times, transform origins, and gesture physics match the action. -- Materials preserve hierarchy and contrast across their backgrounds. -- Type remains legible across size, weight, localization, and text scaling. -- The code names animated properties and avoids needless layout or paint work. -- Reduced-motion, reduced-transparency, contrast, and hover paths work. -- The result fits nearby components and the product's tone. - -## Source - -Adapted from Emil Kowalski's [`emil-design-eng`](https://github.com/emilkowalski/skills/blob/d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7/skills/emil-design-eng/SKILL.md) and [`apple-design`](https://github.com/emilkowalski/skills/blob/d23d7f88a2e21c9e4b1418c7abe420f5c1052ba7/skills/apple-design/SKILL.md) skills. See `LICENSE.md`. diff --git a/skills/design-eng/agents/openai.yaml b/skills/design-eng/agents/openai.yaml deleted file mode 100644 index 0f30764..0000000 --- a/skills/design-eng/agents/openai.yaml +++ /dev/null @@ -1,6 +0,0 @@ -interface: - display_name: Design Engineering - short_description: Plan, build, and review polished interfaces - default_prompt: Use $design-eng to plan, build, or review the interface craft in this task. -policy: - allow_implicit_invocation: false diff --git a/skills/frontend-web-design/SKILL.md b/skills/frontend-web-design/SKILL.md deleted file mode 100644 index dda1964..0000000 --- a/skills/frontend-web-design/SKILL.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -name: frontend-web-design -description: Use only when building or reshaping UI for websites and web apps. Guidance for distinctive, intentional visual design. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults. ---- - -# Frontend Web Design - -Approach this as the design lead at a design studio known for giving every client a distinct visual identity that is not mistaken for anyone else's. This client has already rejected proposals that felt cliché or templated, and is paying for a distinctive point of view: make deliberate, opinionated choices about palette, typography, and layout that are specific to this brief, and take aesthetic risk if justified. - -## Ground your designs in the subject matter - -If the brief does not identify what the product or subject matter is, identify it yourself before designing, and confirm with the client. You can come up with one concrete subject, the design's audience, and the design's primary job, as a proposal. If there's any information in your memory about the client's preferences or context about what they're building, use that as a hint. The subject's industry, subject matter, materials, and vernacular are where distinctive visual choices come from — a design for a toy for girls aged 8–11 will be very aesthetically different from a dashboard for financial analysts. Build with the brief's real content and subject matter throughout. - -## Design principles - -For web designs, the hero is the first thing viewers will see. Open with the most characteristic thing in the subject's world, in the form that is most appropriate: a headline, an image, an animation, a live demo, an interactive moment, or other treatments. Be deliberate with your choice: a big number with a small label, supporting stats, and a gradient accent is the default treatment, so only use it if that's truly the best option. - -Typography carries the personality of the page. You don't need a different typeface for display or headline text and body content: use one family or two, and if two, make them clearly distinct. - -Choose your typefaces deliberately, not the default families you would reach for on any other project, and set a clear type scale following the default guidance of The Elements of Typographic Style with intentional weights, widths, and spacing. When type is used as a headline or visual element, use the type treatment itself as an active part of the design, not a neutral delivery vehicle for the content. - -Default to line lengths of less than 80 characters. Serif typefaces can have slightly longer line lengths; give serif body text slightly more line-height than a sans-serif. - -Avoid these default typographic treatments; they are the commonest tells of a generated page: -- Accenting just a single word or phrase in a headline, like putting one word in italic/bold or a different color. -- Using all caps for labels. -- Adding unnecessary typographic labels above content. - -Visual structure is information. Structural devices like outlines, borders, numbering, eyebrows, dividers, labels, etc., encode useful information about the content rather than decorate it. Many generic designs use numbered markers (01 / 02 / 03), but that's only appropriate if the content actually is a sequence — like a stepped process or a timeline. Before adding numbered markers, check the content really is a sequence. - -Use non-user-triggered motion sparingly and deliberately, only to draw attention. A single orchestrated moment — one page-load sequence or one reveal — lands better than scattered effects; fade-and-slide-up entrances on each section and hover transitions on every card are the generic default and read as AI-generated. Motion that answers a person's action (opening, expanding, confirming) is welcome when it shows what changed. - -Consider written content carefully. Often a design brief may not contain real content, and it's up to you to come up with copy and placeholder content. Copy can make a design feel as templated as the design itself. See the below section on writing for more guidance. - -## Process: plan, review against the brief, build, critique - -Where the brief pins down a visual direction, follow it exactly — the brief's own words always win. As with a hired human designer, there's often a careful balance between doing what you're good at and taking each project as a chance to experiment and learn. - -Work in two passes. First, brainstorm a short design plan based on the client's design brief: create a compact token system with color, type, layout, and principles. -- Color: describe the core base palette as 4–6 named hex values. -- Type: the typefaces and their roles. -- Layout: a layout concept, using one-sentence prose descriptions and ASCII wireframes to ideate and compare. Include alignment guidance; should the content be left aligned, center aligned, justified? -- Principles: the high-level guidance for what makes this page unique. - -Then review that plan against the brief before building: if any part of it reads like the generic default you would produce for any similar page (work through a similar prompt to see if you arrive somewhere similar) rather than a choice made for this specific brief — revise that part, say what you changed and why. Only after you've confirmed the relative uniqueness of your design plan should you start to write the code, following the revised plan. - -When writing the code, be careful of structuring your CSS selector specificities. It's easy to generate CSS classes that cancel each other out (especially with a type-based selector like .section and an element-based selector like .cta). This can happen often with padding/margin between sections. - -## Restraint and self-critique - -Spend your boldness in one place. Let one element be the memorable thing, keep everything around it quiet and disciplined, and cut any decoration that does not serve the brief. Build to a quality floor without announcing it: responsive down to mobile, visible keyboard focus, reduced motion respected, visually accessible, harmonious color palettes. Critique your own work as you build, taking screenshots to review if your environment supports it — a picture is worth 1000 tokens. Consider Chanel's advice: before leaving the house, take a look in the mirror and remove one accessory. Human creatives have memory and always try to do something new, so if you have a space to quickly jot down notes about what you've tried, it can help you in future passes. - -## More on writing in design - -Words appear in a design for one reason: to make it easier to understand and use. They are design content, not decoration. Bring the same intentionality and minimalism to copywriting that you would bring to spacing and color. Before writing anything, ask what the design needs to say, and how it can best be said to help the person navigate the experience. - -Write from the end user's perspective. Name things by what users will understand in simple language, not by how the system is built. A user manages notifications, not webhook config. Describe what something is or does in plain terms rather than selling it. Being specific and legible to new users is always better than being clever. - -Use active voice as default. A CTA says exactly what happens when it is used: "Save changes," not "Submit." An action keeps the same name through the whole flow, so the button that says "Publish" produces a toast that says "Published." The vocabulary of an interface is the signposting for someone navigating the product. Cohesion and consistency are how people learn their way around. - -Treat failure and emptiness as moments for direction, not mood. Explain what went wrong and how to fix it, in the interface's voice rather than a person's. Errors don't apologize, and they are never vague about what happened. An empty screen is an invitation to act. - -Keep the tone conversational: plain verbs, sentence case, no filler, with tone matched to the brand and the audience. Let each written element do exactly one job. diff --git a/skills/manual-verify/SKILL.md b/skills/manual-verify/SKILL.md index 0dee32d..8180827 100644 --- a/skills/manual-verify/SKILL.md +++ b/skills/manual-verify/SKILL.md @@ -1,6 +1,6 @@ --- name: manual-verify -description: Verify changes through real user workflows when hands-on testing would add confidence, including web apps in a browser and native iOS or macOS apps. +description: Exercise and assess real user workflows when hands-on acceptance testing or an evidence-based interface audit would add confidence, including web apps in a browser and native iOS or macOS apps. --- # Manual Verify @@ -12,9 +12,27 @@ evidence, not the verdict. ## Workflow 1. **Choose workflows.** Read the request and changes. Identify the affected - users, their goal, and nearby behavior the change could break. Select the - smallest useful set of realistic workflows covering the main path and any - material error or edge case. State the expected result of each workflow. + users, their goal, and nearby behavior the change could break. + + Treat verification of a changed workflow or behavior as acceptance work. + Treat a whole-surface visual, interaction-quality, or accessibility judgment + as an interface audit. If the request includes both, apply each completeness + rule to its own scope. + + For acceptance verification, select the smallest useful set of realistic + workflows covering the main path and any material error or edge case. State + the expected result of each workflow. + + For an interface audit, identify the requested dimensions first: visual + system, motion, behavior, or accessibility. Load only their specialists: + `ui-design` for visual systems and web behavior or accessibility, `animate` + for motion, and `swiftui` or `uikit` for native Apple behavior or + accessibility. Then inventory every surface, component, state, + input method, and accessibility path relevant to the selected dimensions. If + no matching specialist exists, use the project's platform guidance and the + observe-act-observe workflow below. Turn every applicable criterion within + each selected dimension into an assertion; do not sample that dimension down + to a representative subset. 2. **Choose the interface.** Use the product surface its users use. For a web app, read [web verification](references/web.md). For an iOS app, read @@ -60,6 +78,12 @@ evidence, not the verdict. When the expected result includes persisted data or an output artifact, verify it through a fresh read path rather than relying on the current screen alone. + When accessibility is in scope, check names, roles, values, states, label and + error relationships, task-ordered focus, keyboard traps, text scaling, and + whether visible async status is announced when focus does not move. + When materials are affected, check increased contrast and reduced transparency + where the platform exposes them. + 5. **Report evidence.** For each workflow, state what was exercised and the expected and observed result. Give each required acceptance assertion a status: @@ -80,6 +104,13 @@ evidence, not the verdict. semantic snapshots when they explain the conclusion. Name any untested behavior or environmental gap rather than treating it as passing. + For an interface review, report each issue with its location, observed + behavior, exact change, and reason, then rank the findings by user impact. + + An interface audit is complete only when every inventoried item and applicable + specialist criterion is `passed`, `failed`, `blocked`, or explicitly + `untested`. The audit passes only when all required assertions pass. + If login or another step requires the user, tell them exactly what to do and where, then resume after they finish. Continue independent checks meanwhile. diff --git a/skills/refactoring-ui-skill/README.md b/skills/refactoring-ui-skill/README.md deleted file mode 100644 index 6c8ce87..0000000 --- a/skills/refactoring-ui-skill/README.md +++ /dev/null @@ -1,80 +0,0 @@ -# Refactoring UI (Claude Code skill) - -A [Claude Code](https://claude.com/claude-code) skill that teaches Claude the concrete, -mechanical rules from the book *[Refactoring UI](https://www.refactoringui.com/)* by Adam -Wathan and Steve Schoger — constrained spacing/type/color/shadow scales, visual hierarchy -through weight and color rather than size, and depth through emulated light. - -Every rule and CSS value in this skill was cross-checked page-by-page against the book. -It's not a summary — it's the book's decisions, made once, ready to apply. - -## What it does - -Load this skill and Claude will, when styling or reviewing UI: - -- Pick spacing, type sizes, weights, colors, shadows and radii **from fixed scales** - instead of ad hoc values -- Build hierarchy through weight/color rather than piling on font-size -- Diagnose vague complaints ("looks off", "feels cheap") into specific, mechanical fixes -- Apply concrete techniques for depth, contrast, images, and breaking generic component - shapes - -It does **not** include the book itself — see [Credits](#credits). - -## Repo structure - -``` -SKILL.md the skill: systems, procedure, hierarchy, hard rules -references/ - systems.md building a color palette from scratch (HSL, saturation, hue rotation) - diagnose.md symptom -> fix table, for improving existing UI - techniques.md depth/light simulation, typefaces, grids, images -assets/ - tokens.css a complete, contrast-verified starter token set -``` - -## Installation - -Claude Code loads skills from a folder containing a `SKILL.md`. Clone this repo into one -of the skill directories below — **use the folder name `refactoring-ui`** so it matches -the skill's declared name. - -### Personal skill (available in every project) - -```sh -git clone https://github.com//refactoring-ui-skill.git ~/.claude/skills/refactoring-ui -``` - -### Project skill (checked into a specific repo, shared with your team) - -```sh -git clone https://github.com//refactoring-ui-skill.git .claude/skills/refactoring-ui -``` - -(Or add it as a git submodule at that path if you want to track updates.) - -Restart Claude Code (or start a new session) after installing so it picks up the new -skill. - -## Usage - -The skill activates automatically whenever Claude is building or styling UI, picking -font sizes/spacing/colors/shadows, designing a palette or design tokens, or when you say -a UI "looks off", "looks amateur", or "feels cluttered/plain/unfinished." You can also -invoke it explicitly: - -``` -/refactoring-ui make this dashboard look less amateur -``` - -## Credits - -All design rules and reasoning are drawn from *Refactoring UI* by Adam Wathan and Steve -Schoger. This repo does not include the book's text or images — only original notes and -CSS derived from its concepts. If you find this useful, buy the book: -**https://www.refactoringui.com/** - -## License - -MIT for the contents of this repo (see [LICENSE](LICENSE)). Does not extend to the book -itself. diff --git a/skills/refactoring-ui-skill/SKILL.md b/skills/refactoring-ui-skill/SKILL.md deleted file mode 100644 index d35e416..0000000 --- a/skills/refactoring-ui-skill/SKILL.md +++ /dev/null @@ -1,267 +0,0 @@ ---- -name: refactoring-ui -description: Design and improve user interfaces using the concrete rules from Refactoring UI (Wathan & Schoger) — constrained spacing/type/color/shadow scales, visual hierarchy through weight and color rather than size, and depth through emulated light. Use when building or styling any UI (web, app, dashboard, landing page, component), when picking font sizes, spacing, colors, shadows or border radius, when designing a color palette or design tokens, and whenever someone says a UI "looks off", "looks amateur", "feels cluttered/plain/unfinished", or asks to "make this look better". ---- - -# Refactoring UI - -Visual design is not talent. It is a small set of systems decisions made **once**, plus a -handful of techniques for creating hierarchy. This skill is those systems and those -techniques. - -The single biggest cause of amateur-looking UI is picking values ad hoc — 17px here, -`#3B82F6` there, `lighten(5%)` for a hover state. Design *from a scale*, always. - ---- - -## The systems — use these, do not re-derive them - -Pick from these lists. Never invent a value that isn't on one. - -### Spacing and sizing - -Base 16px, built from factors and multiples of it: - -``` -4 8 12 16 24 32 48 64 96 128 192 256 384 512 640 768 -``` - -Tight at the small end, spreading out at the large end. **No two adjacent values may be -closer than ~25%** — that is what makes the choice obvious. A linear "multiples of 4" -scale fails: it does not help you decide between 120px and 124px. - -Use it for margin, padding, width, height, icon sizes, border width — everything spatial. -Fix a small set of opacity values too (e.g. `.05 .1 .2 .4 .6 .8`) for disabled states, -overlays and hover tints, rather than eyeballing a slider each time. Same logic as the other -scales: decide once, reuse everywhere. - -### Type scale - -``` -12 14 16 18 20 24 30 36 48 60 72 -``` - -Not a modular scale built from a ratio (4:5, 2:3, golden ratio). Those produce fractional -pixel values that round inconsistently across browsers and are too sparse for interface -density — hand-picked values, chosen for how they feel, win instead. - -**Units: `px` or `rem` only. Never `em`.** `em` is relative to the current font size, so a -`.875em` inside a `1.25em` parent computes to 17.5px — a value not in your scale. The -scale silently stops existing. - -### Font weight - -Two weights is enough: - -- **400 or 500** — body and most UI text -- **600 or 700** — anything emphasized - -Nothing below 400 in UI. To de-emphasize, use a lighter *color* or smaller *size* — never a -lighter weight. - -### Color - -You need far more colors than a five-swatch palette generator gives you. - -- **Greys: 8–10 shades.** Almost all of a UI is grey — text, backgrounds, panels, borders, - form controls. Three or four shades always runs out. Start at a very dark grey, not true - black (true black looks unnatural). -- **Primary: 5–10 shades**, one or maybe two primaries. -- **Accents: 5–10 shades each** — destructive red, warning yellow, positive green, plus - whatever else the product needs to distinguish (chart series, calendar events, tags). Ten - colors × 5–10 shades is normal for a complex UI. - -Name them `100` (lightest) → `900` (darkest), base `500`. - -**Build the scale in this order:** pick `500` first (for a primary/accent, it should be a -shade that works as a button background). Then find the edges — `900` is usually your text -color, `100` a background tint; an alert component uses both, so design one and read the -two values off it. Then fill `700` and `300` as the perfect compromise between their -neighbours, then `800 600 400 200` the same way. - -**Write colors as HSL, not hex.** `hsl(220, 95%, 34%)` and `hsl(220, 65%, 61%)` are -visibly related; `#03369E` and `#507DD7` are not. - -**Never generate shades at runtime** with `lighten()` / `darken()`. That is how you end up -with 35 slightly different blues. - -### Shadows — five elevations - -```css -0 1px 3px hsla(0,0%,0%,.2) /* barely raised — buttons */ -0 4px 6px hsla(0,0%,0%,.2) /* dropdowns */ -0 5px 15px hsla(0,0%,0%,.2) -0 10px 24px hsla(0,0%,0%,.2) -0 15px 35px hsla(0,0%,0%,.2) /* modals */ -``` - -Choose by asking *where on the z-axis does this sit?*, not *what shadow looks nice?*. -Closer to the user = more attention. Shrinking a button's shadow on `:active` makes it feel -pressed; growing a list item's shadow when it's picked up for drag-to-reorder does the -reverse — it reads as "now above its siblings" and doubles as the drag affordance itself. - -These five are the default and are fine everywhere. `references/techniques.md` gives a -refined **two-part** version of the same scale — parallel, but not identical values (its top -step is heavier). Use it when shadows are prominent in the design; use these when they -aren't. Don't mix the two in one project. - -### Line-height and line length - -Line-height is **inversely** proportional to font size, and proportional to line width: - -- small text / wide columns → `1.5` to `2` -- large headlines → `1` is fine - -Line length: **45–75 characters**, i.e. `max-width: 20em–35em`. This applies to the -paragraph even when the container around it is wider — mixed widths in one content area -look more polished, not less. - -(`em` is correct *here* — measure should scale with the text it wraps. The "never `em`" rule -is scoped to the *type scale*, where `em` compounds through nesting. Don't "fix" this.) - -### Border radius - -Pick one and stay consistent. Small radius = neutral. Large radius = playful. None = -serious/formal. Mixing square and rounded corners in one interface always looks worse. - ---- - -## The procedure - -**1. Start with a feature, not a layout.** Don't design "the app" — you cannot decide -between top nav and sidebar before you know what's in the product. Design one real piece of -functionality (the search form, the message composer), and let the shell emerge. - -**2. Detail comes later.** Ignore typefaces, shadows and icons early. Work in **grayscale -first** — it forces hierarchy to come from spacing, contrast and size rather than color. -Add color once the layout works. - -**3. Don't over-invest in low fidelity.** Sketches, wireframes and mockups are disposable — -nobody can use a static picture of an app. They exist to explore ideas; abandon them once the -decision is made and go build the real thing. - -**4. Design the smallest useful version, then build it.** Work in short design→code cycles. -Don't imply functionality you aren't ready to build — a comment box with an attachments -zone you can't ship yet blocks the whole feature. Nice-to-haves get designed later. - -**5. Choose by elimination.** When picking a value from a scale: guess the one you think is -right, then compare it against the neighbour on each side. Two will be obviously wrong. If -an outer option wins, re-run the comparison with that as the new middle. - -**6. Start with too much white space and remove it.** Adding space until something stops -looking bad gives you the minimum. Starting generous and trimming gives you the right -amount. Dense UIs (dashboards) are legitimate — but as a deliberate decision, not a default. - -**7. Shrink the canvas.** A small component designed on a 1400px artboard tends to sprawl, -because the space is there to fill. Start at ~400px and design the mobile layout first, where -the constraints are real — then bring it to a large screen and relax only what genuinely felt -cramped. You will change less than you expect. - ---- - -## Hierarchy — the technique that does the most work - -Everything on screen sits in a pyramid: primary, secondary, tertiary. When everything -competes, the UI reads as noise. This is what makes a design look "designed" — not styling. - -**Size isn't everything.** Leaning on font size alone gives you primary content that's too -big and secondary content that's too small. Use **weight** and **color** to carry emphasis -instead, and keep sizes reasonable. - -**Three text colors, maximum:** -- dark — primary content -- grey — secondary content -- lighter grey — tertiary (footnotes, copyright) - -All three carry real body-size text, so all three need 4.5:1. "Lighter grey" means the -lightest shade that still clears it — roughly the middle of a 9-step ramp, not the pale end. -The pale shades are for disabled states and large text only. - -**Emphasize by de-emphasizing.** When the important element won't stand out and there's -nothing left to add to it, soften what competes with it instead. Fade the inactive nav -items; drop the sidebar's background color so the main content sits forward. - -**Actions:** style by hierarchy, not by semantics. -- Primary → solid, high contrast. Usually exactly one per page. -- Secondary → outline, or a low-contrast background. -- Tertiary → styled like a link. - -Destructive ≠ big red button. If "Delete" isn't the primary action on the page, give it -tertiary treatment — then make it a big red primary button *inside the confirmation dialog*, -where it genuinely is the primary action. - -**Labels are a last resort.** `label: value` gives every piece of data equal weight. Most -data identifies itself by format (`$19.99`, an email address) or by context. Where a label -is genuinely needed, fold it into the value ("12 left in stock", not "In stock: 12"), or -add it as visibly *secondary* content. Exception: on spec-sheet-style pages where users scan -*for the label*, emphasize the label instead. - -**Balance weight against contrast.** Solid icons are visually heavy and will out-shout the -text beside them — soften their color to compensate. It works in reverse too: when a 1px -border is too subtle in a soft color but too harsh once you darken it, keep the soft color -and go to 2px. Add weight to fix low contrast; reduce contrast to fix excess weight. - -**Visual hierarchy ≠ document hierarchy.** Semantic markup and visual weight are separate -decisions. Section titles are usually *labels*, not headlines — an `h1` at 16px is fine, and -sometimes the title should be visually hidden entirely because the content speaks for itself. - ---- - -## Hard rules - -Deviating from these produces a specific, recognizable failure. - -1. **Never grey text on a colored background.** Grey-on-white works because it *reduces - contrast*; grey on color just looks dirty. White-at-reduced-opacity looks washed out and - disabled, and lets patterns show through the glyphs. Hand-pick a color with the - background's hue, adjusting saturation and lightness. -2. **Never `em` for the type scale.** `px` or `rem`. -3. **Never generate shades at runtime.** Define them up front. -4. **Never use a percentage width for something that shouldn't scale.** Sidebars get fixed - widths; the main area flexes. Elements get a `max-width` and only shrink when the screen - is actually smaller — a login card shouldn't be *wider* at medium screens than at large. -5. **Never scale things proportionally across breakpoints.** Large elements must shrink - *faster* than small ones. A 2.5em headline sitting on 14px mobile body copy computes to - 35px — far too big; it wants to be 20–24px there. Likewise a button's padding should get - proportionally tighter as the button shrinks, not scale with its font size. -6. **Always more space around a group than within it.** This is the fix for "which label - belongs to which field", cramped bullet lists, and headings that look attached to the - wrong paragraph. Ambiguous spacing is a functional bug, not just an ugly one. -7. **Never use color as the only signal.** Add an icon, a shape, or a text cue. For charts, - distinguish series by *contrast* (light→dark shades of one color) rather than by hue — - colorblind users read lightness reliably, hue not so much. -8. **Contrast minimums:** 4.5:1 for normal text. The 3:1 allowance applies only to *large* - text, which WCAG defines as **24px regular or 18.66px bold** — not 18px. Assume 4.5:1 - unless the text is genuinely that large. When white-on-color fails, flip it: dark colored - text on a light colored tint (see `references/systems.md`). Separately, **3:1 applies to - non-text too** (WCAG 1.4.11): if a border is the only thing identifying a control — an - input outline, a checkbox edge — it needs 3:1 against its background. A hairline that - merely divides content does not. Those are two different tokens, not one. -9. **Never scale an icon far from its intended size.** A 16–24px icon at 48px looks chunky - and detail-starved. Put it inside a colored circle instead. - ---- - -## References - -**`assets/tokens.css`** — a complete, contrast-verified starting set of all the above as CSS -custom properties: spacing, type, weights, border width, a fixed opacity scale, a 9-shade -cool grey ramp, a 9-shade primary, three accent trios, five elevations, a **semantic role -layer** (`--surface`, `--text-primary`, `--action`…) and a **dark-mode block** that overrides -only those roles. Copy it in and retune -the hues rather than re-deriving the scales from this prose. Reference the roles in -components, not the raw ramps — that is what makes the dark mode work. Every text/surface -pair is verified ≥4.5:1 in both modes and every functional border ≥3:1; the deliberate -sub-threshold shades (disabled, decorative dividers, the large-text-only step) are exempt by -criterion and commented inline. - -Load these when the work calls for them: - -- **`references/systems.md`** — building a palette from scratch: choosing the base color, - keeping saturation alive at the light and dark ends, hue rotation, warm/cool greys, and - the two escape hatches for hitting contrast ratios without ugly color. -- **`references/diagnose.md`** — symptom → fix table. Load first whenever the task is - *improving existing UI* rather than building new. -- **`references/techniques.md`** — depth and light simulation, two-part shadows, baseline - alignment, letter-spacing, breaking out of default component shapes, and handling - user-uploaded images. diff --git a/skills/swiftui/SKILL.md b/skills/swiftui/SKILL.md index f1021a6..b1e09d5 100644 --- a/skills/swiftui/SKILL.md +++ b/skills/swiftui/SKILL.md @@ -1,6 +1,6 @@ --- name: swiftui -description: SwiftUI interface work on Apple platforms. Use when choosing SwiftUI versus UIKit; building or restructuring SwiftUI views, state flow, navigation, presentation, or Liquid Glass; or applying a diagnosed SwiftUI performance fix. +description: SwiftUI interface work on Apple platforms. Use when choosing SwiftUI versus UIKit; building, reviewing, or restructuring SwiftUI views, state flow, navigation, presentation, component feedback, async or edge-state behavior, accessibility semantics, or Liquid Glass; or applying a diagnosed SwiftUI performance fix. --- # SwiftUI @@ -9,6 +9,10 @@ Shape the interface around SwiftUI's ownership, identity, and environment rather than reproducing an imperative view hierarchy. Preserve the product's existing architecture and deployment targets unless the task changes them. +For an authorized build or fix, implement and test the workflow below. For a +plan or review, leave the product unchanged and turn its implementation and test +steps into exact proposed changes, findings, and checks. + ## Workflow 1. Inspect the affected scene, views, models, deployment targets, and existing @@ -33,11 +37,24 @@ architecture and deployment targets unless the task changes them. 4. Prefer native containers and controls for the target platform. Add a UIKit or AppKit bridge at a deliberate boundary when SwiftUI lacks the required behavior; keep lifecycle and ownership on one side of that boundary. -5. Build the affected targets and exercise the changed state transitions. Use +5. For interactive components, give immediate feedback and keep loading, empty, + disabled, error, and overflow states close to the action or content they + describe. Prevent interrupted or repeated async work from letting an older + result overwrite the current state. Prefer platform controls and strong + defaults over extra options; preserve valid activation and cancellation. +6. Preserve useful accessibility semantics. Expose the control's name, value, + state, and actions, and keep focus and announcements aligned with the task and + reading order rather than an incidental view hierarchy. Announce visible async + status, validation, and errors when focus does not move and the change would + otherwise be missed. +7. Build the affected targets and exercise main, edge-state, interruption, and + repeated-input transitions. When behavior or accessibility is in scope, + exercise the supported touch, pointer, keyboard, focus, announcement, and + VoiceOver reading paths. Use `manual-verify` for visual or interactive acceptance checks. Use `animate` for motion design, `ios-haptics` for tactile feedback when its iOS 26+ SwiftUI scope - applies, and `diagnosing-bugs` when a failure or performance regression needs - investigation. + applies, `ui-design` for visual hierarchy and token-system work, and + `diagnosing-bugs` when a failure or performance regression needs investigation. After performance diagnosis identifies the bottleneck, use the data-flow and composition guidance here to narrow invalidation or reduce body work without diff --git a/skills/ui-design/README.md b/skills/ui-design/README.md new file mode 100644 index 0000000..526a9ce --- /dev/null +++ b/skills/ui-design/README.md @@ -0,0 +1,47 @@ +# UI Design skill + +A skill for visual systems across web, SwiftUI, and UIKit, plus browser +component behavior and accessibility. + +The entrypoint routes to focused references for art direction, existing-interface +diagnosis, web systems, browser behavior and accessibility, and Apple-platform +design. The web references and CSS starter preserve useful material derived +from *Refactoring UI* by Adam Wathan and Steve Schoger while treating numeric +recipes as adaptable starting points. + +## Structure + +```text +SKILL.md process, shared principles, and routing +references/art-direction.md brief-specific identity and self-critique +references/diagnose.md symptom-to-cause diagnosis for existing web UI +references/web.md web visual systems and verification +references/web-behavior-and-accessibility.md + browser semantics, states, input, and access +references/apple-platforms.md native typography, color, layout, and checks +references/systems.md building and tuning color ramps +references/techniques.md depth, typography, grids, and images +assets/tokens.css optional web starter tokens +``` + +Install or link the skill through the repository-level instructions in the root +[README](../../README.md). It is automatically discoverable for visual design +on its supported platforms and for browser interface behavior. + +## Credits + +The art-direction guidance adapts Anthropic's frontend-design skill. The web +system material and CSS are notes derived from +*[Refactoring UI](https://www.refactoringui.com/)*. This repository does not +include the book itself. Apple-platform guidance follows the cited Apple +documentation. Typography and material additions adapt Emil Kowalski's work. +See the repository's [source record](../../SOURCES.md) and +[third-party notices](../../THIRD_PARTY_NOTICES.md). + +## License + +SreeStack's original work uses the repository's MIT license. The retained +Refactoring UI skill material uses its +[upstream MIT license and scope note](../../licenses/s0xdk-refactoring-ui-skill.txt). Anthropic +material uses [Apache-2.0](../../licenses/anthropics-frontend-design.txt). See the repository's third-party notices for the full +mapping; none of these terms extends to the *Refactoring UI* book. diff --git a/skills/ui-design/SKILL.md b/skills/ui-design/SKILL.md new file mode 100644 index 0000000..121636a --- /dev/null +++ b/skills/ui-design/SKILL.md @@ -0,0 +1,87 @@ +--- +name: ui-design +description: Cross-platform visual design and browser interface behavior. Use for visual hierarchy, art direction, or design systems in web, SwiftUI, or UIKit; also use for browser component states, input, and accessibility. Use swiftui or uikit for native implementation and behavior, and animate for motion. +--- + +# UI Design + +Turn an interface brief, usability problem, or vague dissatisfaction into a +coherent design. Preserve the product's established language and interaction +contract where they work; change only the dimensions the request puts in scope. + +For an authorized build or fix, implement and verify the change. For a plan, +review, or advisory task, leave the product unchanged and make each proposed +change and acceptance check concrete. + +## Process + +1. Inspect the real interface, nearby components, existing tokens, target + platforms, content, states, appearance modes, text scaling, input methods, + access paths, and runnable surfaces available in scope. +2. Select the dimensions the task actually requires: visual system, art + direction, component behavior, or accessibility. Name the design job before + choosing values or changing behavior. For visual work, identify the primary + content and action, their competitors, the meaningful groups, and the + semantic roles the system must support. +3. Read only the guidance for those dimensions: + - For a new identity or a substantial change in visual direction, read + [art direction](references/art-direction.md) first. + - For an existing web interface that looks wrong, read + [diagnosis](references/diagnose.md), then + [web visual design](references/web.md). For new web visual-system work, + start with the web reference. + - For browser semantics, component states, focus, keyboard or pointer input, + announcements, or accessibility, read + [web behavior and accessibility](references/web-behavior-and-accessibility.md). + - For SwiftUI or UIKit visual work, read + [Apple-platform visual design](references/apple-platforms.md). Use `swiftui` + or `uikit` for native implementation, behavior, and accessibility; those + skills own framework structure, state, and lifecycle. + - Use `animate` when feedback moves or transitions. The relevant platform + skill still owns the action and state contract. +4. For visual work, establish hierarchy through position, grouping, spacing, + weight, color, and size. Extend the system with the fewest new values needed + to express real semantic roles across affected components and states. When + only visual dimensions are selected, keep interaction and access contracts + unchanged. +5. For web behavior or accessibility work, preserve the component's semantic, + activation, focus, input, status, and state contracts across the paths in + scope. Keep visual changes limited to what those contracts require unless + visual direction is also selected. +6. When implementation is in scope, cover every affected state and access + variant rather than styling or testing only the happy path. +7. Exercise the result on the real surface at relevant sizes and through the + affected input and accessibility paths. Use `manual-verify` when hands-on + evidence would add confidence. + +The work is done when every selected dimension has an explicit design job, +affected components and states use one coherent system and contract, and the +result fits both the brief and its surrounding product. Name any browser, +device, appearance, input, or accessibility evidence that remains unchecked. + +## Shared principles + +- Prefer semantic roles such as surface, primary text, secondary text, action, + warning, and separator over raw values at call sites. +- Keep more space around a group than within it. Ambiguous spacing obscures the + information architecture. +- Style actions by importance in the current task. Destructive does not + automatically mean primary. +- Use color consistently and pair it with text, shape, iconography, or another + cue when it communicates state. +- Use depth, borders, materials, and overlap to explain structure. Each cue + needs a job. +- Treat scales and token counts as tools, not quotas. Add a value when the + existing system cannot express a real role clearly. +- Prefer standard platform components and existing product patterns before + custom work. Customize deliberately when identity, hierarchy, or behavior + requires it. + +## Handoff + +Show the implemented result or concrete proposal. State the selected design +dimensions, diagnosed job, roles or contracts changed, and states and access +paths checked. + +For a plan, account for every component in scope with a concrete change or an +explicit reason it remains unchanged. diff --git a/skills/refactoring-ui-skill/assets/tokens.css b/skills/ui-design/assets/tokens.css similarity index 83% rename from skills/refactoring-ui-skill/assets/tokens.css rename to skills/ui-design/assets/tokens.css index dd045ca..21ba856 100644 --- a/skills/refactoring-ui-skill/assets/tokens.css +++ b/skills/ui-design/assets/tokens.css @@ -1,25 +1,25 @@ -/* Refactoring UI — starter tokens. - Copy into a project and rename/retune. The point is to decide once, up front. - Ramps follow the book's rules: HSL, saturation rises as lightness leaves 50%, - greys are tinted (cool here — swap hue to ~39 for warm). */ +/* Example starter tokens for a project with no coherent visual system. + Copy only the roles the product needs, then rename, prune, and retune them + against real content, states, appearances, and contrast. The values are + coordinated examples, not required counts or universal rules. */ :root { - /* ---- Spacing & sizing: base 16, no two neighbours closer than ~25% ---- */ + /* ---- Example spacing and sizing scale ---- */ --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 24px; --space-6: 32px; --space-7: 48px; --space-8: 64px; --space-9: 96px; --space-10:128px; --space-11:192px; --space-12:256px; --space-13:384px; --space-14:512px; --space-15:640px; --space-16:768px; - /* ---- Type scale: px/rem only, never em ---- */ + /* ---- Example fixed type tokens; use rem/em when scaling semantics call for them ---- */ --text-xs: 12px; --text-sm: 14px; --text-base:16px; --text-lg: 18px; --text-xl: 20px; --text-2xl: 24px; --text-3xl: 30px; --text-4xl: 36px; --text-5xl: 48px; --text-6xl: 60px; --text-7xl: 72px; - /* ---- Weight: two, and nothing under 400 ---- */ + /* ---- Example body and emphasis roles; add supported weights for real roles ---- */ --weight-normal: 400; --weight-bold: 600; - /* ---- Line-height: inversely proportional to size ---- */ + /* ---- Example leading and measure; tune for face, size, script, and width ---- */ --leading-tight: 1; /* 36px+ headlines */ --leading-snug: 1.25; /* 20-30px */ --leading-normal: 1.5; /* body, narrow measure */ @@ -41,7 +41,7 @@ --grey-800: hsl(211, 39%, 23%); /* 10.7:1 */ --grey-900: hsl(209, 61%, 16%); /* 13.4:1 — primary text */ - /* ---- Primary. 500 is the shade that works as a button background. ---- */ + /* ---- Primary ramp; 500 is this example's action background. ---- */ --primary-100: hsl(205, 92%, 92%); /* tinted background */ --primary-200: hsl(205, 97%, 85%); --primary-300: hsl(205, 90%, 76%); @@ -66,22 +66,22 @@ --green-500: hsl(154, 85%, 24%); --green-800: hsl(156, 100%, 13%); - /* ---- Elevation. Pick by z-position, not by looks. ---- */ + /* ---- Example elevation roles; tune geometry and color on real surfaces. ---- */ --shadow-1: 0 1px 3px hsla(0, 0%, 0%, .2); /* buttons */ --shadow-2: 0 4px 6px hsla(0, 0%, 0%, .2); /* dropdowns */ --shadow-3: 0 5px 15px hsla(0, 0%, 0%, .2); --shadow-4: 0 10px 24px hsla(0, 0%, 0%, .2); --shadow-5: 0 15px 35px hsla(0, 0%, 0%, .2); /* modals */ - /* ---- Radius: pick one personality and hold it ---- */ - --radius: 4px; /* neutral. 0 = formal, 12px+ = playful */ + /* ---- Example compact-control radius and full/pill radius ---- */ + --radius: 4px; --radius-full: 9999px; - /* ---- Border width: fixed, like everything else ---- */ + /* ---- Example border roles ---- */ --border-width: 1px; --border-width-thick: 2px; /* when a soft-colored 1px border reads too subtle */ - /* ---- Opacity: fixed set, not a slider you eyeball each time ---- */ + /* ---- Example opacity roles ---- */ --opacity-1: .05; /* hairline overlays */ --opacity-2: .1; /* subtle tints, inset shadows on images */ --opacity-3: .2; /* disabled controls */ @@ -89,8 +89,7 @@ --opacity-5: .6; /* dark overlay on photos */ --opacity-6: .8; /* near-opaque overlay */ - /* ---- Semantic roles. Reference these in components, not the raw ramps — - it's the only way the dark-mode block below can work. ---- */ + /* ---- Semantic roles. Prefer these in components so appearance mappings can vary. ---- */ --surface: var(--grey-100); /* page */ --surface-raised: #fff; /* cards — lighter than the page */ --surface-sunken: var(--grey-200); /* wells, inset areas */ @@ -110,14 +109,13 @@ --action-text: #fff; } -/* Dark mode. Not a mechanical inversion — surfaces stack *upward* in lightness, - accents move to the light end of the ramp, and text sits a shade dimmer than - the light-mode equivalent. All *text* pairs verified >= 4.5:1; functional borders +/* Example dark mapping. It is not a mechanical inversion: this system uses + lighter raised surfaces and retuned accents. All *text* pairs verified >= 4.5:1; functional borders are held to the 3:1 non-text bar instead (WCAG 1.4.11); decorative dividers and disabled text are exempt from both. */ @media (prefers-color-scheme: dark) { :root { - --surface: var(--grey-900); /* never pure black */ + --surface: var(--grey-900); /* softer than pure black in this system */ --surface-raised: var(--grey-800); /* raised = lighter, same as light mode. Only a 1.26:1 step, and shadows barely register here — so give raised surfaces a --border-strong diff --git a/skills/ui-design/references/apple-platforms.md b/skills/ui-design/references/apple-platforms.md new file mode 100644 index 0000000..2024109 --- /dev/null +++ b/skills/ui-design/references/apple-platforms.md @@ -0,0 +1,62 @@ +# Apple-platform visual design + +Use this branch for SwiftUI and UIKit. Start with the app's existing design system and standard platform components. Check the deployment target before choosing APIs, and prefer system behavior when custom styling would only recreate it. + +## Hierarchy and layout + +- Place the most important content early in reading order and give it enough space. Use alignment, indentation, grouping, and progressive disclosure to make relationships visible. +- Respect safe areas, system margins, readable-content guides, bars, sheets, and resizable-window behavior. Avoid importing web breakpoints or percentage-grid rules. +- Build an adaptive layout for supported orientations, window sizes, localization, right-to-left direction, and text sizes. Let content drive structural changes instead of identifying devices by model. +- Keep controls distinct from content. Prefer standard navigation, toolbar, list, form, sheet, and control appearances before replacing them with custom containers. + +Apple's [Layout](https://developer.apple.com/design/human-interface-guidelines/layout) guidance covers grouping, visual hierarchy, safe areas, adaptability, Dynamic Type, localization, and window changes. + +## Typography and scale + +- Prefer semantic system text styles. Use weight and semantic foreground roles to refine hierarchy without replacing text styles with a fixed point-size ladder. +- Keep the number of typefaces and weights small. Avoid light weights for small interface text. +- In SwiftUI, use system `Font` styles and `@ScaledMetric(relativeTo:)` when custom geometry or icon sizing must scale with text. +- In UIKit, use preferred text-style fonts. Scale custom fonts and related metrics with `UIFontMetrics`. +- Test every supported Dynamic Type size. Preserve the relative hierarchy, allow useful text to wrap, and avoid truncating information merely to hold the original layout. + +See Apple's [Typography](https://developer.apple.com/design/human-interface-guidelines/typography), SwiftUI [`ScaledMetric`](https://developer.apple.com/documentation/swiftui/scaledmetric), and UIKit [`UIFontMetrics`](https://developer.apple.com/documentation/uikit/uifontmetrics). + +## Color and appearance + +- Prefer semantic system colors for standard roles. Do not copy documented system color values into custom constants. +- Give custom colors semantic asset names and provide light, dark, and increased-contrast variants. Test them over every surface and material they actually use. +- Keep one meaning per color role. Do not reuse an interactive tint for unrelated decorative text. +- Use color as one cue, not the only cue. Preserve meaning for people who cannot distinguish the chosen hues. +- Measure contrast rather than judging it from a single screenshot. Recheck text, symbols, control outlines, separators that carry meaning, disabled states, and content over materials. + +See Apple's [Color](https://developer.apple.com/design/human-interface-guidelines/color), [Dark Mode](https://developer.apple.com/design/human-interface-guidelines/dark-mode), and [Accessibility](https://developer.apple.com/design/human-interface-guidelines/accessibility) guidance. + +## Depth, shape, and materials + +- Use system materials and presentation layers to explain hierarchy. Do not port CSS shadow values directly to SwiftUI or UIKit. +- When custom elevation is necessary, define a small semantic scale and tune it on the rendered surface. Combine separation cues sparingly; a surface rarely needs a strong border, shadow, material, and background change at once. +- Keep corner treatment consistent with the component family and platform. Match container shapes, hit regions, clipping, and content backgrounds. +- Check legibility over translucent or variable materials in every supported appearance. Apparent material color can change with content and system settings. +- When Reduce Transparency is enabled, replace blur or translucent separation + with a more opaque surface and preserve the boundary and hierarchy it conveyed. + +Apple's [Materials](https://developer.apple.com/design/human-interface-guidelines/materials) guidance explains why material selection and contrast must be evaluated in context. + +## Verification + +For implemented interface work, run the actual screen in Simulator or on device. +For advisory work, apply the proposed roles and values to representative component +examples. Check what the requested scope makes available: + +- Small and large supported windows or devices, rotation, safe areas, and keyboard presentation. +- Short, long, localized, and right-to-left content. +- Every supported Dynamic Type size, including accessibility sizes. +- Light, dark, and increased-contrast appearances. +- Reduced Transparency when the interface uses translucent materials. +- Default, selected, pressed, disabled, loading, empty, and error states that apply. +- Touch-target sizing and spacing between controls. + +Use Accessibility Inspector for contrast checks when it is available; otherwise +report that manual check as outstanding. Inspect screenshots +at full size; a scaled-down overview can hide weak contrast, bad baselines, and +cramped controls. diff --git a/skills/ui-design/references/art-direction.md b/skills/ui-design/references/art-direction.md new file mode 100644 index 0000000..869512a --- /dev/null +++ b/skills/ui-design/references/art-direction.md @@ -0,0 +1,79 @@ + + +# Art direction for a distinct identity + +Read this for a new interface or a substantial change in visual direction. It +is a calibration guide, not a house style. The brief, an established brand, and +the product's actual constraints take precedence. + +## Find the point of view + +Approach the work like a design studio responsible for giving this product an +identity that could not be swapped unchanged onto an unrelated product. +Identify the subject, audience, and primary job before choosing a look. Draw +from the subject's materials, language, tools, history, and visual vernacular, +and work with representative content rather than neutral filler. + +For an opening composition, lead with the element that is most characteristic +of the subject's world rather than reaching for a generic hero treatment. + +When the brief leaves the subject materially ambiguous, propose a concrete +interpretation and confirm it before committing to the direction. Continue with +reversible exploration while confirmation is outstanding. + +Write a compact direction before building: + +- Palette anchors and the roles they suggest +- Typeface choices and type roles +- A layout idea, including the dominant alignment and composition +- One or two principles that make the direction specific to this brief + +These are anchors, not required counts. Expand them into a usable semantic +system only as the interface demands. For implementation, continue with +[web visual design](web.md) or +[Apple-platform visual design](apple-platforms.md), whichever owns the surface. + +## Detect the generic answer + +Common generated-design tells are useful warnings because they expose decisions +made from habit rather than the brief: + +- A generic gradient, oversized statistic, or glowing accent doing all the + identity work +- Identical rounded cards wrapping every section +- Numbered markers for content that is not actually a sequence +- A small label or eyebrow above every heading +- One word in every headline set in a different color, italic, or weight +- All-caps labels used as a default rather than for a clear voice or function +- Repeated fade-and-slide entrances or hover movement on every card +- Decorative borders, pills, icons, or abstract shapes with no structural job +- A default typeface and default component kit left to carry the personality + +None of these treatments is forbidden. Keep one when the brief, content, or +interaction makes it the right choice. Revise it when it could move unchanged +to an unrelated product. + +Typography can carry identity, but it should remain a system. Choose one family +or a deliberately contrasting pair, assign clear roles, and tune weight, +spacing, line length, and leading for the face and content. Avoid typographic +decoration that competes with the words or creates labels the content does not +need. + +## Restraint and critique + +Spend boldness in one place. Let one composition, type treatment, image, +interaction, or material decision be memorable while the surrounding system +stays disciplined. + +Work in two passes before implementation. First form the direction. Then compare +every choice with the brief and ask: “Could this belong unchanged to an +unrelated product?” Replace the transferable defaults and keep the choices that +earn their place. For plan or review work, complete both passes before handoff. + +Use Coco Chanel's remove-one-accessory advice as a final editing mnemonic: +before finishing, remove one decorative element and check whether the hierarchy +became clearer. Restore it only if it carries meaning or identity the design +lost. + +When motion is part of the direction, use `animate` to decide whether it belongs +and to implement timing, interruption, input, and reduced-motion behavior. diff --git a/skills/refactoring-ui-skill/references/diagnose.md b/skills/ui-design/references/diagnose.md similarity index 82% rename from skills/refactoring-ui-skill/references/diagnose.md rename to skills/ui-design/references/diagnose.md index 63e419d..1a98a5b 100644 --- a/skills/refactoring-ui-skill/references/diagnose.md +++ b/skills/ui-design/references/diagnose.md @@ -1,10 +1,15 @@ # Diagnosing existing UI +Use this reference for web surfaces. For native Apple UI, use +[Apple-platform visual design](apple-platforms.md). + Use this when the task is *improve this*, not *build this*. Complaints about UI are almost always vague ("looks off", "feels cheap"). Each vague symptom maps to a small number of specific, mechanical fixes. -Work down the table in order — the top entries account for most of the damage. +Start near the top because those causes are common, then skip any hypothesis the +rendered interface does not support. The fixes are candidate moves; adapt them +to the platform, product system, content, and measured result. | Symptom | What's actually wrong | Fix | |---|---|---| @@ -17,11 +22,11 @@ Work down the table in order — the top entries account for most of the damage. | Headline over a photo is unreadable at some sizes | The image is too dynamic, not the text | Semi-transparent overlay; or lower image contrast (+brightness to compensate); or desaturate + multiply a brand color; or a large-blur, zero-offset text-shadow used as a glow | | Primary content too big *and* secondary content too small | Font size doing all the hierarchy work | Move the emphasis to weight (600/700) and color; pull sizes back toward the middle of the scale | | Big red button for something that isn't the main action | Styled by semantics instead of hierarchy | Give destructive actions secondary or tertiary treatment; save the red primary button for the confirmation dialog | -| Page title feels oversized and dominates | `h1` styled as an `h1` | Section titles are usually labels. 16px is fine. Consider hiding it visually | +| Page title feels oversized and dominates | Heading semantics were mistaken for required visual weight | Keep the correct heading level, then use a quieter, body-like visual size when the composition calls for it | | Data reads like a database dump (`Name:`, `Email:`, `Phone:`) | Naive label/value pairs | Drop labels the format or context already implies; merge label into value ("3 bedrooms"); otherwise make the label visibly secondary | | Icon next to text overpowers it | Solid icons cover more surface area | Lower the icon's contrast (softer color) | | 1px border either invisible or harsh | Trying to solve weight with color | Keep the soft color, go to 2px | -| Large icons look chunky and crude | Icons drawn at 16–24px, scaled up | Don't scale. Put the icon at its intended size inside a colored circle/square | +| Large icons look chunky and crude | Small-format icon geometry was scaled too far | Render near the icon's intended size and use a surrounding shape when it needs more presence | | Screenshot is an unreadable mush of tiny detail | Full-size screenshot scaled down | Screenshot a smaller (tablet) viewport, or crop to one region, or draw a simplified illustration of the UI | | Logo turns to mush as a favicon | Detailed artwork scaled down | Redraw a simplified version at the target size | | Layout spread thin across a huge viewport | Filling the screen because it's there | Use only the width the content needs. Or split into columns rather than stretching | @@ -33,8 +38,8 @@ Work down the table in order — the top entries account for most of the damage. | Long centered paragraphs are hard to read | Center alignment past 2–3 lines | Left-align. Or rewrite the copy shorter so centering works | | Numeric table columns hard to compare | Left-aligned numbers | Right-align them | | Justified text has rivers of whitespace | No hyphenation | `hyphens: auto`, or don't justify | -| Flat, plain, "nothing wrong but nothing right" | No visual accents anywhere | Colored accent border (top of a card, under a heading, side of an alert, active nav item); change a section's background color; a ≤30° two-hue gradient; a subtle low-contrast pattern or geometric shape — it doesn't need to cover the whole background, running it along just one edge works too | -| Feels unfinished / prototype-y | Browser defaults everywhere | Replace bullets with icons; custom checkboxes and radios in a brand color; promote testimonial quotes into visual elements; style links distinctively | +| Flat, plain, "nothing wrong but nothing right" | No visual accents anywhere | Add one role-specific accent: a border, section background, restrained two-hue gradient, low-contrast pattern, or geometric shape | +| Feels unfinished / prototype-y | Defaults and custom styling are mixed without a system | Keep native controls when they fit; apply a coherent type, spacing, color, and focus system; customize controls only when their complete interaction and access behavior can be preserved | | Screen is blank for new users | Empty state was an afterthought | Illustration + a clear headline + an emphasized call to action. Hide tabs/filters/search that do nothing until content exists | | A component looks generic | Default mental model of the component | Break the box — multi-column dropdowns with icons and descriptions, tables with combined columns and inline images, radio groups as selectable cards | | Elements look pasted onto the page | Everything is in its own rectangle | Overlap layers: negative margins so a card straddles two backgrounds, or extends past its parent's edges | diff --git a/skills/refactoring-ui-skill/references/systems.md b/skills/ui-design/references/systems.md similarity index 50% rename from skills/refactoring-ui-skill/references/systems.md rename to skills/ui-design/references/systems.md index cde6a1b..894fec6 100644 --- a/skills/refactoring-ui-skill/references/systems.md +++ b/skills/ui-design/references/systems.md @@ -1,7 +1,10 @@ -# Building the color system +# Optional HSL ramp workflow -The scales in SKILL.md tell you *what* to define. This tells you *how to pick the values*, -and how to keep them from looking washed out or failing contrast. +Use this workflow when a web product needs a new numbered ramp and HSL is a +useful tuning model. It is one way to choose related values, not a required +palette structure. Existing brand systems, perceptual color spaces, wide-gamut +workflows, and tools that produce stable accessible tokens can be equally valid. +Rendered contrast and recognizable semantic roles are the invariants. ## Why HSL @@ -13,47 +16,50 @@ your eye already uses: - **Saturation** — how vivid. 0% is grey (at which point hue is meaningless), 100% is intense. - **Lightness** — 0% black, 100% white, 50% the pure hue. -Two shades of the same color share a hue in HSL and look nothing alike in hex. Design tools -mostly show HSB, browsers only understand HSL — don't confuse them. In HSB, 100% brightness -is only white when saturation is 0; HSB at S100/B100 equals HSL at S100/L50. +Two shades of the same color share a hue in HSL and look unrelated in hex. Design tools +often show HSB, while browsers accept HSL directly — don't confuse the models. In HSB, +100% brightness is only white when saturation is 0; HSB at S100/B100 equals HSL at +S100/L50. -## Picking the base (500) +## Choose important usage colors first -There is no formula. For a primary or accent color, pick the shade that **works as a button -background** — dark enough that white text sits on it comfortably, light enough that the -button doesn't read as black. Rules like "start at 50% lightness" don't hold; every hue -behaves differently. Use your eyes. +There is no universal base formula. For a numbered primary or accent ramp, one +practical starting point is the shade used by a high-emphasis action. Choose its +foreground and background together, measure contrast, and check that the result +has the intended weight. A different product may anchor the ramp on data, +illustration, content, or another brand-critical usage. -For greys, the base matters less. Work from the edges instead: the darkest grey is whatever -you want your darkest text to be, and the lightest is a subtle off-white background. +For neutral ramps, it can be easier to begin with the darkest text and lightest +surface roles instead of inventing a middle swatch first. -## Finding the edges (900 and 100) +## Add edge roles when needed -Choose them by imagining where they'll be used. `900` is almost always a text color; `100` is -almost always a background tint. A simple alert component uses both at once — dark text on a -pale tinted panel — so design one and read both values off it. +In a `100`–`900` convention, `900` can serve strong text and `100` a tinted +surface. Design a representative component that uses both, measure the pairing, +and tune it in context. Other naming schemes or role-first tokens are fine. ## Filling the gaps -With `900`, `500` and `100` fixed, add `700` and `300` as the perfect compromise between the -shades on either side. That leaves four holes — `800`, `600`, `400`, `200` — filled the same -way. Nine shades is convenient because it divides cleanly. +If the product needs a full nine-step ramp, values such as `700` and `300` can +split the visual distance between the anchors before filling smaller gaps. This +is an efficient construction order, not a required shade count. Keep only the +steps that serve semantic roles. -Then adjust by eye. A systematic build gets you 90% there; expect to nudge a saturation or -push a shade lighter once you see it in use. What you must *not* do is keep adding new shades -outside the system — at that point you don't have a system. +Then adjust on rendered components. Expect to change saturation, lightness, or +hue once the colors appear at real sizes and proportions. When a new shade is needed, add it +to the system with a named role rather than letting one-off values accumulate +at call sites. ## Keeping saturation alive In HSL, saturation's effect weakens as lightness approaches 0% or 100%. The same S value that looks vivid at L50 looks washed out at L90. -**So: increase saturation as lightness moves away from 50%, in both directions.** Your -lightest and darkest shades should carry *more* saturation than your base, not the same -amount. This is subtle per-swatch and very visible when the color covers a large area. +When an HSL ramp looks washed out near its light or dark ends, try increasing +saturation as lightness moves away from 50%. Judge the adjustment across the +whole ramp; some identities or color spaces need a different correction. -Applies to greys too — if you're using tinted greys and don't raise saturation at the ends, -your palest and darkest greys will drift back toward neutral. +Tinted neutral ramps can show the same drift toward neutral at their extremes. ## Perceived brightness and hue rotation @@ -67,38 +73,41 @@ perceived brightness = sqrt(0.299·r² + 0.587·g² + 0.114·b²) / 255 Across the wheel this gives three local maxima — **60° (yellow), 180° (cyan), 300° (magenta)** — and three minima — **0° (red), 120° (green), 240° (blue)**. -That gives you a second way to change how light a color looks, without touching lightness and -without draining its intensity: +This suggests an optional way to change perceived brightness without relying +only on HSL lightness: - **To lighten:** rotate the hue toward the nearest of 60° / 180° / 300°. - **To darken:** rotate the hue toward the nearest of 0° / 120° / 240°. -**Cap the rotation at 20–30° total.** Beyond that it reads as a different color rather than a -lighter or darker one. +Keep hue rotation small enough that the ramp still reads as one color. Around +20–30° total is a useful starting limit, but judge the rendered ramp and the +identity it must preserve. -This is the fix for scales built on light hues. A yellow darkened by lightness alone goes +This can help scales built on light hues. A yellow darkened by lightness alone can go muddy olive-brown; a yellow darkened by rotating gradually toward orange gives you warm, rich dark shades. Combine both approaches freely — take some brightness from hue, some from lightness. ## Warm and cool greys -True grey is S0% — no color at all. Most greys in good UIs are saturated noticeably. +True grey is S0%—no color at all. A tinted neutral can connect surfaces and +text to the palette. These are example starting regions: - **Cool** (blue-ish): hue ~207–210, saturation ~12–21% - **Warm** (yellow/orange-ish): hue ~39–41, saturation ~12–21% -How far you push it is a personality decision. And remember the saturation rule above: raise S -at the light and dark ends or the extremes will look flat next to the mid-tones. +How far to push the tint is an identity and contrast decision. Inspect the +extremes beside their actual neighboring colors. ## Dark mode -Beyond the book — it predates dark mode — but the ramp rules extend to it cleanly. +This example extends the same role-first reasoning to dark appearance. -**Don't invert the ramp mechanically.** Swapping `100` for `900` produces harsh, glaring UI, -because the two modes aren't symmetric: +Test dark roles independently instead of assuming a mechanical inversion will +preserve hierarchy and contrast: -- **Never pure black as the surface.** Use `grey-900`-ish, and build *elevation by getting +- **Avoid pure black when it makes surfaces harsh.** A `grey-900`-like base often + leaves more room for separation. Build *elevation by getting lighter*, not darker. "Raised is lighter than the page" holds in both modes — what changes is that shadows barely register against a dark surface, so lightness has to carry the depth cue on its own. Surfaces stack upward in lightness; shadows do progressively less work. @@ -106,7 +115,7 @@ because the two modes aren't symmetric: dark surface usually also needs a hairline border to read as raised at all. Don't just reach for a lighter surface: pushing it further up the ramp squeezes the text sitting on it, and tertiary text is the first thing to fail. -- **Desaturate your accents.** A `500` tuned to carry white text on a light page will vibrate +- **Retune accents in context.** A `500` tuned to carry white text on a light page may vibrate against a dark one. Shift toward the `300`/`400` end and drop saturation. - **Re-check contrast; don't assume it mirrors.** Light-on-dark at the same nominal ratio reads heavier, so text often wants to be a shade *dimmer* than the equivalent light-mode @@ -121,17 +130,16 @@ WCAG wants 4.5:1 for normal text. The relaxed 3:1 threshold applies only to *lar defined as **18pt (24px) regular, or 14pt (≈18.66px) bold**. 18px regular text is normal text and needs the full 4.5:1; the book's "~18px" phrasing is looser than the spec. -Dark-on-light is easy. Color is where it gets hard, and there are two moves that solve almost -every case. +When a colored pairing misses its target, these two candidate moves often help. ### 1. Flip the contrast White text on a colored background needs the background to be *very* dark to reach 4.5:1 — and a page full of dark saturated badges grabs attention that those elements don't deserve. -Instead, invert: **dark colored text on a light colored tint.** A green `800` on a green `100` -easily clears AAA, keeps the semantic color, and sits quietly in the hierarchy. This is the -default treatment for status pills, tags and badges. +One option is **dark colored text on a light colored tint.** A compatible dark +and light pair can keep the semantic color while sitting quietly in the +hierarchy. This often works well for status pills, tags, and badges. ### 2. Rotate the hue toward a brighter one @@ -139,6 +147,6 @@ For colored text on a colored background — secondary text inside a dark colore lightness alone drives you to near-white before you hit the ratio, and then the primary and secondary text look identical. -Use perceived brightness instead: **rotate the text's hue toward cyan, magenta or yellow.** You +Try perceived brightness instead: **rotate the text's hue toward cyan, magenta or yellow.** You gain contrast while keeping the text visibly colored and visibly secondary. A blue-violet panel with cyan-shifted body text can clear AAA and still look like part of the panel. diff --git a/skills/refactoring-ui-skill/references/techniques.md b/skills/ui-design/references/techniques.md similarity index 75% rename from skills/refactoring-ui-skill/references/techniques.md rename to skills/ui-design/references/techniques.md index f46a8e6..b25f2c4 100644 --- a/skills/refactoring-ui-skill/references/techniques.md +++ b/skills/ui-design/references/techniques.md @@ -1,14 +1,19 @@ # Techniques +Use these as opt-in techniques when they solve a diagnosed visual problem. +Examples are starting values; preserve a coherent product system and judge the +result on its rendered surface. + ## Emulating a light source Raised and inset are the same trick: decide the element's **profile**, then mimic how light would hit that shape. Light comes from above, and people look slightly *down* at their screens — so you see the top edge of a raised element and the bottom edge of an inset one. -Each element needs **both** effects — the lit edge and the blocked light. They go in a -single comma-separated `box-shadow`. Two `box-shadow` declarations on one selector do not -combine; the second silently discards the first. +When this dimensional effect fits the direction, pair a lit edge with blocked +light so the profile reads coherently. Put both in one comma-separated +`box-shadow`; two declarations on one selector do not combine, and the second +replaces the first. **Raised** (button, card) — lit top edge, shadow cast below: @@ -42,12 +47,12 @@ face. Note both lit edges are `inset` — a non-inset shadow with a negative Y offset draws *above* the element, not on its bottom lip. -Two rules: **hand-pick the lighter color** rather than overlaying semi-transparent white — +For this technique, **hand-pick the lighter color** rather than overlaying semi-transparent white — white overlays drain the saturation out of the underlying color, which is why both examples above use a solid `hsl()` sampled from the element's own hue. (On a neutral grey or near- black surface there is no saturation to lose, so `hsla(0,0%,100%,.15)` is fine there.) And -**keep blur radii tiny** — these edges are sharp in the real world, like the shadow under a -wall outlet. +**keep blur radii restrained** — these edges are sharp in the real world, like +the shadow under a wall outlet. Don't chase photorealism. Borrow the cue and stop. @@ -66,14 +71,17 @@ box-shadow: 0 3px 6px hsla(0, 0%, 0%, .10); /* contact — tighter, sharper */ ``` -The two parts must differ *substantially* in offset and blur or the effect is invisible — -that's a ~3x difference in both here. +The two parts need enough difference in offset and blur to remain perceptible. +The roughly threefold difference in the example is a starting point, not a +required ratio. **Which one is darker depends on elevation, and this is the whole point.** At rest on the -surface the contact shadow is the darker of the two (`.24` against the cast shadow's `.12`); +surface the contact shadow is the darker of the two (`.24` against the cast +shadow's `.12` in this example); as the object lifts, it fades out and ends up lighter, until at the top of the scale it's -gone entirely. Don't fix the alphas — let them cross over. Keep both inside `.05–.25`; -anything heavier reads as a smudge rather than a shadow. +gone entirely. Let the alphas cross over rather than fixing one relationship +throughout the scale. Values around `.05–.25` are a useful starting range; +judge heavier values against the actual surface and direction. The tradeoff: at the lowest elevations the two shadows converge in geometry (`0 1px 3px` + `0 1px 2px`) and the technique buys you little beyond a slightly crisper edge. @@ -129,43 +137,47 @@ Default to trusting the type designer. Two exceptions: what makes them scannable. Caps are uniform blocks, so default tracking crowds them. Add about `+0.05em`. -## Choosing typefaces without taste +## Choosing a UI typeface -- Neutral sans-serif is the safe default. The system font stack is a legitimate choice: +- A neutral sans-serif or system stack is a legitimate choice when another + element carries the identity: `-apple-system, Segoe UI, Roboto, Noto Sans, Ubuntu, Cantarell, Helvetica Neue`. -- **Ignore families with fewer than five weights.** Filtering Google Fonts to 10+ styles cuts - ~85% of the options and what remains skews toward carefully-made families. +- Confirm that the family has the writing systems, symbols, styles, and weights + required by the product. More styles are useful only when they serve real roles. - Optimize for legibility: taller x-height, wider default tracking. Avoid condensed faces with short x-heights for UI text. -- Sort by popularity — a widely used font is usually a good font. And inspect sites you admire. +- Inspect the face at the actual sizes, weights, and content before committing. -## Personality is four decisions +## Personality levers Not a vibe — four concrete levers: -1. **Typeface.** Serif → elegant/classic. Rounded sans → playful. Neutral sans → plain, lets - other elements carry the personality. -2. **Color.** Blue is safe and nobody objects. Gold reads expensive. Pink reads fun. -3. **Border radius.** Small = neutral, large = playful, none = formal. Be consistent. -4. **Language.** "Thank you Mr. Benson" vs "Sweet, thanks Steve!" changes the product's - character more than any color choice. +1. **Typeface.** Its construction, contrast, width, and historical associations + influence the voice. +2. **Color.** Hue, saturation, contrast, and proportion establish mood and emphasis. +3. **Shape.** Corner treatment and geometry can make a system feel precise, + utilitarian, soft, or expressive. +4. **Language.** Vocabulary and rhythm affect character as strongly as visual choices. -If you can't decide, look at the other sites your users spend time in. Don't imitate direct -competitors — you'll look like a lesser version of them. +If the direction is unclear, study the visual world around the subject and the +interfaces the audience already understands. Use competitors to learn conventions, +then make the product's own position explicit. -## Grids are overrated +## Use grids where they help -A grid is just fluid percentage widths chosen from a constrained set. That's the wrong tool -whenever an element has an optimal *fixed* size: +A fluid grid is the wrong tool when an element has a content-driven optimal +size. Common cases include: -- **Sidebars** should be a fixed width sized to their contents; the main area flexes and runs - its own internal grid. -- **Cards and forms** get a `max-width` and only shrink when the viewport is actually smaller. +- **Sidebars** often use a stable content-driven width while the main area + flexes and runs its own internal grid. +- **Cards and forms** often benefit from a `max-width`, shrinking when available + space requires it. Sizing a login card as "6 columns, then 8 columns at medium" produces the absurd result of the card being *wider* on medium screens than on large ones. - Inside components, don't use a percentage unless you genuinely want the thing to scale. -Don't compromise a component's size until the screen actually forces you to. +Preserve a component's useful size until content or available space gives a +reason to change it. **Think in columns, not width.** When a component wants to stay narrow (a form field) but sits in a wide layout, don't stretch it to fill the space — split the supporting content @@ -212,5 +224,6 @@ downscale the logo. inset shadow — `box-shadow: inset 0 0 0 1px hsla(0,0%,0%,.1)` — rather than a border. Borders clash with the image's own colors; nobody notices the shadow. -**Photos themselves.** Bad photography ruins an otherwise good design. Hire a photographer or -use good stock. Never design against placeholders planning to shoot something on a phone later. +**Photos themselves.** Image quality and composition can dominate the result. +Use representative imagery early enough to validate crops, contrast, and layout; +placeholders hide those constraints. diff --git a/skills/ui-design/references/web-behavior-and-accessibility.md b/skills/ui-design/references/web-behavior-and-accessibility.md new file mode 100644 index 0000000..1a06d48 --- /dev/null +++ b/skills/ui-design/references/web-behavior-and-accessibility.md @@ -0,0 +1,39 @@ +# Web behavior and accessibility + +Use this branch for browser component behavior, semantics, input, state, and +accessibility. Preserve the product's visual direction unless visual design is +also in scope. + +1. Inspect the rendered component, semantic tree, interaction contract, + affected states, supported input methods, and nearby product patterns. +2. Prefer native HTML elements and browser behavior. When a custom component is + justified, preserve the equivalent name, role, value, state, relationship, + focus, and keyboard contract. +3. Associate labels, help, validation, and errors with the controls they + describe. Keep focus visible and ordered by the task. Restore or move it + deliberately after navigation or dismissal, and prevent keyboard traps. +4. Expose visible async status, validation, and errors to assistive technology + when focus remains elsewhere. +5. Model loading, empty, disabled, error, overflow, cancellation, and + interruption inside the component contract rather than relying on a + happy-path page shell. +6. Start press feedback on pointer or key down, but commit only after a valid + activation. Clear the pressed state when input cancels, leaves the allowed + target, or becomes a drag. +7. Handle rapid and repeated input without stale work overwriting current + state. Keep the control usable while work is pending when the action safely + permits it. +8. Honor increased contrast, forced colors, reduced transparency, and larger + text where the browser or operating system exposes them. +9. Exercise affected mouse, touch, keyboard, focus, and assistive-technology + paths on the real component. Include rapid repeat, interruption, and + non-happy states. When an announcement or screen-reader check cannot run, + name that evidence gap. + +Use `animate` for the moving feedback's timing and interruption while keeping +the action and state contract here. Use `manual-verify` when hands-on evidence +would add confidence. + +This branch is complete when every affected semantic, keyboard, focus, status, +input, and edge-state path passes on the real page, or its remaining evidence +gap is explicit. diff --git a/skills/ui-design/references/web.md b/skills/ui-design/references/web.md new file mode 100644 index 0000000..96142b0 --- /dev/null +++ b/skills/ui-design/references/web.md @@ -0,0 +1,168 @@ +# Web visual systems + +Use the product's coherent tokens first. When the system is missing or cannot +express the required roles, establish a small set of scales and tune them +together. The values below are starting points, not universal requirements. + +## Foundations + +### Spacing and sizing + +A useful starter scale is: + +```text +4 8 12 16 24 32 48 64 96 128 192 256 +``` + +Keep adjacent choices distinct enough to make decisions clear. A denser product +may need intermediate values; a marketing surface may need larger ones. Use +tokens for repeated spacing, sizing, border widths, and opacity rather than +inventing values component by component. + +Keep more space around a group than within it. This relationship matters more +than any particular scale. + +### Typography + +A practical UI type scale might begin with: + +```text +12 14 16 18 20 24 30 36 48 60 72 +``` + +Use `rem` when values should follow the root text scale, `em` when a measure or +component should follow its own text size, and pixels where a fixed rendering +value is intentional. Test computed results, nesting, zoom, and user text +settings instead of enforcing a single unit everywhere. + +Choose typefaces that cover the product's writing systems, symbols, styles, and +needed weights. Use enough weights to make roles clear without creating nearly +indistinguishable steps. Light weights often lose legibility at small sizes; +de-emphasize with role, color, size, or placement when that communicates the +hierarchy better. + +When a variable face supports an optical-size axis, consider +`font-optical-sizing: auto` and verify it at the actual rendered sizes. Keep the +project's explicit optical-size settings when they are intentional. + +Tune tracking, line height, and measure for the face, script, size, and content. +Body text commonly reads well around 45–75 characters per line, but dense data, +editorial prose, and localized content can need different measures. + +### Color + +Start with semantic needs: surfaces, text levels, interactive actions, +separators, focus, selection, and status. Build only enough ramp steps to serve +those roles and their appearance variants. A simple product may need a few; a +data-rich product may need many. + +When deriving a ramp, choose the important usage values first—for example, an +action background, its readable foreground, a quiet tint, and strong text—then +fill gaps that have a real role. HSL or OKLCH can make relationships easier to +reason about, but preserve the project's token format and validate rendered +contrast. + +Generated or computed shades are acceptable when they produce stable, +reviewable, accessible tokens. Avoid uncontrolled runtime transformations that +create slightly different colors across components or states. + +On a colored surface, a neutral gray foreground can read muddy and detached. +Start from the surface hue, then tune saturation and lightness until the role is +clear and the rendered pairing meets its contrast target. + +Use [systems](systems.md) when building or repairing a palette from scratch. + +### Shape, borders, and depth + +Define shape and elevation by component family and structural role. Related +controls should feel related, but a sheet, compact control, and branded hero do +not need one universal radius. + +Use solid surfaces for primary content, raised or translucent surfaces for +elements above it, and scrims for blocking tasks. A surface rarely needs a +strong border, shadow, blur, and background change at once. Each cue should +explain a boundary, layer, or interaction. + +A small elevation scale is often enough. Starter shadows might range from a +tight `0 1px 3px` contact shadow to a softer `0 15px 35px` overlay shadow, but +tune color, opacity, and geometry against the actual surfaces. Use +[techniques](techniques.md) when emulated light or prominent shadows are part of +the direction. + +When elevation communicates interaction, move a pressed control toward its +surface and lift a legitimately dragged item above its siblings. Treat that as +supporting feedback, not the only state cue, and use `animate` for timing and +interruption. + +## Working method + +1. Start with a real feature and representative content. Let the shell emerge + from what the product must do. +2. Resolve layout and hierarchy before decorative detail. A grayscale pass can + expose dependence on color, but it is a diagnostic technique rather than a + required phase. +3. Explore in disposable sketches or prototypes, then move to the real surface + once the direction is decided. +4. Build the smallest useful version. Add capability and visual detail when the + product can support them. +5. Compare a candidate token with its neighboring values. If the distinction is + not visible or meaningful, reuse a neighbor. +6. Begin with enough whitespace to see the groups, then tighten deliberately for + the product's density. +7. Start at the narrowest relevant surface and test wider compositions. That + may be a compact component, a mobile viewport, a desktop tool, or an embedded + panel; it is not always a 400-pixel canvas. + +## Hierarchy and composition + +Build primary, secondary, and tertiary roles with position, spacing, weight, +color, and size together. When the primary element still does not stand out, +soften its competitors before amplifying it again. + +Use as many text-color roles as the content hierarchy and contrast requirements +need, and no more. Name the roles by meaning. Every text/surface pairing must +meet the applicable contrast criterion; a tertiary role is not permission to +make normal text unreadable. + +Style actions by task importance: + +- Primary actions receive the strongest treatment. +- Secondary actions remain clearly available without competing. +- Tertiary actions can use quiet or link-like treatment. + +Destructive is a semantic role, not automatically the strongest visual action. +It can become primary inside a confirmation step where deletion is the actual +decision. + +Treat semantic markup and visual weight as separate, coordinated choices. Keep +the correct heading and landmark structure even when a section title is visually +quiet. + +Put controls near what they affect. Let familiar placement and behavior carry +the interaction unless the product has evidence for a different pattern. + +## Invariants to verify + +- Color is not the only signal for state or meaning. In charts, make series + separable by lightness or contrast and a secondary cue such as shape, pattern, + label, or position rather than relying on hue alone. +- Text and essential graphics meet the applicable measured contrast criterion + on every real surface and material. +- Functional control boundaries remain perceptible; decorative separators need + not be promoted to controls. +- Responsive changes follow content pressure. Large and small elements do not + have to scale proportionally. +- Fixed-purpose regions such as a readable form or sidebar use the width their + content needs and shrink only when the available space requires it. +- Icons render near a size for which their geometry was designed. A surrounding + shape can give a small icon more presence without distorting it. +- Appearance modes, forced colors, zoom, larger text, localization, and relevant + viewport sizes preserve the hierarchy and content. + +## Starter asset + +[`../assets/tokens.css`](../assets/tokens.css) is a contrast-checked example for +projects with no usable tokens. Treat its spacing, type, palette, radius, and +elevation values as a coherent starting system, then retune or prune them for +the product. Reference semantic roles in components rather than coupling them +to raw ramp values. diff --git a/skills/uikit/SKILL.md b/skills/uikit/SKILL.md index 8784223..4a69ac0 100644 --- a/skills/uikit/SKILL.md +++ b/skills/uikit/SKILL.md @@ -1,6 +1,6 @@ --- name: uikit -description: UIKit interface work. Use when building, maintaining, or modernizing UIKit controllers, scenes, traits, adaptive layout, collections, or Liquid Glass; or deciding whether an existing UIKit surface should adopt SwiftUI. +description: UIKit interface work. Use when building, reviewing, maintaining, or modernizing UIKit controllers, scenes, traits, adaptive layout, collections, component feedback, async or edge-state behavior, accessibility semantics, or Liquid Glass; or deciding whether an existing UIKit surface should adopt SwiftUI. --- # UIKit @@ -9,6 +9,10 @@ Build each interface around its actual view-controller, view, window, and scene context. Preserve the product's architecture and deployment targets while making ownership and lifecycle explicit. +For an authorized build or fix, implement and test the workflow below. For a +plan or review, leave the product unchanged and turn its implementation and test +steps into exact proposed changes, findings, and checks. + ## Workflow 1. Inspect the affected controller hierarchy, scene configuration, layout system, @@ -34,10 +38,24 @@ ownership and lifecycle explicit. 4. Use standard controls and containers where they express the behavior. If a SwiftUI island is appropriate, place `UIHostingController` at an explicit containment boundary and keep one owner for state and lifecycle. -5. For modernization, replace a deprecated or global assumption end to end. Trace +5. For interactive components, give immediate feedback and keep loading, empty, + disabled, error, and overflow states close to the action or content they + describe. Cancel or identify interrupted and repeated async work so an older + callback cannot overwrite the current state. Prefer platform controls and + strong defaults over extra options; preserve valid activation and cancellation. +6. Preserve useful accessibility semantics. Expose the control's name, value, + state, and actions, and keep focus and announcements aligned with the task and + reading order rather than an incidental view hierarchy. Announce visible async + status, validation, and errors when focus does not move and the change would + otherwise be missed. +7. For modernization, replace a deprecated or global assumption end to end. Trace every caller, pass local context where needed, and preserve supported behavior for each active scene rather than swapping symbols mechanically. -6. Build the affected targets and exercise resizing, traits, navigation, and data - updates relevant to the change. Use `manual-verify` for visual or interactive - acceptance checks, `animate` for motion, and `diagnosing-bugs` for runtime - failures or performance regressions. +8. Build the affected targets and exercise resizing, traits, navigation, data + updates, edge states, interruption, and repeated input relevant to the change. + When behavior or accessibility is in scope, exercise the supported touch, + pointer, keyboard, focus, announcement, and VoiceOver reading paths. + Use `manual-verify` for visual or interactive + acceptance checks, `animate` for motion, `ui-design` for visual hierarchy + and token-system work, and `diagnosing-bugs` for runtime failures or performance + regressions.