@birdapi/velinstyle 0.8.0 → 0.9.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 (313) hide show
  1. package/README.de.md +135 -246
  2. package/README.md +134 -245
  3. package/cli/blueprints/onboarding.html +2 -2
  4. package/cli/cli-manifest.json +97 -0
  5. package/cli/docgen/extract-a11y.js +89 -0
  6. package/cli/docgen/extract-attributes.js +95 -0
  7. package/cli/docgen/extract-cli.js +50 -0
  8. package/cli/docgen/extract-components.js +175 -0
  9. package/cli/docgen/extract-meta.js +32 -0
  10. package/cli/docgen/extract-rules.js +76 -0
  11. package/cli/docgen/extract-tokens.js +79 -0
  12. package/cli/docgen/extract-utilities.js +75 -0
  13. package/cli/docgen/markdown.js +43 -0
  14. package/cli/docs-generate.js +196 -0
  15. package/cli/index.js +121 -5
  16. package/cli/meta.js +97 -0
  17. package/cli/perf-audit.js +174 -0
  18. package/cli/pii-scanner.js +134 -0
  19. package/cli/scanner-rules-data.js +62 -0
  20. package/cli/scanner.js +68 -1
  21. package/cli/search-index.js +163 -0
  22. package/cli/tokens-build.js +21 -1
  23. package/cli/tokens-validate.js +69 -0
  24. package/components/a11y-entry.js +42 -0
  25. package/components/a11y-utils.js +71 -0
  26. package/components/focus-manager.js +45 -8
  27. package/components/index.js +22 -12
  28. package/components/runtime/component-loaders.js +43 -0
  29. package/components/runtime/index.js +77 -0
  30. package/components/runtime-entry.js +10 -0
  31. package/components/sanitize.js +135 -54
  32. package/components/velin-accordion.js +12 -0
  33. package/components/velin-bottom-nav.js +19 -0
  34. package/components/velin-carousel.js +2 -2
  35. package/components/velin-code-block.js +142 -0
  36. package/components/velin-command.js +15 -0
  37. package/components/velin-copy.js +18 -5
  38. package/components/velin-counter.js +3 -0
  39. package/components/velin-dialog.js +9 -1
  40. package/components/velin-email.js +94 -0
  41. package/components/velin-icon.js +65 -22
  42. package/components/velin-lightbox.js +8 -3
  43. package/components/velin-live-dot.js +5 -0
  44. package/components/velin-modal.js +6 -3
  45. package/components/velin-popover.js +34 -2
  46. package/components/velin-reveal.js +7 -65
  47. package/components/velin-scroll-top.js +1 -1
  48. package/components/velin-search.js +267 -0
  49. package/components/velin-secure-field.js +99 -0
  50. package/components/velin-sparkline.js +27 -7
  51. package/components/{velin-stepper-wc.js → velin-stepper.js} +37 -8
  52. package/components/velin-theme-toggle.js +12 -5
  53. package/components/velin-toast.js +4 -0
  54. package/components/{velin-tooltip-wc.js → velin-tooltip.js} +22 -3
  55. package/core/a11y/component-contracts.json +221 -0
  56. package/core/attributes/index.js +6 -0
  57. package/core/attributes/registry.js +268 -0
  58. package/core/highlight/highlight.js +114 -0
  59. package/core/highlight/index.js +29 -0
  60. package/core/highlight/languages/_utils.js +52 -0
  61. package/core/highlight/languages/blade.js +16 -0
  62. package/core/highlight/languages/css.js +26 -0
  63. package/core/highlight/languages/html.js +17 -0
  64. package/core/highlight/languages/js.js +58 -0
  65. package/core/highlight/languages/json.js +14 -0
  66. package/core/highlight/languages/markdown.js +16 -0
  67. package/core/highlight/languages/php.js +39 -0
  68. package/core/highlight/languages/plain.js +7 -0
  69. package/core/highlight/languages/shell.js +33 -0
  70. package/core/highlight/languages/sql.js +20 -0
  71. package/core/highlight/languages/typescript.js +28 -0
  72. package/core/highlight/observe.js +53 -0
  73. package/core/highlight/registry.js +107 -0
  74. package/core/highlight/render.js +35 -0
  75. package/core/highlight/types.js +28 -0
  76. package/core/meta/build.js +293 -0
  77. package/core/meta/index.js +17 -0
  78. package/core/meta/schema.js +49 -0
  79. package/core/motion/effects.js +54 -0
  80. package/core/motion/index.js +76 -0
  81. package/core/motion/scheduler.js +72 -0
  82. package/core/motion/scroll.js +32 -0
  83. package/core/motion/stagger.js +24 -0
  84. package/core/search/docs-url.js +96 -0
  85. package/core/search/engine.js +139 -0
  86. package/core/search/highlight.js +48 -0
  87. package/core/search/index.js +126 -0
  88. package/core/search/providers.js +36 -0
  89. package/core/search/types.js +61 -0
  90. package/core/search/worker-client.js +56 -0
  91. package/core/search/worker.js +20 -0
  92. package/dist/chunks/a11y-utils-IRC7LOPF.js +16 -0
  93. package/dist/chunks/attributes-3BZLI7XF.js +364 -0
  94. package/dist/chunks/attributes-4N5JP4CG.js +364 -0
  95. package/dist/chunks/attributes-5Q2WXGRC.js +374 -0
  96. package/dist/chunks/attributes-AIR7SVLK.js +364 -0
  97. package/dist/chunks/attributes-BGRN5XZO.js +364 -0
  98. package/dist/chunks/attributes-BVSQAYLR.js +364 -0
  99. package/dist/chunks/attributes-CDYFUY7Y.js +364 -0
  100. package/dist/chunks/attributes-JMYJZBPE.js +364 -0
  101. package/dist/chunks/attributes-R5JY3X4O.js +374 -0
  102. package/dist/chunks/attributes-STYCS3O5.js +391 -0
  103. package/dist/chunks/attributes-TNSPQTHX.js +374 -0
  104. package/dist/chunks/attributes-TPANLMLF.js +391 -0
  105. package/dist/chunks/blade-LIQLVKZQ.js +19 -0
  106. package/dist/chunks/browser-MRKYZPEH.js +1149 -0
  107. package/dist/chunks/chunk-2354NEBP.js +109 -0
  108. package/dist/chunks/chunk-2VNA7G7S.js +109 -0
  109. package/dist/chunks/chunk-42VVPW6N.js +132 -0
  110. package/dist/chunks/chunk-7FFAMRFV.js +44 -0
  111. package/dist/chunks/chunk-7MCGPHVC.js +69 -0
  112. package/dist/chunks/chunk-AQLRJSGG.js +109 -0
  113. package/dist/chunks/chunk-EWPSDMQT.js +109 -0
  114. package/dist/chunks/chunk-F7OLHTGX.js +22 -0
  115. package/dist/chunks/chunk-J472ERN2.js +242 -0
  116. package/dist/chunks/chunk-LA7264K4.js +85 -0
  117. package/dist/chunks/chunk-M5CHQVP6.js +61 -0
  118. package/dist/chunks/chunk-MKZP2TBH.js +89 -0
  119. package/dist/chunks/chunk-QTJJ3DPO.js +109 -0
  120. package/dist/chunks/chunk-RDE3QE7Z.js +89 -0
  121. package/dist/chunks/chunk-RSMRR27R.js +109 -0
  122. package/dist/chunks/chunk-RZQVWFHW.js +109 -0
  123. package/dist/chunks/chunk-SRL6EWHP.js +109 -0
  124. package/dist/chunks/chunk-U4XHMZ7D.js +109 -0
  125. package/dist/chunks/chunk-V5YIUA6G.js +109 -0
  126. package/dist/chunks/chunk-XIET2VSZ.js +109 -0
  127. package/dist/chunks/chunk-XYLJ2GCB.js +205 -0
  128. package/dist/chunks/chunk-Z4JYQ2XX.js +51 -0
  129. package/dist/chunks/chunk-ZPSPKUYD.js +109 -0
  130. package/dist/chunks/css-MQ5YU77P.js +28 -0
  131. package/dist/chunks/highlight-GJHHV4KM.js +37 -0
  132. package/dist/chunks/highlight-XTHRKBA3.js +37 -0
  133. package/dist/chunks/html-ZODC4DLQ.js +20 -0
  134. package/dist/chunks/js-MNSNYTJU.js +7 -0
  135. package/dist/chunks/json-VEM2HFH3.js +17 -0
  136. package/dist/chunks/markdown-E7OPGS3S.js +19 -0
  137. package/dist/chunks/php-MLL7T3LT.js +41 -0
  138. package/dist/chunks/plain-LJJDC5TN.js +8 -0
  139. package/dist/chunks/runtime-entry.js +14 -0
  140. package/dist/chunks/shell-QTRK4U4E.js +35 -0
  141. package/dist/chunks/sql-PPWLHGJ2.js +23 -0
  142. package/dist/chunks/typescript-JT3CCYWL.js +30 -0
  143. package/dist/chunks/velin-accordion-FBIPAEXG.js +105 -0
  144. package/dist/chunks/velin-accordion-QAQO7BI7.js +117 -0
  145. package/dist/chunks/velin-announcer-PVTXXCWR.js +33 -0
  146. package/dist/chunks/velin-bottom-nav-2N2TYWOF.js +86 -0
  147. package/dist/chunks/velin-bottom-nav-7GEMPIM6.js +86 -0
  148. package/dist/chunks/velin-bottom-nav-CTU6FFZV.js +101 -0
  149. package/dist/chunks/velin-bottom-nav-N3DFQR66.js +86 -0
  150. package/dist/chunks/velin-carousel-Y5VCOABZ.js +213 -0
  151. package/dist/chunks/velin-carousel-ZTBANFQQ.js +213 -0
  152. package/dist/chunks/velin-code-block-ASUBTAQV.js +119 -0
  153. package/dist/chunks/velin-code-block-CIAURDRJ.js +132 -0
  154. package/dist/chunks/velin-code-block-TSUKPY4C.js +123 -0
  155. package/dist/chunks/velin-code-block-Y6CM726Q.js +119 -0
  156. package/dist/chunks/velin-collapse-5XYBUIID.js +80 -0
  157. package/dist/chunks/velin-combobox-2KDTCQ7N.js +155 -0
  158. package/dist/chunks/velin-combobox-NXS4QB4R.js +155 -0
  159. package/dist/chunks/velin-combobox-UGA56HP3.js +155 -0
  160. package/dist/chunks/velin-command-CKDNO4BW.js +148 -0
  161. package/dist/chunks/velin-command-M7RNHUPR.js +136 -0
  162. package/dist/chunks/velin-command-ONKO2A3J.js +136 -0
  163. package/dist/chunks/velin-command-TMLSRGIU.js +136 -0
  164. package/dist/chunks/velin-copy-G2TZ5YBB.js +81 -0
  165. package/dist/chunks/velin-copy-NYDBOKXT.js +81 -0
  166. package/dist/chunks/velin-copy-T5KDTDXP.js +81 -0
  167. package/dist/chunks/velin-countdown-4ZVDGK4R.js +101 -0
  168. package/dist/chunks/velin-countdown-5XSTN3BH.js +101 -0
  169. package/dist/chunks/velin-countdown-7AIY66CU.js +101 -0
  170. package/dist/chunks/velin-counter-ISCTEAHI.js +118 -0
  171. package/dist/chunks/velin-counter-L5FYJF7A.js +121 -0
  172. package/dist/chunks/velin-dialog-D2GUHSCD.js +144 -0
  173. package/dist/chunks/velin-dialog-ELFOZIXZ.js +152 -0
  174. package/dist/chunks/velin-dialog-GTTZI564.js +147 -0
  175. package/dist/chunks/velin-dialog-IJLFDXAJ.js +144 -0
  176. package/dist/chunks/velin-dialog-TNS3WXMB.js +144 -0
  177. package/dist/chunks/velin-drawer-BE6TYN3H.js +130 -0
  178. package/dist/chunks/velin-drawer-DLL2GLT6.js +130 -0
  179. package/dist/chunks/velin-drawer-MJS6WCF7.js +130 -0
  180. package/dist/chunks/velin-dropdown-PLUIFA5M.js +172 -0
  181. package/dist/chunks/velin-email-N5B5ZYTE.js +90 -0
  182. package/dist/chunks/velin-email-NTM6DG3V.js +90 -0
  183. package/dist/chunks/velin-email-RBX6ZR4S.js +90 -0
  184. package/dist/chunks/velin-haptic-4QQTM3RK.js +50 -0
  185. package/dist/chunks/velin-icon-7M76DOPB.js +164 -0
  186. package/dist/chunks/velin-icon-KZO3IEHG.js +164 -0
  187. package/dist/chunks/velin-icon-WTFPG2DD.js +191 -0
  188. package/dist/chunks/velin-icon-ZTSKUOVN.js +193 -0
  189. package/dist/chunks/velin-lightbox-6E7CAATP.js +149 -0
  190. package/dist/chunks/velin-lightbox-I75U6JF4.js +140 -0
  191. package/dist/chunks/velin-lightbox-QOTB4PRL.js +140 -0
  192. package/dist/chunks/velin-lightbox-UCD6N7HF.js +140 -0
  193. package/dist/chunks/velin-live-dot-RJHX2DGY.js +74 -0
  194. package/dist/chunks/velin-live-dot-XHUZCIDZ.js +67 -0
  195. package/dist/chunks/velin-menubar-I426AED2.js +86 -0
  196. package/dist/chunks/velin-menubar-J66JXRWW.js +86 -0
  197. package/dist/chunks/velin-menubar-SFEXJE56.js +86 -0
  198. package/dist/chunks/velin-modal-2HOBXE6F.js +176 -0
  199. package/dist/chunks/velin-modal-5HYNNNUI.js +176 -0
  200. package/dist/chunks/velin-modal-AEOTZ67O.js +177 -0
  201. package/dist/chunks/velin-modal-GLI2XZZB.js +176 -0
  202. package/dist/chunks/velin-persist-DFPL3QP4.js +110 -0
  203. package/dist/chunks/velin-popover-EXINRIGJ.js +145 -0
  204. package/dist/chunks/velin-popover-HQW6Q2Y6.js +172 -0
  205. package/dist/chunks/velin-popover-OXX7MRZ6.js +145 -0
  206. package/dist/chunks/velin-popover-T72HK3DF.js +151 -0
  207. package/dist/chunks/velin-popover-YKCCROJG.js +145 -0
  208. package/dist/chunks/velin-progress-ring-E4YRLZHH.js +66 -0
  209. package/dist/chunks/velin-rating-6CDBI6DG.js +91 -0
  210. package/dist/chunks/velin-rating-N4DI2XNL.js +91 -0
  211. package/dist/chunks/velin-rating-XRQJV4LO.js +91 -0
  212. package/dist/chunks/velin-scroll-top-F2FCZNYD.js +58 -0
  213. package/dist/chunks/velin-scroll-top-OHYVVHHY.js +58 -0
  214. package/dist/chunks/velin-scrollspy-OKCT4FDV.js +50 -0
  215. package/dist/chunks/velin-search-2XRQFBCS.js +556 -0
  216. package/dist/chunks/velin-search-4YHJWYSS.js +556 -0
  217. package/dist/chunks/velin-search-7B4KJ6TX.js +557 -0
  218. package/dist/chunks/velin-search-LWHY23Q5.js +474 -0
  219. package/dist/chunks/velin-secure-field-6PV7RZDJ.js +95 -0
  220. package/dist/chunks/velin-secure-field-H7FSBUJW.js +95 -0
  221. package/dist/chunks/velin-secure-field-OFNAXCDP.js +95 -0
  222. package/dist/chunks/velin-segmented-control-EKL4E3BL.js +109 -0
  223. package/dist/chunks/velin-segmented-control-GYD5BIXQ.js +109 -0
  224. package/dist/chunks/velin-segmented-control-PQX6LKOJ.js +109 -0
  225. package/dist/chunks/velin-sheet-3OGI4HD7.js +119 -0
  226. package/dist/chunks/velin-sheet-OUK6572T.js +119 -0
  227. package/dist/chunks/velin-sheet-R2Y67X6H.js +119 -0
  228. package/dist/chunks/velin-sparkline-GVEANJVW.js +184 -0
  229. package/dist/chunks/velin-sparkline-KDA3GQAN.js +162 -0
  230. package/dist/chunks/velin-sparkline-XVTFC6GE.js +181 -0
  231. package/dist/chunks/velin-stepper-2ZIHLKGM.js +141 -0
  232. package/dist/chunks/velin-stepper-7ECRUYHD.js +148 -0
  233. package/dist/chunks/velin-stepper-FYEUEWE6.js +141 -0
  234. package/dist/chunks/velin-stepper-X54WGHDG.js +141 -0
  235. package/dist/chunks/velin-stepper-wc-QU3KRVQR.js +133 -0
  236. package/dist/chunks/velin-tabs-5UQ5ZVMV.js +138 -0
  237. package/dist/chunks/velin-theme-toggle-32J2CBNC.js +291 -0
  238. package/dist/chunks/velin-theme-toggle-BNNS7WLV.js +285 -0
  239. package/dist/chunks/velin-theme-toggle-NO7V4TWI.js +285 -0
  240. package/dist/chunks/velin-theme-toggle-QELCJM2Q.js +291 -0
  241. package/dist/chunks/velin-toast-OMMOA2DK.js +109 -0
  242. package/dist/chunks/velin-toast-RCZ4CSUC.js +109 -0
  243. package/dist/chunks/velin-toast-RSF2IHT3.js +113 -0
  244. package/dist/chunks/velin-toast-WEUBTJG6.js +109 -0
  245. package/dist/chunks/velin-tooltip-664IOHZA.js +112 -0
  246. package/dist/chunks/velin-tooltip-BDHGRTQB.js +112 -0
  247. package/dist/chunks/velin-tooltip-HVUOKNVX.js +112 -0
  248. package/dist/chunks/velin-tooltip-wc-LXDVT6DE.js +103 -0
  249. package/dist/chunks/worker-client-R6DBYPFT.js +46 -0
  250. package/dist/llms.test.txt +40 -0
  251. package/dist/llms.txt +40 -0
  252. package/dist/search-index.json +1773 -0
  253. package/dist/search-index.test.json +1773 -0
  254. package/dist/themes/brutalist.min.css +1 -1
  255. package/dist/themes/midnight.min.css +1 -1
  256. package/dist/themes/pastel.min.css +1 -1
  257. package/dist/themes/retro.min.css +1 -1
  258. package/dist/themes/sunset.min.css +1 -1
  259. package/dist/velin-agent.json +684 -0
  260. package/dist/velin-agent.test.json +684 -0
  261. package/dist/velinstyle-components.iife.js +7715 -3515
  262. package/dist/velinstyle-components.js +7087 -2859
  263. package/dist/velinstyle-components.min.js +196 -109
  264. package/dist/velinstyle.css +604 -65
  265. package/dist/velinstyle.d.ts +54 -0
  266. package/dist/velinstyle.min.css +1 -1
  267. package/examples/search-index.schema.json +33 -0
  268. package/package.json +56 -10
  269. package/src/a11y/authentication.css +37 -0
  270. package/src/a11y/consistent-help.css +22 -0
  271. package/src/a11y/dragging-alternatives.css +30 -0
  272. package/src/a11y/focus-appearance.css +20 -0
  273. package/src/a11y/high-contrast-aaa.css +16 -26
  274. package/src/a11y/skip-link.css +3 -1
  275. package/src/a11y/sr-only.css +1 -1
  276. package/src/base/reset.css +0 -36
  277. package/src/base/wc-placeholder.css +102 -0
  278. package/src/components/attributes.css +42 -0
  279. package/src/components/highlight.css +182 -0
  280. package/src/components/input-group.css +1 -2
  281. package/src/components/nav.css +2 -3
  282. package/src/components/search.css +95 -0
  283. package/src/components/stepper.css +2 -4
  284. package/src/components/timeline.css +1 -2
  285. package/src/components/tooltip.css +2 -4
  286. package/src/layout/container.css +5 -5
  287. package/src/layout/grid.css +8 -8
  288. package/src/layout/patterns.css +5 -5
  289. package/src/themes/brutalist.css +2 -11
  290. package/src/themes/corporate.css +0 -9
  291. package/src/themes/earth.css +0 -9
  292. package/src/themes/forest.css +0 -9
  293. package/src/themes/midnight.css +1 -10
  294. package/src/themes/neon.css +0 -9
  295. package/src/themes/nordic.css +0 -9
  296. package/src/themes/ocean.css +0 -9
  297. package/src/themes/pastel.css +1 -10
  298. package/src/themes/retro.css +2 -11
  299. package/src/themes/sharp.css +0 -7
  300. package/src/themes/soft.css +0 -7
  301. package/src/themes/sunset.css +1 -10
  302. package/src/tokens/color.css +45 -46
  303. package/src/tokens/fonts.css +10 -0
  304. package/src/tokens/typography.css +4 -5
  305. package/src/utilities/animation.css +2 -2
  306. package/src/utilities/display.css +3 -3
  307. package/src/utilities/divide.css +2 -6
  308. package/src/utilities/responsive.css +4 -4
  309. package/src/utilities/safe-area.css +1 -1
  310. package/src/utilities/scroll-animation.css +34 -0
  311. package/src/utilities/spacing.css +17 -8
  312. package/src/utilities/text.css +4 -1
  313. package/src/velinstyle.css +9 -0
