@birdapi/velinstyle 1.2.0 → 1.2.2

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 (89) hide show
  1. package/README.de.md +150 -24
  2. package/README.md +155 -33
  3. package/cli/__fixtures__/atelier-library/showcases/01-login/app.css +1 -0
  4. package/cli/__fixtures__/atelier-library/showcases/01-login/app.js +2 -0
  5. package/cli/__fixtures__/atelier-library/showcases/01-login/index.html +5 -0
  6. package/cli/__fixtures__/atelier-library/showcases/04-pricing/app.css +1 -0
  7. package/cli/__fixtures__/atelier-library/showcases/04-pricing/app.js +2 -0
  8. package/cli/__fixtures__/atelier-library/showcases/04-pricing/index.html +5 -0
  9. package/cli/__fixtures__/atelier-library/showcases/36-calendar/app.css +1 -0
  10. package/cli/__fixtures__/atelier-library/showcases/36-calendar/app.js +2 -0
  11. package/cli/__fixtures__/atelier-library/showcases/36-calendar/index.html +5 -0
  12. package/cli/atelier-catalog.json +1267 -0
  13. package/cli/atelier-formats.js +159 -0
  14. package/cli/atelier.js +382 -0
  15. package/cli/blueprints/empty-state.html +3 -5
  16. package/cli/cli-manifest.json +23 -10
  17. package/cli/docgen/extract-attributes.js +2 -0
  18. package/cli/docgen/extract-cli.js +1 -1
  19. package/cli/index.js +181 -6
  20. package/cli/production/component-graph.json +166 -0
  21. package/cli/production/explain.js +52 -0
  22. package/cli/production/extract.js +238 -0
  23. package/cli/production/graph.js +102 -0
  24. package/cli/production/report.js +78 -0
  25. package/cli/production/run.js +312 -0
  26. package/cli/production/trim-css.js +177 -0
  27. package/cli/production/trim-fonts.js +23 -0
  28. package/cli/production/trim-icons.js +38 -0
  29. package/cli/production/trim-js.js +48 -0
  30. package/cli/production/trim-motion.js +22 -0
  31. package/cli/production/trim-themes.js +50 -0
  32. package/cli/production/watch.js +38 -0
  33. package/cli/review.js +48 -1
  34. package/cli/scripts/write-atelier-fixtures.mjs +33 -0
  35. package/cli/transparency.js +221 -0
  36. package/components/index.js +3 -0
  37. package/components/runtime/component-loaders.js +3 -0
  38. package/components/velin-drawer.js +43 -4
  39. package/components/velin-empty-state.js +83 -0
  40. package/components/velin-modal.js +76 -15
  41. package/components/velin-otp-input.js +220 -0
  42. package/components/velin-password-strength.js +147 -0
  43. package/components/velin-sheet.js +49 -4
  44. package/core/a11y/component-contracts.json +23 -4
  45. package/core/attributes/registry.js +14 -0
  46. package/core/meta/knowledge/components.json +75 -3
  47. package/core/meta/schema.js +10 -0
  48. package/core/transparency/attach.js +74 -0
  49. package/core/transparency/claims.js +97 -0
  50. package/core/transparency/doctor.js +142 -0
  51. package/core/transparency/engine.js +75 -0
  52. package/core/transparency/export.js +98 -0
  53. package/core/transparency/index.js +30 -0
  54. package/core/transparency/migrate.js +130 -0
  55. package/core/transparency/normalize.js +125 -0
  56. package/core/transparency/policy.js +105 -0
  57. package/core/transparency/providers.js +235 -0
  58. package/core/transparency/registry.js +104 -0
  59. package/core/transparency/renderer.js +111 -0
  60. package/core/transparency/reporter.js +113 -0
  61. package/core/transparency/validator.js +112 -0
  62. package/dist/chunks/attach-H2ZSEAE6.js +365 -0
  63. package/dist/chunks/attributes-2ORR27KA.js +404 -0
  64. package/dist/chunks/attributes-DZCXX2RZ.js +404 -0
  65. package/dist/chunks/chunk-CQMTCEI6.js +113 -0
  66. package/dist/chunks/chunk-Y6HN7HWX.js +116 -0
  67. package/dist/chunks/runtime-entry.js +1 -1
  68. package/dist/chunks/velin-drawer-A7Q7EBOS.js +162 -0
  69. package/dist/chunks/velin-empty-state-3NTUH2RF.js +81 -0
  70. package/dist/chunks/velin-modal-3MV4FYBK.js +231 -0
  71. package/dist/chunks/velin-otp-input-PSK42MM6.js +207 -0
  72. package/dist/chunks/velin-password-strength-TAXMLSED.js +136 -0
  73. package/dist/chunks/velin-sheet-N2VVYXFP.js +157 -0
  74. package/dist/llms.txt +5 -4
  75. package/dist/search-index.json +94 -5
  76. package/dist/velin-agent.json +290 -23
  77. package/dist/velinstyle-components.iife.js +3189 -2202
  78. package/dist/velinstyle-components.js +3187 -2196
  79. package/dist/velinstyle-components.min.js +261 -119
  80. package/dist/velinstyle.css +214 -6
  81. package/dist/velinstyle.d.ts +3 -0
  82. package/dist/velinstyle.min.css +1 -1
  83. package/package.json +143 -142
  84. package/packages/velinstyle-skills/catalog.json +1 -1
  85. package/src/components/data-table.css +19 -0
  86. package/src/components/empty-auth.css +33 -0
  87. package/src/components/table.css +16 -6
  88. package/src/components/transparency.css +138 -0
  89. package/src/velinstyle.css +2 -0
