@jjlmoya/utils-performing-arts 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/.github/workflows/npm-publish.yml +40 -0
  2. package/.gitignore +6 -0
  3. package/.stylelintrc.json +98 -0
  4. package/astro.config.mjs +19 -0
  5. package/eslint.config.js +201 -0
  6. package/package.json +79 -0
  7. package/prompts/create_tool.md +98 -0
  8. package/prompts/i18n/de.md +16 -0
  9. package/prompts/i18n/en.md +16 -0
  10. package/prompts/i18n/es.md +16 -0
  11. package/prompts/i18n/fr.md +16 -0
  12. package/prompts/i18n/id.md +16 -0
  13. package/prompts/i18n/it.md +16 -0
  14. package/prompts/i18n/ja.md +16 -0
  15. package/prompts/i18n/ko.md +16 -0
  16. package/prompts/i18n/nl.md +16 -0
  17. package/prompts/i18n/pl.md +16 -0
  18. package/prompts/i18n/pt.md +16 -0
  19. package/prompts/i18n/ru.md +16 -0
  20. package/prompts/i18n/sv.md +16 -0
  21. package/prompts/i18n/tr.md +16 -0
  22. package/prompts/i18n/zh.md +16 -0
  23. package/prompts/seo.md +58 -0
  24. package/prompts/translations/french.md +33 -0
  25. package/scripts/postinstall.mjs +27 -0
  26. package/src/category/PerformingArtsCategorySEO.astro +9 -0
  27. package/src/category/i18n/de.ts +27 -0
  28. package/src/category/i18n/en.ts +27 -0
  29. package/src/category/i18n/es.ts +27 -0
  30. package/src/category/i18n/fr.ts +27 -0
  31. package/src/category/i18n/id.ts +27 -0
  32. package/src/category/i18n/it.ts +27 -0
  33. package/src/category/i18n/ja.ts +27 -0
  34. package/src/category/i18n/ko.ts +27 -0
  35. package/src/category/i18n/nl.ts +27 -0
  36. package/src/category/i18n/pl.ts +27 -0
  37. package/src/category/i18n/pt.ts +27 -0
  38. package/src/category/i18n/ru.ts +27 -0
  39. package/src/category/i18n/sv.ts +27 -0
  40. package/src/category/i18n/tr.ts +27 -0
  41. package/src/category/i18n/zh.ts +27 -0
  42. package/src/category/index.ts +10 -0
  43. package/src/components/PreviewNavSidebar.astro +116 -0
  44. package/src/components/PreviewToolbar.astro +143 -0
  45. package/src/data.ts +10 -0
  46. package/src/entries.ts +3 -0
  47. package/src/env.d.ts +5 -0
  48. package/src/index.ts +20 -0
  49. package/src/layouts/PreviewLayout.astro +118 -0
  50. package/src/pages/[locale]/[slug].astro +165 -0
  51. package/src/pages/[locale].astro +251 -0
  52. package/src/pages/index.astro +4 -0
  53. package/src/tests/bibliography_wellformed_export.test.ts +46 -0
  54. package/src/tests/category_seo_quality.test.ts +74 -0
  55. package/src/tests/diacritics_density.test.ts +118 -0
  56. package/src/tests/faq_count.test.ts +18 -0
  57. package/src/tests/i18n_coverage.test.ts +34 -0
  58. package/src/tests/inverted_punctuation.test.ts +84 -0
  59. package/src/tests/locale_completeness.test.ts +23 -0
  60. package/src/tests/mocks/astro_mock.js +2 -0
  61. package/src/tests/no_em_dash.test.ts +47 -0
  62. package/src/tests/no_en_dash.test.ts +70 -0
  63. package/src/tests/no_h1_in_components.test.ts +48 -0
  64. package/src/tests/pagespeed_best_practices.test.ts +198 -0
  65. package/src/tests/qa-test-helpers.ts +32 -0
  66. package/src/tests/qa_bibliography_links.test.ts +43 -0
  67. package/src/tests/qa_claim_evidence.test.ts +69 -0
  68. package/src/tests/qa_logic_reference_coverage.test.ts +46 -0
  69. package/src/tests/qa_runtime_i18n.test.ts +100 -0
  70. package/src/tests/schemas_fulfillment.test.ts +23 -0
  71. package/src/tests/script_density.test.ts +94 -0
  72. package/src/tests/seo_length.test.ts +22 -0
  73. package/src/tests/seo_parity.test.ts +60 -0
  74. package/src/tests/seo_translation_completeness.test.ts +69 -0
  75. package/src/tests/seo_wellformed_export.test.ts +65 -0
  76. package/src/tests/shared-test-helpers.ts +56 -0
  77. package/src/tests/slug_language_code_format.test.ts +23 -0
  78. package/src/tests/slug_uniqueness.test.ts +81 -0
  79. package/src/tests/spanish_leakage.test.ts +175 -0
  80. package/src/tests/title_quality.test.ts +55 -0
  81. package/src/tests/tool_exports.test.ts +34 -0
  82. package/src/tests/tool_validation.test.ts +16 -0
  83. package/src/tests/translation_copy.test.ts +115 -0
  84. package/src/tool/rehearsal-call-sheet-planner/bibliography.astro +6 -0
  85. package/src/tool/rehearsal-call-sheet-planner/bibliography.ts +12 -0
  86. package/src/tool/rehearsal-call-sheet-planner/component.astro +74 -0
  87. package/src/tool/rehearsal-call-sheet-planner/controller.ts +98 -0
  88. package/src/tool/rehearsal-call-sheet-planner/dom-views.ts +86 -0
  89. package/src/tool/rehearsal-call-sheet-planner/entry.ts +27 -0
  90. package/src/tool/rehearsal-call-sheet-planner/evaluator.ts +27 -0
  91. package/src/tool/rehearsal-call-sheet-planner/i18n/de.ts +60 -0
  92. package/src/tool/rehearsal-call-sheet-planner/i18n/en.ts +158 -0
  93. package/src/tool/rehearsal-call-sheet-planner/i18n/es.ts +60 -0
  94. package/src/tool/rehearsal-call-sheet-planner/i18n/fr.ts +60 -0
  95. package/src/tool/rehearsal-call-sheet-planner/i18n/id.ts +47 -0
  96. package/src/tool/rehearsal-call-sheet-planner/i18n/it.ts +47 -0
  97. package/src/tool/rehearsal-call-sheet-planner/i18n/ja.ts +47 -0
  98. package/src/tool/rehearsal-call-sheet-planner/i18n/ko.ts +47 -0
  99. package/src/tool/rehearsal-call-sheet-planner/i18n/nl.ts +47 -0
  100. package/src/tool/rehearsal-call-sheet-planner/i18n/pl.ts +47 -0
  101. package/src/tool/rehearsal-call-sheet-planner/i18n/pt.ts +47 -0
  102. package/src/tool/rehearsal-call-sheet-planner/i18n/ru.ts +48 -0
  103. package/src/tool/rehearsal-call-sheet-planner/i18n/sv.ts +48 -0
  104. package/src/tool/rehearsal-call-sheet-planner/i18n/tr.ts +48 -0
  105. package/src/tool/rehearsal-call-sheet-planner/i18n/zh.ts +48 -0
  106. package/src/tool/rehearsal-call-sheet-planner/index.ts +11 -0
  107. package/src/tool/rehearsal-call-sheet-planner/logic.test.ts +68 -0
  108. package/src/tool/rehearsal-call-sheet-planner/logic.ts +229 -0
  109. package/src/tool/rehearsal-call-sheet-planner/rehearsal-call-sheet-planner.css +593 -0
  110. package/src/tool/rehearsal-call-sheet-planner/seo.astro +16 -0
  111. package/src/tool/rehearsal-call-sheet-planner/storage.ts +33 -0
  112. package/src/tool/rehearsal-call-sheet-planner/types.ts +84 -0
  113. package/src/tool/rehearsal-call-sheet-planner/ui.ts +70 -0
  114. package/src/tools.ts +8 -0
  115. package/src/types.ts +68 -0
  116. package/tsconfig.json +15 -0
  117. package/vitest.config.ts +20 -0