@@ -0,0 +1,28 @@
1
+ /** @typedef {'keyword'|'identifier'|'string'|'comment'|'number'|'operator'|'punctuation'|'tag'|'attr-name'|'attr-value'|'builtin'|'regex'|'plain'} TokenType */
2
+
3
+ /**
4
+ * @typedef {object} Token
5
+ * @property {TokenType} type
6
+ * @property {string} value
7
+ */
8
+
9
+ /** @type {TokenType[]} */
10
+ export const TOKEN_TYPES = [
11
+ 'keyword',
12
+ 'identifier',
13
+ 'string',
14
+ 'comment',
15
+ 'number',
16
+ 'operator',
17
+ 'punctuation',
18
+ 'tag',
19
+ 'attr-name',
20
+ 'attr-value',
21
+ 'builtin',
22
+ 'regex',
23
+ 'plain',
24
+ ];
25
+
26
+ /**
27
+ * @typedef {(code: string) => Token[]} LexerFn
28
+ */
@@ -0,0 +1,293 @@
1
+ import { readFileSync, existsSync, readdirSync } from 'fs';
2
+ import { join, basename } from 'path';
3
+ import {
4
+ VELIN_META_MIME,
5
+ VELIN_AGENT_SCHEMA_VERSION,
6
+ AGENT_CONVENTIONS,
7
+ } from './schema.js';
8
+ import { relativizeDocsPathname } from '../search/docs-url.js';
9
+
10
+ /**
11
+ * @param {string} pkgRoot
12
+ */
13
+ export function readPackageMeta(pkgRoot) {
14
+ const pkgPath = join(pkgRoot, 'package.json');
15
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
16
+ const exports = Object.keys(pkg.exports || {});
17
+ return {
18
+ name: pkg.name,
19
+ version: pkg.version,
20
+ homepage: pkg.homepage,
21
+ repository: typeof pkg.repository === 'string' ? pkg.repository : pkg.repository?.url,
22
+ exports,
23
+ };
24
+ }
25
+
26
+ const LEGACY_WC_SUFFIX = '-wc';
27
+
28
+ /**
29
+ * @param {string} pkgRoot
30
+ * @returns {{ canonical: string[], legacyAliases: string[], loaderTags: string[] }}
31
+ */
32
+ export function collectComponentTags(pkgRoot) {
33
+ const loadersPath = join(pkgRoot, 'components', 'runtime', 'component-loaders.js');
34
+ if (existsSync(loadersPath)) {
35
+ const src = readFileSync(loadersPath, 'utf-8');
36
+ const loaderTags = [...new Set([...src.matchAll(/'((velin-[a-z0-9-]+))':/g)].map((m) => m[1]))].sort();
37
+ const legacyAliases = loaderTags.filter((t) => t.endsWith(LEGACY_WC_SUFFIX));
38
+ const canonical = loaderTags.filter((t) => !t.endsWith(LEGACY_WC_SUFFIX));
39
+ return { canonical, legacyAliases, loaderTags };
40
+ }
41
+ const dir = join(pkgRoot, 'components');
42
+ if (!existsSync(dir)) return { canonical: [], legacyAliases: [], loaderTags: [] };
43
+ const canonical = readdirSync(dir)
44
+ .filter((f) => f.startsWith('velin-') && f.endsWith('.js') && !f.includes('runtime'))
45
+ .map((f) => basename(f, '.js'))
46
+ .filter((t) => !t.endsWith(LEGACY_WC_SUFFIX))
47
+ .sort();
48
+ return { canonical, legacyAliases: [], loaderTags: canonical };
49
+ }
50
+
51
+ /**
52
+ * JS helpers shipped under components/ but not registered as custom elements.
53
+ * @param {string} pkgRoot
54
+ */
55
+ export function collectHelperModules(pkgRoot) {
56
+ const helpers = ['velin-flip', 'velin-haptic', 'velin-reveal'];
57
+ return helpers.filter((name) => existsSync(join(pkgRoot, 'components', `${name}.js`)));
58
+ }
59
+
60
+ /**
61
+ * @param {string} html
62
+ * @param {string} [sourcePath]
63
+ * @param {string} [pkgRoot]
64
+ */
65
+ export function buildPageMeta(html, sourcePath = '', pkgRoot = '.') {
66
+ const components = new Set();
67
+ const classes = new Set();
68
+ const attributes = new Set();
69
+
70
+ for (const m of html.matchAll(/<(velin-[a-z0-9-]+)/gi)) {
71
+ components.add(m[1].toLowerCase());
72
+ }
73
+ for (const m of html.matchAll(/\b(velin-[a-z0-9-]+)/gi)) {
74
+ classes.add(m[1].toLowerCase());
75
+ }
76
+ for (const m of html.matchAll(/\b(velin-[a-z]+)(?:\s*=|(?=\s|>))/gi)) {
77
+ const name = m[1].toLowerCase();
78
+ if (!name.includes('-wc')) attributes.add(name);
79
+ }
80
+
81
+ const intent = sourcePath.includes('components/')
82
+ ? 'component-doc'
83
+ : sourcePath.includes('guides/')
84
+ ? 'guide'
85
+ : 'page';
86
+
87
+ return {
88
+ version: readPackageMeta(pkgRoot).version || '0.9.0',
89
+ mime: VELIN_META_MIME,
90
+ page: {
91
+ intent,
92
+ source: sourcePath || undefined,
93
+ },
94
+ allowed: {
95
+ classesPrefix: ['velin-'],
96
+ components: [...components].sort(),
97
+ sampleClasses: [...classes].sort().slice(0, 48),
98
+ },
99
+ attributes: [...attributes].sort(),
100
+ a11y: [
101
+ 'Use semantic HTML inside Velin components.',
102
+ 'Provide labels for interactive controls.',
103
+ 'Respect prefers-reduced-motion; Velin motion attributes honor it.',
104
+ ],
105
+ };
106
+ }
107
+
108
+ /**
109
+ * @param {object} options
110
+ * @param {string} options.pkgRoot
111
+ * @param {string} [options.searchIndexPath]
112
+ * @param {import('./schema.js').VelinAgentBundle} [options.partial]
113
+ */
114
+ export async function buildAgentBundle(options) {
115
+ const { pkgRoot } = options;
116
+ const pkg = readPackageMeta(pkgRoot);
117
+ const { canonical, legacyAliases, loaderTags } = collectComponentTags(pkgRoot);
118
+ const helpers = collectHelperModules(pkgRoot);
119
+
120
+ let attributes = [];
121
+ try {
122
+ const { listRegisteredAttributes } = await import('../attributes/registry.js');
123
+ attributes = listRegisteredAttributes().sort();
124
+ } catch {
125
+ /* registry may need DOM in some environments */
126
+ }
127
+
128
+ let cliCommands = [];
129
+ try {
130
+ const { loadCliManifest } = await import('../../cli/docgen/extract-cli.js');
131
+ cliCommands = loadCliManifest().commands || [];
132
+ } catch {
133
+ const manifestPath = join(pkgRoot, 'cli', 'cli-manifest.json');
134
+ if (existsSync(manifestPath)) {
135
+ cliCommands = JSON.parse(readFileSync(manifestPath, 'utf-8')).commands || [];
136
+ }
137
+ }
138
+
139
+ let scannerRuleCount = 0;
140
+ let a11yContracts = { wcagLevel: 'AAA', components: {} };
141
+ try {
142
+ const { SCANNER_RULES } = await import('../../cli/scanner-rules-data.js');
143
+ scannerRuleCount = SCANNER_RULES.length;
144
+ } catch {
145
+ /* optional */
146
+ }
147
+ try {
148
+ const contractsPath = join(pkgRoot, 'core', 'a11y', 'component-contracts.json');
149
+ if (existsSync(contractsPath)) {
150
+ a11yContracts = JSON.parse(readFileSync(contractsPath, 'utf-8'));
151
+ }
152
+ } catch {
153
+ /* optional */
154
+ }
155
+
156
+ const searchPath = options.searchIndexPath || join(pkgRoot, 'dist', 'search-index.json');
157
+ let entryCount;
158
+ if (existsSync(searchPath)) {
159
+ try {
160
+ const idx = JSON.parse(readFileSync(searchPath, 'utf-8'));
161
+ entryCount = Array.isArray(idx.entries) ? idx.entries.length : undefined;
162
+ } catch {
163
+ /* ignore */
164
+ }
165
+ }
166
+
167
+ const bundle = {
168
+ schemaVersion: VELIN_AGENT_SCHEMA_VERSION,
169
+ mime: VELIN_META_MIME,
170
+ generatedAt: new Date().toISOString(),
171
+ framework: {
172
+ name: pkg.name,
173
+ version: pkg.version,
174
+ homepage: pkg.homepage,
175
+ repository: pkg.repository,
176
+ tagline:
177
+ 'VelinStyle is the WCAG 2.2 AAA CSS framework with native JavaScript runtime and Web Components.',
178
+ },
179
+ packageExports: pkg.exports,
180
+ release: {
181
+ breaking: [
182
+ 'Canonical tags: velin-tooltip, velin-stepper (legacy *-wc aliases deprecated).',
183
+ '.velin-mb-* is margin-bottom only; use .velin-my-* for block axis.',
184
+ ],
185
+ migration: [
186
+ 'Replace velin-tooltip-wc / velin-stepper-wc with velin-tooltip / velin-stepper.',
187
+ 'Point AI tools at velin-agent.json or docs/llms.txt for framework context.',
188
+ ],
189
+ },
190
+ components: {
191
+ tags: canonical,
192
+ count: canonical.length,
193
+ loaderTags,
194
+ loaderCount: loaderTags.length,
195
+ legacyAliases,
196
+ helpers,
197
+ },
198
+ attributes: { names: attributes, count: attributes.length },
199
+ cli: { commands: cliCommands },
200
+ tooling: {
201
+ categories: ['scan', 'prefix', 'scaffold', 'layout', 'perf', 'tokens', 'docs', 'search', 'meta'],
202
+ scannerRuleCount,
203
+ },
204
+ a11y: {
205
+ wcagLevel: a11yContracts.wcagLevel || 'AAA',
206
+ modules: 'src/a11y/*.css',
207
+ matrix: 'docs/generated/a11y/wcag22-aaa-matrix.md',
208
+ componentContracts: a11yContracts.components,
209
+ init: "import { initA11y } from '@birdapi/velinstyle/a11y'; initA11y();",
210
+ },
211
+ searchIndex: {
212
+ path: 'dist/search-index.json',
213
+ entryCount,
214
+ },
215
+ documentation: {
216
+ generated: 'docs/generated/',
217
+ guides: {
218
+ velinMeta: 'docs/guides/velin-meta.html',
219
+ velinSearch: 'docs/guides/velin-search.html',
220
+ syntaxHighlight: 'docs/guides/syntax-highlight.html',
221
+ promptScaffolding: 'docs/guides/prompt-scaffolding.html',
222
+ apiReference: 'docs/guides/api-reference.html',
223
+ },
224
+ agentFiles: {
225
+ json: 'dist/velin-agent.json',
226
+ llmsTxt: 'dist/llms.txt',
227
+ },
228
+ },
229
+ conventions: AGENT_CONVENTIONS,
230
+ ...options.partial,
231
+ };
232
+
233
+ return bundle;
234
+ }
235
+
236
+ /**
237
+ * @param {object} bundle
238
+ * @param {string} [baseUrl]
239
+ */
240
+ export function buildLlmsTxt(bundle, baseUrl = 'https://velinstyle.info') {
241
+ const tagline =
242
+ bundle.framework.tagline ||
243
+ 'VelinStyle is the WCAG 2.2 AAA CSS framework with native JavaScript runtime and Web Components.';
244
+ const lines = [
245
+ `# VelinStyle ${bundle.framework.version}`,
246
+ '',
247
+ `> ${tagline}`,
248
+ `> Full machine context: ${baseUrl}/dist/velin-agent.json`,
249
+ `> MIME: ${VELIN_META_MIME}`,
250
+ '',
251
+ '## Framework',
252
+ `- npm: ${bundle.framework.name}`,
253
+ `- ${tagline}`,
254
+ `- Components: ${bundle.components.count} canonical Web Components (\`velin-*\`); ${bundle.components.loaderCount ?? bundle.components.count} lazy-loader entries`,
255
+ `- HTML attributes: ${bundle.attributes.count} \`velin-*\` bridges`,
256
+ `- CLI: velinstyle (scan, scaffold, docs generate, search index, meta)`,
257
+ '',
258
+ '## Conventions',
259
+ ...bundle.conventions.map((c) => `- ${c}`),
260
+ '',
261
+ '## Key guides',
262
+ `- [Velin-Meta](${baseUrl}/docs/guides/velin-meta.html)`,
263
+ `- [VelinSearch](${baseUrl}/docs/guides/velin-search.html)`,
264
+ `- [Syntax highlighting](${baseUrl}/docs/guides/syntax-highlight.html)`,
265
+ `- [Prompt scaffolding](${baseUrl}/docs/guides/prompt-scaffolding.html)`,
266
+ `- [API reference (generated)](${baseUrl}/docs/guides/api-reference.html)`,
267
+ '',
268
+ '## Generated reference',
269
+ `- [Components index](${baseUrl}/docs/generated/components/)`,
270
+ `- [Tokens](${baseUrl}/docs/generated/tokens/)`,
271
+ `- [Utilities](${baseUrl}/docs/generated/utilities/)`,
272
+ `- [CLI commands](${baseUrl}/docs/generated/cli/commands.md)`,
273
+ '',
274
+ '## Usage for agents',
275
+ '```',
276
+ 'npx velinstyle meta',
277
+ 'npx velinstyle docs generate',
278
+ 'npx velinstyle search index',
279
+ '```',
280
+ '',
281
+ ];
282
+ return lines.join('\n');
283
+ }
284
+
285
+ /**
286
+ * Serialize page meta for embedding in HTML.
287
+ * @param {object} meta
288
+ */
289
+ export function serializePageMetaScript(meta) {
290
+ return `<script type="${VELIN_META_MIME}" id="velin-meta">\n${JSON.stringify(meta, null, 2)}\n</script>`;
291
+ }
292
+
293
+ export { relativizeDocsPathname };
@@ -0,0 +1,17 @@
1
+ export {
2
+ VELIN_META_MIME,
3
+ VELIN_AGENT_SCHEMA_VERSION,
4
+ DOC_ROOT_SEGMENTS,
5
+ AGENT_CONVENTIONS,
6
+ } from './schema.js';
7
+
8
+ export {
9
+ buildAgentBundle,
10
+ buildLlmsTxt,
11
+ buildPageMeta,
12
+ serializePageMetaScript,
13
+ readPackageMeta,
14
+ collectComponentTags,
15
+ collectHelperModules,
16
+ relativizeDocsPathname,
17
+ } from './build.js';
@@ -0,0 +1,49 @@
1
+ /** Velin-Meta MIME and JSON shape for agent consumption. */
2
+
3
+ export const VELIN_META_MIME = 'application/vnd.velinstyle.meta+json';
4
+
5
+ export const VELIN_AGENT_SCHEMA_VERSION = 1;
6
+
7
+ /** Top-level doc sections under /docs/ used to fix wrongly prefixed paths. */
8
+ export const DOC_ROOT_SEGMENTS = new Set([
9
+ 'getting-started',
10
+ 'extend',
11
+ 'guides',
12
+ 'utilities',
13
+ 'components',
14
+ 'forms',
15
+ 'layout',
16
+ 'content',
17
+ 'customize',
18
+ 'animations',
19
+ 'about',
20
+ 'helpers',
21
+ 'generated',
22
+ 'migration',
23
+ ]);
24
+
25
+ /**
26
+ * @typedef {Object} VelinAgentBundle
27
+ * @property {number} schemaVersion
28
+ * @property {string} mime
29
+ * @property {string} generatedAt
30
+ * @property {{ name: string, version: string, homepage?: string, repository?: string }} framework
31
+ * @property {string[]} packageExports
32
+ * @property {{ breaking?: string[], migration?: string[] }} release
33
+ * @property {{ tags: string[], count: number }} components
34
+ * @property {{ names: string[], count: number }} attributes
35
+ * @property {{ commands: object[] }} cli
36
+ * @property {{ categories: string[], scannerRuleCount: number }} tooling
37
+ * @property {{ path: string, entryCount?: number }} searchIndex
38
+ * @property {{ generated: string, guides: Record<string, string> }} documentation
39
+ * @property {string[]} conventions
40
+ */
41
+
42
+ export const AGENT_CONVENTIONS = [
43
+ 'Positioning: VelinStyle is the WCAG 2.2 AAA CSS framework with native JavaScript runtime and Web Components — not a JS-only library or a utility-only CSS kit.',
44
+ 'Use only velin-* utility classes and documented Web Components.',
45
+ 'Prefer data-velin-theme on <html> for theme switching.',
46
+ 'Run velinstyle scan on generated HTML before shipping.',
47
+ 'Do not put secrets, API keys, or raw emails in velin-meta or page meta.',
48
+ 'Resolve doc links against docs root (/docs/), not the current page folder.',
49
+ ];
@@ -0,0 +1,54 @@
1
+ export const VISIBLE_CLASS = 'velin-in-view';
2
+
3
+ const EFFECT_MAP = {
4
+ reveal: ['velin-animate-on-scroll'],
5
+ fade: ['velin-animate-on-scroll', 'velin-animate-on-scroll--fade'],
6
+ slide: ['velin-animate-on-scroll', 'velin-animate-on-scroll--slide-up'],
7
+ 'slide-up': ['velin-animate-on-scroll', 'velin-animate-on-scroll--slide-up'],
8
+ 'slide-down': ['velin-animate-on-scroll', 'velin-animate-on-scroll--slide-down'],
9
+ 'slide-left': ['velin-animate-on-scroll', 'velin-animate-on-scroll--slide-left'],
10
+ 'slide-right': ['velin-animate-on-scroll', 'velin-animate-on-scroll--slide-right'],
11
+ scale: ['velin-animate-on-scroll', 'velin-animate-on-scroll--scale'],
12
+ parallax: ['velin-parallax'],
13
+ 'parallax-slow': ['velin-parallax', 'velin-parallax--slow'],
14
+ hover: ['velin-animate-hover'],
15
+ 'hover-lift': ['velin-animate-hover'],
16
+ flip: ['velin-animate-scale-in'],
17
+ blur: ['velin-animate-fade-in'],
18
+ };
19
+
20
+ /**
21
+ * Apply motion effect classes from velin-* attribute values.
22
+ * @param {HTMLElement} el
23
+ * @param {Record<string, string>} attrs keyed by effect name
24
+ */
25
+ export function applyEffects(el, attrs = {}) {
26
+ const classes = new Set();
27
+ for (const [name, value] of Object.entries(attrs)) {
28
+ if (value === 'false' || value === 'off') continue;
29
+ const mapped = EFFECT_MAP[name];
30
+ if (mapped) mapped.forEach((c) => classes.add(c));
31
+ if (name === 'slide' && value && value !== 'true' && value !== '') {
32
+ const key = `slide-${value}`;
33
+ EFFECT_MAP[key]?.forEach((c) => classes.add(c));
34
+ }
35
+ }
36
+ classes.forEach((c) => el.classList.add(c));
37
+ if (!el.classList.contains('velin-animate-on-scroll') && attrs.reveal !== undefined) {
38
+ el.classList.add('velin-animate-on-scroll');
39
+ }
40
+ return [...classes];
41
+ }
42
+
43
+ export function markVisible(el) {
44
+ el.classList.add(VISIBLE_CLASS);
45
+ el.dataset.velinVisible = 'true';
46
+ }
47
+
48
+ export function prefersReducedMotion() {
49
+ return (
50
+ typeof window !== 'undefined' &&
51
+ window.matchMedia &&
52
+ window.matchMedia('(prefers-reduced-motion: reduce)').matches
53
+ );
54
+ }
@@ -0,0 +1,76 @@
1
+ import { observeInView, disconnectInViewObserver } from './scheduler.js';
2
+ import { applyEffects, markVisible, prefersReducedMotion, VISIBLE_CLASS } from './effects.js';
3
+ import { enhanceStagger } from './stagger.js';
4
+ import { bindSmoothScroll } from './scroll.js';
5
+
6
+ const MOTION_ATTRS = ['velin-reveal', 'velin-fade', 'velin-slide', 'velin-scale', 'velin-parallax', 'velin-hover'];
7
+
8
+ let teardownFns = [];
9
+
10
+ /**
11
+ * Initialize motion system: in-view reveals, stagger, smooth scroll anchors.
12
+ * @param {object} [options]
13
+ * @param {HTMLElement|Document} [options.root]
14
+ * @param {string} [options.selector]
15
+ */
16
+ export function initMotion(options = {}) {
17
+ const root = options.root || (typeof document !== 'undefined' ? document : null);
18
+ if (!root) return () => {};
19
+
20
+ const selector =
21
+ options.selector ||
22
+ [
23
+ '[velin-reveal]',
24
+ '[velin-fade]',
25
+ '[velin-slide]',
26
+ '[velin-scale]',
27
+ '[velin-parallax]',
28
+ '[velin-hover]',
29
+ '.velin-animate-on-scroll',
30
+ ].join(',');
31
+
32
+ const elements = root.querySelectorAll(selector);
33
+ const reduced = prefersReducedMotion();
34
+
35
+ for (const el of elements) {
36
+ if (el.dataset.velinMotionInit) continue;
37
+ el.dataset.velinMotionInit = '1';
38
+
39
+ const attrs = {};
40
+ for (const name of MOTION_ATTRS) {
41
+ if (el.hasAttribute(name)) attrs[name.replace('velin-', '')] = el.getAttribute(name) || 'true';
42
+ }
43
+ applyEffects(el, attrs);
44
+
45
+ if (reduced) {
46
+ markVisible(el);
47
+ continue;
48
+ }
49
+
50
+ const stop = observeInView(el, (node) => markVisible(node));
51
+ teardownFns.push(stop);
52
+ }
53
+
54
+ enhanceStagger(root);
55
+ bindSmoothScroll(root);
56
+
57
+ return () => {
58
+ teardownFns.forEach((fn) => fn());
59
+ teardownFns = [];
60
+ disconnectInViewObserver();
61
+ };
62
+ }
63
+
64
+ /** @deprecated use initMotion */
65
+ export function initReveal(options = {}) {
66
+ return initMotion({
67
+ root: typeof document !== 'undefined' ? document : null,
68
+ selector: options.selector || '.velin-animate-on-scroll',
69
+ });
70
+ }
71
+
72
+ export const velinMotion = { init: initMotion, observe: observeInView, markVisible, VISIBLE_CLASS };
73
+ export { observeInView, disconnectInViewObserver } from './scheduler.js';
74
+ export { applyEffects, markVisible, prefersReducedMotion, VISIBLE_CLASS } from './effects.js';
75
+ export { enhanceStagger, applyStagger } from './stagger.js';
76
+ export { smoothScrollTo, bindSmoothScroll } from './scroll.js';
@@ -0,0 +1,72 @@
1
+ const pending = new Set();
2
+ let rafId = 0;
3
+
4
+ export function scheduleInView(callback) {
5
+ pending.add(callback);
6
+ if (!rafId) {
7
+ rafId = requestAnimationFrame(() => {
8
+ rafId = 0;
9
+ const batch = [...pending];
10
+ pending.clear();
11
+ batch.forEach((fn) => fn());
12
+ });
13
+ }
14
+ }
15
+
16
+ let sharedObserver = null;
17
+ const observed = new WeakMap();
18
+
19
+ export function getInViewObserver(options = {}) {
20
+ if (typeof IntersectionObserver === 'undefined') return null;
21
+ if (!sharedObserver) {
22
+ sharedObserver = new IntersectionObserver(
23
+ (entries) => {
24
+ for (const entry of entries) {
25
+ if (!entry.isIntersecting) continue;
26
+ const cb = observed.get(entry.target);
27
+ if (cb) scheduleInView(() => cb(entry.target));
28
+ const once = entry.target.dataset.velinOnce !== 'false';
29
+ if (once) sharedObserver.unobserve(entry.target);
30
+ }
31
+ },
32
+ {
33
+ threshold: options.threshold ?? 0.1,
34
+ rootMargin: options.rootMargin ?? '0px 0px -40px 0px',
35
+ },
36
+ );
37
+ }
38
+ return sharedObserver;
39
+ }
40
+
41
+ export function observeInView(el, onVisible, opts = {}) {
42
+ const reduced =
43
+ typeof window !== 'undefined' &&
44
+ window.matchMedia &&
45
+ window.matchMedia('(prefers-reduced-motion: reduce)').matches;
46
+ const motionOff = el.closest('[data-velin-motion="off"]') || el.dataset.velinMotion === 'off';
47
+
48
+ if (reduced || motionOff) {
49
+ scheduleInView(() => onVisible(el, true));
50
+ return () => {};
51
+ }
52
+
53
+ const io = getInViewObserver(opts);
54
+ if (!io) {
55
+ scheduleInView(() => onVisible(el, true));
56
+ return () => {};
57
+ }
58
+
59
+ observed.set(el, onVisible);
60
+ io.observe(el);
61
+ return () => {
62
+ observed.delete(el);
63
+ io.unobserve(el);
64
+ };
65
+ }
66
+
67
+ export function disconnectInViewObserver() {
68
+ if (sharedObserver) {
69
+ sharedObserver.disconnect();
70
+ sharedObserver = null;
71
+ }
72
+ }
@@ -0,0 +1,32 @@
1
+ export function smoothScrollTo(target, options = {}) {
2
+ const reduced =
3
+ typeof window !== 'undefined' &&
4
+ window.matchMedia &&
5
+ window.matchMedia('(prefers-reduced-motion: reduce)').matches;
6
+ const el = typeof target === 'string' ? document.querySelector(target) : target;
7
+ if (!el) return;
8
+ el.scrollIntoView({
9
+ behavior: reduced || options.instant ? 'auto' : 'smooth',
10
+ block: options.block || 'start',
11
+ inline: options.inline || 'nearest',
12
+ });
13
+ if (el.tabIndex < 0 && !el.hasAttribute('tabindex')) {
14
+ el.setAttribute('tabindex', '-1');
15
+ }
16
+ el.focus({ preventScroll: true });
17
+ }
18
+
19
+ export function bindSmoothScroll(root = document) {
20
+ root.querySelectorAll('[velin-scroll]').forEach((link) => {
21
+ if (link.dataset.velinScrollBound) return;
22
+ link.dataset.velinScrollBound = '1';
23
+ link.addEventListener('click', (e) => {
24
+ const href = link.getAttribute('href');
25
+ if (!href || !href.startsWith('#')) return;
26
+ const target = document.querySelector(href);
27
+ if (!target) return;
28
+ e.preventDefault();
29
+ smoothScrollTo(target);
30
+ });
31
+ });
32
+ }
@@ -0,0 +1,24 @@
1
+ const STAGGER_ATTR = 'velin-stagger';
2
+
3
+ /**
4
+ * Apply stagger delay to direct children.
5
+ * @param {HTMLElement} listEl
6
+ * @param {string} [value] base delay ms or multiplier
7
+ */
8
+ export function applyStagger(listEl, value = 'true') {
9
+ const base = value === 'true' || value === '' ? 60 : parseInt(value, 10) || 60;
10
+ const children = [...listEl.children];
11
+ children.forEach((child, i) => {
12
+ child.style.setProperty('--velin-stagger-delay', `${i * base}ms`);
13
+ child.classList.add('velin-stagger-item');
14
+ });
15
+ listEl.classList.add('velin-stagger');
16
+ }
17
+
18
+ export function enhanceStagger(root = document) {
19
+ root.querySelectorAll(`[${STAGGER_ATTR}]`).forEach((el) => {
20
+ if (el.dataset.velinStaggerDone) return;
21
+ el.dataset.velinStaggerDone = '1';
22
+ applyStagger(el, el.getAttribute(STAGGER_ATTR) || 'true');
23
+ });
24
+ }