@@ -0,0 +1,365 @@
1
+ // core/transparency/claims.js
2
+ var CLAIM_CATALOG = {
3
+ "ai.generated": { pillar: "ai", label: { en: "AI generated", de: "KI-generiert" } },
4
+ "ai.assisted": { pillar: "ai", label: { en: "AI assisted", de: "KI-unterst\xFCtzt" } },
5
+ "review.human": { pillar: "ai", label: { en: "Human reviewed", de: "Mensch gepr\xFCft" } },
6
+ "review.verified": { pillar: "trust", label: { en: "Verified", de: "Verifiziert" } },
7
+ "security.checked": { pillar: "trust", label: { en: "Security checked", de: "Security gepr\xFCft" } },
8
+ "accessibility.checked": { pillar: "trust", label: { en: "Accessibility checked", de: "Barrierefreiheit gepr\xFCft" } },
9
+ "trust.official": { pillar: "trust", label: { en: "Official", de: "Offiziell" } },
10
+ "trust.signed": { pillar: "trust", label: { en: "Signed", de: "Signiert" } },
11
+ "trust.opensource": { pillar: "trust", label: { en: "Open source", de: "Open Source" } },
12
+ "privacy.gdpr": { pillar: "compliance", label: { en: "GDPR", de: "DSGVO" } },
13
+ "license.cc-by": { pillar: "compliance", label: { en: "CC BY", de: "CC BY" } },
14
+ "license.mit": { pillar: "compliance", label: { en: "MIT", de: "MIT" } },
15
+ "license.apache-2": { pillar: "compliance", label: { en: "Apache-2.0", de: "Apache-2.0" } },
16
+ "content.updated": { pillar: "metadata", label: { en: "Updated", de: "Aktualisiert" } },
17
+ "content.author": { pillar: "metadata", label: { en: "Author", de: "Autor" } },
18
+ "content.source": { pillar: "metadata", label: { en: "Source", de: "Quelle" } },
19
+ "content.language": { pillar: "metadata", label: { en: "Language", de: "Sprache" } },
20
+ "version.current": { pillar: "metadata", label: { en: "Version", de: "Version" } },
21
+ "provenance.complete": { pillar: "provenance", label: { en: "Provenance complete", de: "Nachweis vollst\xE4ndig" } }
22
+ };
23
+ var STATUS_TO_CLAIM = {
24
+ generated: "ai.generated",
25
+ assisted: "ai.assisted",
26
+ "ai-assisted": "ai.assisted",
27
+ "human-reviewed": "review.human",
28
+ "human-edited": "review.human",
29
+ verified: "review.verified",
30
+ edited: "review.human",
31
+ draft: null
32
+ };
33
+ var REVIEW_TO_CLAIM = {
34
+ human: "review.human",
35
+ "human-reviewed": "review.human",
36
+ verified: "review.verified",
37
+ none: null
38
+ };
39
+ var LICENSE_TO_CLAIM = {
40
+ "cc by 4.0": "license.cc-by",
41
+ "cc-by": "license.cc-by",
42
+ "cc-by-4.0": "license.cc-by",
43
+ mit: "license.mit",
44
+ "apache-2.0": "license.apache-2",
45
+ apache: "license.apache-2"
46
+ };
47
+ function deriveClaims({ status, review, license, claims = [] } = {}) {
48
+ const out = new Set(Array.isArray(claims) ? claims.filter(Boolean) : []);
49
+ const statusClaim = STATUS_TO_CLAIM[String(status || "").toLowerCase()];
50
+ if (statusClaim) out.add(statusClaim);
51
+ const reviewClaim = REVIEW_TO_CLAIM[String(review || "").toLowerCase()];
52
+ if (reviewClaim) out.add(reviewClaim);
53
+ if (license) {
54
+ const key = String(license).toLowerCase().trim();
55
+ const mapped = LICENSE_TO_CLAIM[key] || (key.startsWith("cc") ? "license.cc-by" : null);
56
+ if (mapped) out.add(mapped);
57
+ }
58
+ return [...out];
59
+ }
60
+ function claimLabel(claim, lang = "en") {
61
+ const entry = CLAIM_CATALOG[claim];
62
+ if (!entry) return claim;
63
+ return entry.label[lang] || entry.label.en || claim;
64
+ }
65
+ function primaryLabel(claims = [], lang = "en") {
66
+ const order = ["ai.generated", "ai.assisted", "review.human", "review.verified", "trust.official", "license.cc-by", "license.mit"];
67
+ for (const c of order) {
68
+ if (claims.includes(c)) return claimLabel(c, lang);
69
+ }
70
+ if (claims[0]) return claimLabel(claims[0], lang);
71
+ return lang === "de" ? "Transparenz" : "Transparency";
72
+ }
73
+
74
+ // core/transparency/registry.js
75
+ function createRegistry() {
76
+ const map = /* @__PURE__ */ new Map();
77
+ return {
78
+ register(record) {
79
+ if (!record?.id) throw new Error("DisclosureRecord requires id");
80
+ map.set(record.id, structuredCloneSafe(record));
81
+ return map.get(record.id);
82
+ },
83
+ get(id) {
84
+ return map.get(id) || null;
85
+ },
86
+ has(id) {
87
+ return map.has(id);
88
+ },
89
+ remove(id) {
90
+ return map.delete(id);
91
+ },
92
+ list() {
93
+ return [...map.values()].map((r) => structuredCloneSafe(r));
94
+ },
95
+ query(predicate) {
96
+ return this.list().filter(predicate);
97
+ },
98
+ clear() {
99
+ map.clear();
100
+ },
101
+ size() {
102
+ return map.size;
103
+ },
104
+ export() {
105
+ return { schema: "velinstyle.transparency.registry", version: 1, items: this.list() };
106
+ },
107
+ diff(otherList = []) {
108
+ const other = new Map(otherList.map((r) => [r.id, r]));
109
+ const added = [];
110
+ const removed = [];
111
+ const changed = [];
112
+ for (const r of map.values()) {
113
+ if (!other.has(r.id)) added.push(r.id);
114
+ else if (JSON.stringify(r) !== JSON.stringify(other.get(r.id))) changed.push(r.id);
115
+ }
116
+ for (const id of other.keys()) {
117
+ if (!map.has(id)) removed.push(id);
118
+ }
119
+ return { added, removed, changed };
120
+ }
121
+ };
122
+ }
123
+ function structuredCloneSafe(obj) {
124
+ return JSON.parse(JSON.stringify(obj));
125
+ }
126
+ function stableDisclosureId(parts = {}) {
127
+ if (parts.id) return String(parts.id).trim();
128
+ const raw = [parts.file || "", parts.selector || "", parts.src || "", parts.tag || "", parts.type || ""].join("|").toLowerCase();
129
+ let h = 2166136261;
130
+ for (let i = 0; i < raw.length; i += 1) {
131
+ h ^= raw.charCodeAt(i);
132
+ h = Math.imul(h, 16777619);
133
+ }
134
+ return `tx-${(h >>> 0).toString(16)}`;
135
+ }
136
+
137
+ // core/transparency/normalize.js
138
+ var PROVENANCE_KEYS = [
139
+ "createdBy",
140
+ "createdAt",
141
+ "reviewedAt",
142
+ "approvedBy",
143
+ "source",
144
+ "license",
145
+ "version",
146
+ "publishedAt"
147
+ ];
148
+ function normalizeDisclosure(draft = {}, ctx = {}) {
149
+ const provider = String(draft.provider || ctx.provider || "api");
150
+ const type = String(draft.type || "ai").toLowerCase();
151
+ const status = draft.status != null ? String(draft.status).toLowerCase() : void 0;
152
+ const review = draft.review != null ? String(draft.review).toLowerCase() : void 0;
153
+ const provenance = normalizeProvenance(draft.provenance || draft);
154
+ if (draft.license && !provenance.license) provenance.license = String(draft.license);
155
+ if (draft.model && !provenance.source) provenance.source = `model:${draft.model}`;
156
+ if (draft.generated === true && !status) {
157
+ }
158
+ const resolvedStatus = status || (draft.generated === true ? "generated" : void 0);
159
+ const claims = deriveClaims({
160
+ status: resolvedStatus,
161
+ review,
162
+ license: provenance.license,
163
+ claims: draft.claims
164
+ });
165
+ const target = {
166
+ selector: draft.target?.selector || draft.selector || void 0,
167
+ tag: draft.target?.tag || draft.tag || void 0,
168
+ src: draft.target?.src || draft.src || void 0,
169
+ file: draft.target?.file || ctx.file || draft.file || void 0
170
+ };
171
+ const id = stableDisclosureId({
172
+ id: draft.id || draft.velinTransparencyId,
173
+ selector: target.selector,
174
+ src: target.src,
175
+ tag: target.tag,
176
+ type,
177
+ file: target.file
178
+ });
179
+ const lang = ctx.lang === "de" ? "de" : "en";
180
+ const label = draft.label ? String(draft.label) : primaryLabel(claims, lang);
181
+ const updated = draft.updated || provenance.publishedAt || provenance.reviewedAt || provenance.createdAt || void 0;
182
+ return {
183
+ id,
184
+ type,
185
+ status: resolvedStatus,
186
+ review,
187
+ provider,
188
+ claims,
189
+ provenance,
190
+ updated,
191
+ label,
192
+ description: draft.description ? String(draft.description) : void 0,
193
+ renderer: draft.renderer || draft.overlay || "badge",
194
+ tone: draft.tone || toneFromClaims(claims),
195
+ position: draft.position || "top-right",
196
+ target,
197
+ meta: draft.meta && typeof draft.meta === "object" ? draft.meta : void 0
198
+ };
199
+ }
200
+ function normalizeProvenance(src = {}) {
201
+ const out = {};
202
+ for (const key of PROVENANCE_KEYS) {
203
+ const v = src[key] ?? src[key.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`)];
204
+ if (v != null && String(v).trim()) out[key] = String(v).trim();
205
+ }
206
+ if (src["created-by"]) out.createdBy = String(src["created-by"]);
207
+ if (src["created-at"]) out.createdAt = String(src["created-at"]);
208
+ if (src["reviewed-at"]) out.reviewedAt = String(src["reviewed-at"]);
209
+ if (src["approved-by"]) out.approvedBy = String(src["approved-by"]);
210
+ if (src["published-at"]) out.publishedAt = String(src["published-at"]);
211
+ return out;
212
+ }
213
+ function toneFromClaims(claims) {
214
+ if (claims.includes("ai.generated")) return "generated";
215
+ if (claims.includes("review.verified") || claims.includes("trust.official")) return "verified";
216
+ if (claims.includes("review.human")) return "human";
217
+ if (claims.includes("ai.assisted")) return "mixed";
218
+ return "neutral";
219
+ }
220
+
221
+ // core/transparency/renderer.js
222
+ var renderers = /* @__PURE__ */ new Map();
223
+ function registerTransparencyRenderer(name, fn) {
224
+ renderers.set(name, fn);
225
+ }
226
+ function renderDisclosure(el, record) {
227
+ if (typeof document === "undefined" || !el) return null;
228
+ const name = record.renderer || "badge";
229
+ const custom = renderers.get(name);
230
+ if (custom) {
231
+ custom(el, record);
232
+ return el.querySelector(".velin-transparency");
233
+ }
234
+ return defaultRender(el, record);
235
+ }
236
+ function defaultRender(el, record) {
237
+ const cs = getComputedStyle(el);
238
+ if (cs.position === "static") el.style.position = "relative";
239
+ let mark = el.querySelector(":scope > .velin-transparency");
240
+ if (!mark) {
241
+ mark = document.createElement("div");
242
+ el.prepend(mark);
243
+ }
244
+ const renderer = record.renderer || "badge";
245
+ const tone = record.tone || "neutral";
246
+ const position = record.position || "top-right";
247
+ mark.className = [
248
+ "velin-transparency",
249
+ `velin-transparency--${renderer}`,
250
+ `velin-transparency--tone-${tone}`,
251
+ `velin-transparency--pos-${position}`
252
+ ].join(" ");
253
+ mark.setAttribute("data-velin-transparency-id", record.id);
254
+ mark.setAttribute("role", "note");
255
+ const claimsText = (record.claims || []).join(", ");
256
+ const prov = record.provenance || {};
257
+ const sr = document.createElement("span");
258
+ sr.className = "velin-sr-only";
259
+ const lang = (el.closest("[lang]")?.getAttribute("lang") || document.documentElement.lang || "en").startsWith("de") ? "de" : "en";
260
+ sr.textContent = lang === "de" ? `Transparenzhinweis: ${record.label}. ${claimsText}. ${provenanceSr(prov, "de")}` : `Transparency notice: ${record.label}. ${claimsText}. ${provenanceSr(prov, "en")}`;
261
+ const visible = document.createElement("span");
262
+ visible.className = "velin-transparency__label";
263
+ visible.textContent = record.label || "Transparency";
264
+ const details = document.createElement("span");
265
+ details.className = "velin-transparency__details";
266
+ details.hidden = renderer === "badge" || renderer === "icon";
267
+ details.textContent = formatDetails(record, lang);
268
+ mark.replaceChildren(sr, visible, details);
269
+ if (record.description) mark.title = record.description;
270
+ else if (details.textContent) mark.title = details.textContent;
271
+ el.setAttribute("data-velin-transparency", record.id);
272
+ return mark;
273
+ }
274
+ function provenanceSr(p, lang) {
275
+ const parts = [];
276
+ if (p.createdBy) parts.push(lang === "de" ? `Erstellt von ${p.createdBy}` : `Created by ${p.createdBy}`);
277
+ if (p.createdAt) parts.push(lang === "de" ? `am ${p.createdAt}` : `on ${p.createdAt}`);
278
+ if (p.approvedBy) parts.push(lang === "de" ? `Freigegeben von ${p.approvedBy}` : `Approved by ${p.approvedBy}`);
279
+ if (p.license) parts.push(p.license);
280
+ if (p.version) parts.push(`v${p.version}`);
281
+ return parts.join(". ");
282
+ }
283
+ function formatDetails(record, lang) {
284
+ const p = record.provenance || {};
285
+ const bits = [];
286
+ if (p.approvedBy) bits.push(lang === "de" ? `Freigabe: ${p.approvedBy}` : `Approved: ${p.approvedBy}`);
287
+ if (p.license) bits.push(p.license);
288
+ if (p.version) bits.push(`v${p.version}`);
289
+ if (p.updated || record.updated) bits.push(record.updated || p.publishedAt || "");
290
+ return bits.filter(Boolean).join(" \xB7 ");
291
+ }
292
+ for (const name of ["overlay", "badge", "inline", "tooltip", "footer", "ribbon", "panel", "icon", "corner-badge", "stamp", "sidebar", "floating-card", "banner"]) {
293
+ registerTransparencyRenderer(name, (el, record) => {
294
+ defaultRender(el, { ...record, renderer: normalizeRendererName(name) });
295
+ });
296
+ }
297
+ function normalizeRendererName(name) {
298
+ if (name === "corner-badge" || name === "stamp") return "badge";
299
+ if (name === "floating-card" || name === "sidebar") return "panel";
300
+ if (name === "banner") return "footer";
301
+ return name;
302
+ }
303
+
304
+ // core/transparency/attach.js
305
+ var defaultRegistry = createRegistry();
306
+ function attach(el, options = {}, ctx = {}) {
307
+ if (!el) throw new Error("VelinTransparency.attach requires an element");
308
+ const registry = ctx.registry || defaultRegistry;
309
+ const draft = {
310
+ ...options,
311
+ tag: el.tagName,
312
+ src: el.getAttribute?.("src") || el.getAttribute?.("href") || options.src,
313
+ selector: el.id ? `#${el.id}` : options.selector,
314
+ id: options.id || el.getAttribute?.("velin-transparency-id") || el.id,
315
+ provider: options.provider || "api"
316
+ };
317
+ if (el.hasAttribute?.("velin-transparency") || el.hasAttribute?.("velin-disclosure")) {
318
+ draft.type = draft.type || el.getAttribute("velin-type") || "ai";
319
+ draft.status = draft.status || el.getAttribute("velin-status");
320
+ draft.review = draft.review || el.getAttribute("velin-review");
321
+ draft.license = draft.license || el.getAttribute("velin-license");
322
+ draft.label = draft.label || el.getAttribute("velin-label");
323
+ draft.description = draft.description || el.getAttribute("velin-description");
324
+ draft.overlay = draft.overlay || el.getAttribute("velin-overlay") || el.getAttribute("velin-renderer");
325
+ draft.provenance = {
326
+ createdBy: el.getAttribute("velin-created-by"),
327
+ createdAt: el.getAttribute("velin-created-at"),
328
+ reviewedAt: el.getAttribute("velin-reviewed-at"),
329
+ approvedBy: el.getAttribute("velin-approved-by"),
330
+ source: el.getAttribute("velin-source"),
331
+ license: el.getAttribute("velin-license"),
332
+ version: el.getAttribute("velin-version"),
333
+ publishedAt: el.getAttribute("velin-published-at"),
334
+ ...options.provenance || {}
335
+ };
336
+ }
337
+ const record = normalizeDisclosure(draft, { provider: draft.provider, lang: ctx.lang });
338
+ registry.register(record);
339
+ if (!el.hasAttribute("velin-transparency")) el.setAttribute("velin-transparency", "");
340
+ if (!el.hasAttribute("velin-transparency-id")) el.setAttribute("velin-transparency-id", record.id);
341
+ renderDisclosure(el, record);
342
+ return record;
343
+ }
344
+ function enhanceAll(root = typeof document !== "undefined" ? document : null) {
345
+ if (!root?.querySelectorAll) return [];
346
+ const out = [];
347
+ root.querySelectorAll("[velin-transparency], [velin-disclosure]").forEach((el) => {
348
+ out.push(attach(el, {}, { registry: defaultRegistry }));
349
+ });
350
+ return out;
351
+ }
352
+ function getDefaultRegistry() {
353
+ return defaultRegistry;
354
+ }
355
+ var VelinTransparency = {
356
+ attach,
357
+ enhanceAll,
358
+ getRegistry: getDefaultRegistry
359
+ };
360
+ export {
361
+ VelinTransparency,
362
+ attach,
363
+ enhanceAll,
364
+ getDefaultRegistry
365
+ };