@@ -0,0 +1,40 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ publish:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: write
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ with:
16
+ token: ${{ secrets.GITHUB_TOKEN }}
17
+
18
+ - uses: actions/setup-node@v4
19
+ with:
20
+ node-version: '22'
21
+ registry-url: 'https://registry.npmjs.org'
22
+
23
+ - name: Sync package.json version from tag
24
+ run: |
25
+ VERSION=${GITHUB_REF_NAME#v}
26
+ CURRENT_VERSION=$(node -p "require('./package.json').version")
27
+ if [ "$VERSION" != "$CURRENT_VERSION" ]; then
28
+ npm version $VERSION --no-git-tag-version
29
+ git config user.name "github-actions[bot]"
30
+ git config user.email "github-actions[bot]@users.noreply.github.com"
31
+ git add package.json
32
+ git commit -m "chore: bump version to $VERSION [skip ci]"
33
+ git push origin HEAD:master
34
+ fi
35
+
36
+ - run: npm ci
37
+ - run: npm run build
38
+ - run: npm publish --access public
39
+ env:
40
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ dist/
2
+ node_modules/
3
+ .env
4
+ .astro/
5
+ .gemini/
6
+ .claude/
@@ -0,0 +1,98 @@
1
+ {
2
+ "extends": [
3
+ "stylelint-config-standard"
4
+ ],
5
+ "overrides": [
6
+ {
7
+ "files": [
8
+ "**/*.astro"
9
+ ],
10
+ "customSyntax": "postcss-html"
11
+ },
12
+ {
13
+ "files": [
14
+ "src/tool/**/*.css",
15
+ "src/tool/**/*.astro",
16
+ "src/pages/**/*.astro"
17
+ ],
18
+ "rules": {
19
+ "color-named": null,
20
+ "property-no-vendor-prefix": null,
21
+ "selector-pseudo-element-colon-notation": null,
22
+ "declaration-block-no-redundant-longhand-properties": null,
23
+ "rule-empty-line-before": null,
24
+ "import-notation": null,
25
+ "block-no-empty": null
26
+ }
27
+ },
28
+ {
29
+ "files": [
30
+ "src/layouts/**/*.astro"
31
+ ],
32
+ "rules": {
33
+ "property-disallowed-list": null
34
+ }
35
+ }
36
+ ],
37
+ "plugins": [
38
+ "stylelint-declaration-strict-value"
39
+ ],
40
+ "rules": {
41
+ "scale-unlimited/declaration-strict-value": [
42
+ [
43
+ "color",
44
+ "fill",
45
+ "stroke"
46
+ ],
47
+ {
48
+ "ignoreValues": [
49
+ "transparent",
50
+ "none",
51
+ "inherit",
52
+ "currentColor",
53
+ "initial"
54
+ ]
55
+ }
56
+ ],
57
+ "color-no-invalid-hex": true,
58
+ "shorthand-property-no-redundant-values": true,
59
+ "declaration-block-no-duplicate-properties": true,
60
+ "no-duplicate-selectors": true,
61
+ "color-named": "never",
62
+ "unit-allowed-list": [
63
+ "px",
64
+ "rem",
65
+ "em",
66
+ "%",
67
+ "vw",
68
+ "vh",
69
+ "svh",
70
+ "svw",
71
+ "fr",
72
+ "deg",
73
+ "s",
74
+ "ms",
75
+ "ch"
76
+ ],
77
+ "declaration-no-important": true,
78
+ "alpha-value-notation": "number",
79
+ "comment-empty-line-before": null,
80
+ "no-descending-specificity": null,
81
+ "selector-pseudo-class-no-unknown": [
82
+ true,
83
+ {
84
+ "ignorePseudoClasses": [
85
+ "global",
86
+ "local"
87
+ ]
88
+ }
89
+ ],
90
+ "media-feature-range-notation": null,
91
+ "color-function-notation": "legacy",
92
+ "color-function-alias-notation": null,
93
+ "custom-property-pattern": null,
94
+ "property-disallowed-list": [
95
+ "font-family"
96
+ ]
97
+ }
98
+ }
@@ -0,0 +1,19 @@
1
+ import { defineConfig } from "astro/config";
2
+ import icon from "astro-icon";
3
+
4
+ export default defineConfig({
5
+ integrations: [icon()],
6
+ server: {
7
+ port: 3037,
8
+ host: true
9
+ },
10
+ vite: {
11
+ server: {
12
+ watch: {
13
+ usePolling: true,
14
+ interval: 1000,
15
+ }
16
+ }
17
+ }
18
+ });
19
+
@@ -0,0 +1,201 @@
1
+ import eslintPluginAstro from "eslint-plugin-astro";
2
+ import tseslint from "typescript-eslint";
3
+ import noComments from "eslint-plugin-no-comments";
4
+
5
+ const customCommentsPlugin = {
6
+ rules: {
7
+ "no-html-comments": {
8
+ meta: { type: "layout", fixable: "whitespace" },
9
+ create(context) {
10
+ return {
11
+ Program() {
12
+ const sourceCode = context.sourceCode;
13
+ const text = sourceCode.getText();
14
+ const regex = new RegExp("<!--[\\s\\S]*?-->", "g");
15
+ let match;
16
+ while ((match = regex.exec(text)) !== null) {
17
+ context.report({
18
+ loc: sourceCode.getLocFromIndex(match.index),
19
+ message: "HTML comments are forbidden.",
20
+ fix(fixer) {
21
+ return fixer.removeRange([match.index, match.index + match[0].length]);
22
+ },
23
+ });
24
+ }
25
+ },
26
+ };
27
+ },
28
+ },
29
+ "no-css-comments": {
30
+ meta: { type: "layout", fixable: "whitespace" },
31
+ create(context) {
32
+ return {
33
+ Program() {
34
+ const sourceCode = context.sourceCode;
35
+ const text = sourceCode.getText();
36
+ const regex = new RegExp("/\\*[\\s\\S]*?\\*/", "g");
37
+ let match;
38
+ while ((match = regex.exec(text)) !== null) {
39
+ context.report({
40
+ loc: sourceCode.getLocFromIndex(match.index),
41
+ message: "CSS/Block comments are forbidden.",
42
+ fix(fixer) {
43
+ return fixer.removeRange([match.index, match.index + match[0].length]);
44
+ },
45
+ });
46
+ }
47
+ },
48
+ };
49
+ },
50
+ },
51
+ "no-emojis": {
52
+ meta: { type: "layout", fixable: false },
53
+ create(context) {
54
+ return {
55
+ Program() {
56
+ const sourceCode = context.sourceCode;
57
+ const text = sourceCode.getText();
58
+ const emojiRegex = /[\u{1F300}-\u{1F9FF}]|[\u{2600}-\u{27BF}]|[\u{1F680}-\u{1F6FF}]/gu;
59
+ let match;
60
+ while ((match = emojiRegex.exec(text)) !== null) {
61
+ context.report({
62
+ loc: sourceCode.getLocFromIndex(match.index),
63
+ message: "Emojis are not allowed in code.",
64
+ });
65
+ }
66
+ },
67
+ };
68
+ },
69
+ },
70
+ "single-font-load": {
71
+ meta: { type: "suggestion", fixable: false },
72
+ create(context) {
73
+ return {
74
+ Program() {
75
+ const sourceCode = context.sourceCode;
76
+ const filename = context.filename;
77
+ const isPreviewLayout = filename.includes("PreviewLayout.astro");
78
+ const text = sourceCode.getText();
79
+ const fontPatterns = [
80
+ /fonts\.googleapis\.com/g,
81
+ /@font-face\s*\{/g,
82
+ /family:\s*['"](Inter|inter)['"]/g,
83
+ ];
84
+ if (!isPreviewLayout) {
85
+ fontPatterns.forEach((pattern) => {
86
+ let match;
87
+ while ((match = pattern.exec(text)) !== null) {
88
+ context.report({
89
+ loc: sourceCode.getLocFromIndex(match.index),
90
+ message: "Fonts must be loaded only in PreviewLayout.astro. Do not declare fonts in other files.",
91
+ });
92
+ }
93
+ });
94
+ }
95
+ },
96
+ };
97
+ },
98
+ },
99
+ },
100
+ };
101
+
102
+ export default [
103
+ {
104
+ ignores: ["**/dist/", "**/node_modules/", ".astro/", "**/.astro/**", "**/public/**"],
105
+ },
106
+ ...tseslint.configs.recommended,
107
+ ...eslintPluginAstro.configs["flat/recommended"],
108
+
109
+ {
110
+ files: ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.mjs", "**/*.astro"],
111
+ plugins: { "no-comments": noComments, "custom": customCommentsPlugin },
112
+ rules: {
113
+ "custom/no-emojis": "error",
114
+ "custom/single-font-load": "error",
115
+ "no-comments/disallowComments": "error",
116
+ "@typescript-eslint/no-explicit-any": "error",
117
+ "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
118
+ "@typescript-eslint/consistent-type-imports": "error",
119
+
120
+ "complexity": ["error", { max: 8 }],
121
+ "max-lines": ["error", { max: 250, skipBlankLines: true, skipComments: true }],
122
+ "max-lines-per-function": ["error", { max: 30, skipBlankLines: true, skipComments: true }],
123
+ "max-depth": ["error", 4],
124
+ "max-params": ["error", 4],
125
+ "no-nested-ternary": "error",
126
+ "no-unneeded-ternary": "error",
127
+ },
128
+ },
129
+
130
+ {
131
+ files: ["**/*.astro", "**/*.html"],
132
+ plugins: { custom: customCommentsPlugin },
133
+ rules: { "custom/no-html-comments": "error" },
134
+ },
135
+
136
+ {
137
+ files: ["**/*.astro"],
138
+ plugins: { custom: customCommentsPlugin },
139
+ rules: {
140
+ "custom/no-css-comments": "error",
141
+ "custom/single-font-load": "error",
142
+ "max-lines": ["error", { max: 250, skipBlankLines: true, skipComments: true }],
143
+ },
144
+ },
145
+
146
+ {
147
+ files: ["**/SEORenderer.astro"],
148
+ rules: {
149
+ "max-lines-per-function": "off",
150
+ "complexity": "off",
151
+ },
152
+ },
153
+ {
154
+ files: ["**/i18n/*.ts"],
155
+ rules: {
156
+ "max-lines": "off",
157
+ },
158
+ },
159
+ {
160
+ files: ["**/pages/**/*.astro"],
161
+ rules: {
162
+ "max-lines-per-function": ["error", { max: 50, skipBlankLines: true, skipComments: true }],
163
+ "complexity": "off",
164
+ "no-comments/disallowComments": "off",
165
+ },
166
+ },
167
+ {
168
+ files: ["**/tests/**/*.ts", "**/*.test.ts"],
169
+ rules: {
170
+ "@typescript-eslint/no-explicit-any": "off",
171
+ "max-lines-per-function": "off",
172
+ "max-lines": "off",
173
+ },
174
+ },
175
+ {
176
+ files: ["**/*seo.astro"],
177
+ rules: {
178
+ "max-lines-per-function": "off",
179
+ "complexity": "off",
180
+ "@typescript-eslint/no-explicit-any": "off",
181
+ },
182
+ },
183
+ {
184
+ files: ["**/i18n/**/*.ts", "**/app.ts"],
185
+ rules: {
186
+ "@typescript-eslint/no-explicit-any": "off",
187
+ "max-params": "off",
188
+ "max-lines": "off",
189
+ "max-lines-per-function": "off",
190
+ },
191
+ },
192
+ {
193
+ files: ["**/tool/**/component.astro"],
194
+ rules: {
195
+ "max-lines": "off",
196
+ "max-lines-per-function": "off",
197
+ "complexity": "off",
198
+ },
199
+ },
200
+ ];
201
+
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@jjlmoya/utils-performing-arts",
3
+ "version": "1.1.0",
4
+ "type": "module",
5
+ "main": "./src/index.ts",
6
+ "types": "./src/index.ts",
7
+ "exports": {
8
+ ".": "./src/index.ts",
9
+ "./data": "./src/data.ts",
10
+ "./entries": "./src/entries.ts",
11
+ "./runtime/*": "./src/tool/*/index.ts",
12
+ "./category-seo": "./src/category/PerformingArtsCategorySEO.astro"
13
+ },
14
+ "files": [
15
+ ".github",
16
+ ".gitignore",
17
+ ".stylelintrc.json",
18
+ "astro.config.mjs",
19
+ "eslint.config.js",
20
+ "package.json",
21
+ "package-lock.json",
22
+ "prompts",
23
+ "scripts",
24
+ "src",
25
+ "tsconfig.json",
26
+ "vitest.config.ts"
27
+ ],
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "scripts": {
32
+ "dev": "astro dev --host",
33
+ "start": "astro dev",
34
+ "build": "astro build",
35
+ "preview": "astro preview",
36
+ "astro": "astro",
37
+ "lint": "eslint src/ --max-warnings 0 && stylelint \"src/**/*.{css,astro}\"",
38
+ "check": "astro check",
39
+ "type-check": "astro check",
40
+ "test": "vitest run --reporter=verbose --testTimeout=30000",
41
+ "preversion": "npm run lint && npm run test && npm run build",
42
+ "postversion": "git push && git push --tags",
43
+ "patch": "npm version patch",
44
+ "minor": "npm version minor",
45
+ "major": "npm version major",
46
+ "postinstall": "node scripts/postinstall.mjs"
47
+ },
48
+ "lint-staged": {
49
+ "*.{ts,tsx,astro}": [
50
+ "eslint --fix"
51
+ ]
52
+ },
53
+ "dependencies": {
54
+ "@iconify-json/mdi": "^1.2.3",
55
+ "@jjlmoya/prompagate": "^1.1.0",
56
+ "@jjlmoya/utils-shared": "1.2.0",
57
+ "@panzoom/panzoom": "^4.6.2",
58
+ "astro": "^6.1.2",
59
+ "astro-icon": "^1.1.0",
60
+ "html2canvas": "^1.4.1",
61
+ "interactjs": "^1.10.27"
62
+ },
63
+ "devDependencies": {
64
+ "@astrojs/check": "^0.9.8",
65
+ "eslint": "^9.39.4",
66
+ "eslint-plugin-astro": "^1.6.0",
67
+ "eslint-plugin-no-comments": "^1.1.10",
68
+ "husky": "^9.1.7",
69
+ "lint-staged": "^16.4.0",
70
+ "postcss-html": "^1.8.1",
71
+ "schema-dts": "^1.1.2",
72
+ "stylelint": "^17.6.0",
73
+ "stylelint-config-standard": "^40.0.0",
74
+ "stylelint-declaration-strict-value": "^1.11.1",
75
+ "typescript": "^5.4.0",
76
+ "typescript-eslint": "^8.58.0",
77
+ "vitest": "^4.1.2"
78
+ }
79
+ }
@@ -0,0 +1,98 @@
1
+ ¡Hola! Qué buena base de partida. Lo que tienes aquí es una guía excelente, pero hiperfocalizada en herramientas de rol y dados (performing-arts).
2
+
3
+ Para transformarla en una habilidad/guía genérica, lo que haremos será abstraer el dominio del juego y los dados, y sustituirlo por conceptos universales de desarrollo de software (como "núcleo de la aplicación", "métricas de negocio", "feedback visual de alto impacto" y "componentes estructurados").
4
+
5
+ Aquí tienes la versión completamente genérica, modular y lista para aplicar a cualquier tipo de biblioteca de herramientas web.
6
+
7
+ Creating Library Tools: Developer Skill & Workflow Guide
8
+ Follow this guide to build new tools in the core utility library. This document outlines the technical standards, user experience (UX) requirements, SEO standards, and step-by-step translation workflow.
9
+
10
+ Philosophy & Rigid Rules
11
+ 1. Code Quality & Formatting
12
+ SOLID Principles: Keep components small, focused, and reusable. Business logic and UI components must be completely separated.
13
+
14
+ NO Comments in Code: Do not write any comments (// or /* */) in TypeScript, framework components, CSS, or JSON files.
15
+
16
+ NO Emojis: Do not use emojis in code, UI text, logs, titles, metadata, or translations.
17
+
18
+ 2. High-Dopamine User Experience
19
+ Interactive Outcomes: Visual result banners must include detailed logical breakdowns displaying custom geometric badges or status indicators that match the exact category and context of the output.
20
+
21
+ Epic Feedback Animations:
22
+
23
+ Peak or optimal results must trigger an emphasis animation (e.g., scale-up rotation, bright dynamic border) and render a custom highlighting SVG symbol.
24
+
25
+ Critical errors or minimal results must trigger a warning animation (e.g., shiver-drop sag, desaturated danger glow) and render a distinct alert SVG symbol.
26
+
27
+ Click Particles: Spawn floating micro-feedback particles (e.g., value offsets, status triggers) at the exact click coordinates with text shadow glows and translation animations.
28
+
29
+ Micro-Animations: All interactive elements (button presses, selectors, and adjustments) must trigger springy hover and active scale animations to maximize tactile responsiveness.
30
+
31
+ 3. Premium User-Facing SEO
32
+ No Programming Content: Do not write code examples, programming explanations, or developer jargon in public SEO text. Focus entirely on user utility, core value proposition, and practical use cases.
33
+
34
+ Rich Elements: Build information architectures using structured layouts (stats, table, tip, proscons, comparative, glossary, diagnostic).
35
+
36
+ No Hyphens or Pipes in Titles: Page titles in SEO sections and metadata must never contain - or | separators.
37
+
38
+ Workflow Steps
39
+ Step 1: Core Implementation (English-First)
40
+ Analyze existing library tools to understand registered paths, file structures, and shared core imports.
41
+
42
+ Build the primary tool files in English following the architecture:
43
+
44
+ src/tool/$TOOL_ID/index.ts (Core logic)
45
+
46
+ src/tool/$TOOL_ID/entry.ts (Registration & metadata)
47
+
48
+ src/tool/$TOOL_ID/component.[ext] (UI View)
49
+
50
+ src/tool/$TOOL_ID/seo.[ext] (SEO & Marketing content)
51
+
52
+ src/tool/$TOOL_ID/bibliography.ts (Data sources/References logic)
53
+
54
+ src/tool/$TOOL_ID/bibliography.[ext] (Data sources view)
55
+
56
+ src/tool/$TOOL_ID/i18n/en.ts (English dictionary)
57
+
58
+ src/tool/$TOOL_ID/$TOOL_ID.css (Scoped styles)
59
+
60
+ Map all i18n properties in the entry file to the English dictionary temporarily.
61
+
62
+ Add the new tool entry to the central registration files (indexes, categories, and routing lists).
63
+
64
+ Step 2: Component Refactoring & Clean Up
65
+ Enforce strict style linting compliance: Do not use literal design values (hex, rgb, raw pixels) inside CSS properties; declare them as design tokens/CSS variables in the global root scope and read them via var().
66
+
67
+ Keep functions under 30 lines and source code files under 250 lines to maintain maintainability.
68
+
69
+ Step 3: Verification & QA
70
+ Run linting to check for formatting, syntax, and comment violations:
71
+ npm run lint
72
+
73
+ Run unit tests to check core mathematical, parsing, or business logic:
74
+ npm run test -- --testPathIgnorePatterns=i18n_coverage
75
+
76
+ After this, ask for the user's feedback.
77
+
78
+ Step 4: Multi-Language Translation
79
+ Once the baseline English tool is validated by the user, translate the content to the supported production locales:
80
+
81
+ Target Locales: de, es, fr, id, it, ja, ko, nl, pl, pt, ru, sv, tr, zh.
82
+
83
+ Slug Localization Rules:
84
+
85
+ For logographic script locales (ja, ko, zh), the URL slug must remain identical to the English slug.
86
+
87
+ For all other locales, translate and fully localize the URL slug to its respective language.
88
+
89
+ Separators Validation: Double check that no titles in the translated files contain - or |.
90
+
91
+ Register the loaders for the new locales in the tool's entry configuration.
92
+
93
+ Step 5: Final Verification
94
+ Run the complete automated lint and test suites to verify all locales and configurations are fully compliant:
95
+
96
+ npm run lint
97
+
98
+ npm run test
@@ -0,0 +1,16 @@
1
+ # Prompts-utsch (de)
2
+
3
+ ## Übersetzung
4
+
5
+ Lokalisieren Sie den folgenden Inhalt ins Deutsche.
6
+
7
+ Übersetzen Sie nicht: lokalisieren Sie. Das Ziel ist nicht, Wörter von einer Sprache in eine andere zu übertragen, sondern einen Text zu erstellen, der so klingt, als wäre er von Anfang an von einem echten Menschen auf Deutsch geschrieben worden. Ein gut lokalisierter Text lässt keine Spuren der Ausgangssprache erkennen.
8
+
9
+ Schreiben Sie mit menschlicher Stimme: nah, klar und professionell. Vermeiden Sie Maschinensprache, erzwungene Konstruktionen und Sätze, die wie eine Bedienungsanleitung klingen. Wenn etwas auf Deutsch nicht natürlich fließt, formulieren Sie es um, bis es das tut.
10
+
11
+ Einzuhaltende Richtlinien:
12
+
13
+ - Passen Sie Ausdrücke, Metaphern und kulturelle Bezüge an das an, was in einem deutschsprachigen Kontext natürlich ankommen würde.
14
+ - Verwenden Sie Fachbegriffe in ihrer im deutschsprachigen Raum gebräuchlichsten Form; wenn kein klares Äquivalent existiert, behalten Sie den Originalbegriff bei.
15
+ - Respektieren Sie die Formatierung des Originals (Markdown, Listen, Überschriften).
16
+ - Fügen Sie keine Informationen hinzu und lassen Sie keine Informationen gegenüber dem Original weg.
@@ -0,0 +1,16 @@
1
+ # Prompts-glish (en)
2
+
3
+ ## Translation
4
+
5
+ Localize the following content into English.
6
+
7
+ Don't translate: localize. Your goal is not to carry words from one language to another, but to produce text that reads as if it were written in English by a real person from the start. A well-localized text leaves no trace of the source language.
8
+
9
+ Write with a human voice: warm, clear, and professional. Avoid machine-like phrasing, stiff constructions, and anything that sounds like it came out of an instruction manual. If something doesn't flow naturally in English, rewrite it until it does.
10
+
11
+ Guidelines to follow:
12
+
13
+ - Adapt expressions, metaphors, and cultural references to what would resonate naturally in an English-speaking context.
14
+ - Keep technical terms in their most widely recognized form in the English-speaking world; if no clear equivalent exists, retain the original term.
15
+ - Respect the formatting of the original (markdown, lists, headings).
16
+ - Do not add or omit any information from the original.
@@ -0,0 +1,16 @@
1
+ # Prompts-pañol (es)
2
+
3
+ ## Traducción
4
+
5
+ Localiza el siguiente contenido al español.
6
+
7
+ No traduzcas: localiza. Tu objetivo no es trasladar palabras de un idioma a otro, sino que el resultado suene como si hubiera sido escrito originalmente en español por una persona real. Un texto bien localizado no tiene rastro del idioma de origen.
8
+
9
+ Escribe con voz humana: cercana, clara y profesional. Evita el lenguaje de máquina, los giros forzados y las frases que suenan a manual de instrucciones. Si algo no fluye de forma natural en español, reformúlalo hasta que lo haga.
10
+
11
+ Criterios que debes respetar:
12
+
13
+ - Adapta expresiones, metáforas y referencias culturales a lo que resonaría de forma natural en un contexto hispanohablante.
14
+ - Mantén los términos técnicos en su forma más reconocida en el ámbito hispanohablante; si no existe un equivalente claro, conserva el término original.
15
+ - Respeta el formato del original (markdown, listas, encabezados).
16
+ - No añadas ni omitas información respecto al original.
@@ -0,0 +1,16 @@
1
+ # Prompts-ançais (fr)
2
+
3
+ ## Traduction
4
+
5
+ Localisez le contenu suivant en français.
6
+
7
+ Ne traduisez pas : localisez. L'objectif n'est pas de transposer des mots d'une langue à l'autre, mais de produire un texte qui semble avoir été écrit directement en français par une personne réelle. Un texte bien localisé ne laisse aucune trace de la langue source.
8
+
9
+ Écrivez avec une voix humaine : proche, claire et professionnelle. Évitez le langage machine, les tournures forcées et les phrases qui sonnent comme un manuel d'utilisation. Si quelque chose ne coule pas naturellement en français, reformulez-le jusqu'à ce que ce soit le cas.
10
+
11
+ Critères à respecter :
12
+
13
+ - Adaptez les expressions, les métaphores et les références culturelles à ce qui résonnerait naturellement dans un contexte francophone.
14
+ - Conservez les termes techniques dans leur forme la plus reconnue dans le monde francophone ; s'il n'existe pas d'équivalent clair, gardez le terme original.
15
+ - Respectez la mise en forme de l'original (markdown, listes, titres).
16
+ - N'ajoutez ni ne supprimez aucune information par rapport à l'original.
@@ -0,0 +1,16 @@
1
+ # Prompts-hasa Indonesia (id)
2
+
3
+ ## Terjemahan
4
+
5
+ Lokalisasi konten berikut ke dalam Bahasa Indonesia.
6
+
7
+ Jangan menerjemahkan: lokalisasi. Tujuannya bukan memindahkan kata dari satu bahasa ke bahasa lain, melainkan menghasilkan teks yang terasa seolah-olah ditulis langsung dalam Bahasa Indonesia oleh orang sungguhan. Teks yang dilokalisasi dengan baik tidak meninggalkan jejak bahasa sumbernya.
8
+
9
+ Tulis dengan suara manusia: hangat, jelas, dan profesional. Hindari bahasa mesin, susunan kalimat yang dipaksakan, dan kalimat yang terdengar seperti buku panduan. Jika ada yang tidak mengalir secara alami dalam Bahasa Indonesia, tulis ulang hingga terasa alami.
10
+
11
+ Panduan yang harus diikuti:
12
+
13
+ - Sesuaikan ekspresi, metafora, dan referensi budaya agar beresonansi secara alami dalam konteks berbahasa Indonesia.
14
+ - Gunakan istilah teknis dalam bentuk yang paling dikenal di dunia berbahasa Indonesia; jika tidak ada padanan yang jelas, pertahankan istilah aslinya.
15
+ - Pertahankan format asli (markdown, daftar, judul).
16
+ - Jangan menambahkan atau menghilangkan informasi apa pun dari aslinya.
@@ -0,0 +1,16 @@
1
+ # Prompts-aliano (it)
2
+
3
+ ## Traduzione
4
+
5
+ Localizza il seguente contenuto in italiano.
6
+
7
+ Non tradurre: localizza. L'obiettivo non è trasferire parole da una lingua all'altra, ma produrre un testo che sembri scritto fin dall'inizio in italiano da una persona reale. Un testo ben localizzato non lascia traccia della lingua di partenza.
8
+
9
+ Scrivi con voce umana: vicina, chiara e professionale. Evita il linguaggio da macchina, le costruzioni forzate e le frasi che suonano come un manuale di istruzioni. Se qualcosa non scorre in modo naturale in italiano, riformulalo finché non lo fa.
10
+
11
+ Criteri da rispettare:
12
+
13
+ - Adatta espressioni, metafore e riferimenti culturali a ciò che risuonerebbe in modo naturale in un contesto italofono.
14
+ - Mantieni i termini tecnici nella forma più riconoscibile nel mondo italofono; se non esiste un equivalente chiaro, conserva il termine originale.
15
+ - Rispetta la formattazione dell'originale (markdown, liste, intestazioni).
16
+ - Non aggiungere né omettere informazioni rispetto all'originale.
@@ -0,0 +1,16 @@
1
+ # Prompts-語 (ja)
2
+
3
+ ## 翻訳
4
+
5
+ 以下のコンテンツを日本語にローカライズしてください。
6
+
7
+ 翻訳ではなく、ローカライズを行ってください。目標は言葉をある言語から別の言語に移すことではなく、最初から日本語を母語とする人が書いたかのように自然に読めるテキストを作ることです。質の高いローカライズされたテキストには、原文言語の痕跡が残りません。
8
+
9
+ 人間の声で書いてください:親しみやすく、明確で、プロフェッショナルに。機械的な表現、不自然な言い回し、マニュアルのように聞こえる文章は避けてください。日本語として自然に読めない部分があれば、自然になるまで言い換えてください。
10
+
11
+ 遵守すべきガイドライン:
12
+
13
+ - 表現、比喩、文化的な参照を、日本語圏のコンテキストで自然に響くものに適応させてください。
14
+ - 技術用語は日本語圏で最も広く認知されている形で使用し、明確な対応語がない場合は元の用語をそのまま使用してください。
15
+ - 原文のフォーマット(マークダウン、リスト、見出し)を尊重してください。
16
+ - 原文から情報を追加したり省略したりしないでください。