@birdapi/velinstyle 0.7.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 (336) hide show
  1. package/README.de.md +135 -224
  2. package/README.md +134 -223
  3. package/cli/blueprint.js +8 -0
  4. package/cli/blueprints/bottom-nav-mobile.html +17 -0
  5. package/cli/blueprints/cookie-consent.html +9 -0
  6. package/cli/blueprints/empty-state.html +5 -0
  7. package/cli/blueprints/filter-bar.html +15 -0
  8. package/cli/blueprints/notification-center.html +13 -0
  9. package/cli/blueprints/onboarding.html +23 -0
  10. package/cli/blueprints/pricing-table.html +20 -0
  11. package/cli/blueprints/settings-panel.html +20 -0
  12. package/cli/cli-manifest.json +97 -0
  13. package/cli/docgen/extract-a11y.js +89 -0
  14. package/cli/docgen/extract-attributes.js +95 -0
  15. package/cli/docgen/extract-cli.js +50 -0
  16. package/cli/docgen/extract-components.js +175 -0
  17. package/cli/docgen/extract-meta.js +32 -0
  18. package/cli/docgen/extract-rules.js +76 -0
  19. package/cli/docgen/extract-tokens.js +79 -0
  20. package/cli/docgen/extract-utilities.js +75 -0
  21. package/cli/docgen/markdown.js +43 -0
  22. package/cli/docs-generate.js +196 -0
  23. package/cli/index.js +236 -5
  24. package/cli/layout-audit.js +325 -0
  25. package/cli/meta.js +97 -0
  26. package/cli/perf-audit.js +174 -0
  27. package/cli/pii-scanner.js +134 -0
  28. package/cli/scaffold-recipes.json +70 -0
  29. package/cli/scaffold.js +155 -0
  30. package/cli/scanner-rules-data.js +62 -0
  31. package/cli/scanner.js +136 -1
  32. package/cli/search-index.js +163 -0
  33. package/cli/tokens-build.js +21 -1
  34. package/cli/tokens-validate.js +69 -0
  35. package/components/a11y-entry.js +42 -0
  36. package/components/a11y-utils.js +71 -0
  37. package/components/focus-manager.js +45 -8
  38. package/components/index.js +40 -11
  39. package/components/runtime/component-loaders.js +43 -0
  40. package/components/runtime/index.js +77 -0
  41. package/components/runtime-entry.js +10 -0
  42. package/components/sanitize.js +135 -28
  43. package/components/shadow-a11y-styles.js +18 -0
  44. package/components/velin-accordion.js +12 -0
  45. package/components/velin-announcer.js +35 -0
  46. package/components/velin-bottom-nav.js +108 -0
  47. package/components/velin-carousel.js +2 -2
  48. package/components/velin-code-block.js +142 -0
  49. package/components/velin-combobox.js +149 -0
  50. package/components/velin-command.js +142 -0
  51. package/components/velin-copy.js +18 -5
  52. package/components/velin-counter.js +155 -0
  53. package/components/velin-dialog.js +9 -1
  54. package/components/velin-email.js +94 -0
  55. package/components/velin-flip.js +220 -0
  56. package/components/velin-icon.js +99 -22
  57. package/components/velin-lightbox.js +8 -3
  58. package/components/velin-live-dot.js +90 -0
  59. package/components/velin-menubar.js +83 -0
  60. package/components/velin-modal.js +6 -3
  61. package/components/velin-popover.js +34 -2
  62. package/components/velin-rating.js +91 -0
  63. package/components/velin-reveal.js +22 -0
  64. package/components/velin-scroll-top.js +1 -1
  65. package/components/velin-search.js +267 -0
  66. package/components/velin-secure-field.js +99 -0
  67. package/components/velin-segmented-control.js +108 -0
  68. package/components/velin-sheet.js +107 -0
  69. package/components/velin-sparkline.js +227 -0
  70. package/components/{velin-stepper-wc.js → velin-stepper.js} +37 -8
  71. package/components/velin-theme-toggle.js +284 -60
  72. package/components/velin-toast.js +4 -0
  73. package/components/{velin-tooltip-wc.js → velin-tooltip.js} +22 -3
  74. package/core/a11y/component-contracts.json +221 -0
  75. package/core/attributes/index.js +6 -0
  76. package/core/attributes/registry.js +268 -0
  77. package/core/highlight/highlight.js +114 -0
  78. package/core/highlight/index.js +29 -0
  79. package/core/highlight/languages/_utils.js +52 -0
  80. package/core/highlight/languages/blade.js +16 -0
  81. package/core/highlight/languages/css.js +26 -0
  82. package/core/highlight/languages/html.js +17 -0
  83. package/core/highlight/languages/js.js +58 -0
  84. package/core/highlight/languages/json.js +14 -0
  85. package/core/highlight/languages/markdown.js +16 -0
  86. package/core/highlight/languages/php.js +39 -0
  87. package/core/highlight/languages/plain.js +7 -0
  88. package/core/highlight/languages/shell.js +33 -0
  89. package/core/highlight/languages/sql.js +20 -0
  90. package/core/highlight/languages/typescript.js +28 -0
  91. package/core/highlight/observe.js +53 -0
  92. package/core/highlight/registry.js +107 -0
  93. package/core/highlight/render.js +35 -0
  94. package/core/highlight/types.js +28 -0
  95. package/core/meta/build.js +293 -0
  96. package/core/meta/index.js +17 -0
  97. package/core/meta/schema.js +49 -0
  98. package/core/motion/effects.js +54 -0
  99. package/core/motion/index.js +76 -0
  100. package/core/motion/scheduler.js +72 -0
  101. package/core/motion/scroll.js +32 -0
  102. package/core/motion/stagger.js +24 -0
  103. package/core/search/docs-url.js +96 -0
  104. package/core/search/engine.js +139 -0
  105. package/core/search/highlight.js +48 -0
  106. package/core/search/index.js +126 -0
  107. package/core/search/providers.js +36 -0
  108. package/core/search/types.js +61 -0
  109. package/core/search/worker-client.js +56 -0
  110. package/core/search/worker.js +20 -0
  111. package/dist/chunks/a11y-utils-IRC7LOPF.js +16 -0
  112. package/dist/chunks/attributes-3BZLI7XF.js +364 -0
  113. package/dist/chunks/attributes-4N5JP4CG.js +364 -0
  114. package/dist/chunks/attributes-5Q2WXGRC.js +374 -0
  115. package/dist/chunks/attributes-AIR7SVLK.js +364 -0
  116. package/dist/chunks/attributes-BGRN5XZO.js +364 -0
  117. package/dist/chunks/attributes-BVSQAYLR.js +364 -0
  118. package/dist/chunks/attributes-CDYFUY7Y.js +364 -0
  119. package/dist/chunks/attributes-JMYJZBPE.js +364 -0
  120. package/dist/chunks/attributes-R5JY3X4O.js +374 -0
  121. package/dist/chunks/attributes-STYCS3O5.js +391 -0
  122. package/dist/chunks/attributes-TNSPQTHX.js +374 -0
  123. package/dist/chunks/attributes-TPANLMLF.js +391 -0
  124. package/dist/chunks/blade-LIQLVKZQ.js +19 -0
  125. package/dist/chunks/browser-MRKYZPEH.js +1149 -0
  126. package/dist/chunks/chunk-2354NEBP.js +109 -0
  127. package/dist/chunks/chunk-2VNA7G7S.js +109 -0
  128. package/dist/chunks/chunk-42VVPW6N.js +132 -0
  129. package/dist/chunks/chunk-7FFAMRFV.js +44 -0
  130. package/dist/chunks/chunk-7MCGPHVC.js +69 -0
  131. package/dist/chunks/chunk-AQLRJSGG.js +109 -0
  132. package/dist/chunks/chunk-EWPSDMQT.js +109 -0
  133. package/dist/chunks/chunk-F7OLHTGX.js +22 -0
  134. package/dist/chunks/chunk-J472ERN2.js +242 -0
  135. package/dist/chunks/chunk-LA7264K4.js +85 -0
  136. package/dist/chunks/chunk-M5CHQVP6.js +61 -0
  137. package/dist/chunks/chunk-MKZP2TBH.js +89 -0
  138. package/dist/chunks/chunk-QTJJ3DPO.js +109 -0
  139. package/dist/chunks/chunk-RDE3QE7Z.js +89 -0
  140. package/dist/chunks/chunk-RSMRR27R.js +109 -0
  141. package/dist/chunks/chunk-RZQVWFHW.js +109 -0
  142. package/dist/chunks/chunk-SRL6EWHP.js +109 -0
  143. package/dist/chunks/chunk-U4XHMZ7D.js +109 -0
  144. package/dist/chunks/chunk-V5YIUA6G.js +109 -0
  145. package/dist/chunks/chunk-XIET2VSZ.js +109 -0
  146. package/dist/chunks/chunk-XYLJ2GCB.js +205 -0
  147. package/dist/chunks/chunk-Z4JYQ2XX.js +51 -0
  148. package/dist/chunks/chunk-ZPSPKUYD.js +109 -0
  149. package/dist/chunks/css-MQ5YU77P.js +28 -0
  150. package/dist/chunks/highlight-GJHHV4KM.js +37 -0
  151. package/dist/chunks/highlight-XTHRKBA3.js +37 -0
  152. package/dist/chunks/html-ZODC4DLQ.js +20 -0
  153. package/dist/chunks/js-MNSNYTJU.js +7 -0
  154. package/dist/chunks/json-VEM2HFH3.js +17 -0
  155. package/dist/chunks/markdown-E7OPGS3S.js +19 -0
  156. package/dist/chunks/php-MLL7T3LT.js +41 -0
  157. package/dist/chunks/plain-LJJDC5TN.js +8 -0
  158. package/dist/chunks/runtime-entry.js +14 -0
  159. package/dist/chunks/shell-QTRK4U4E.js +35 -0
  160. package/dist/chunks/sql-PPWLHGJ2.js +23 -0
  161. package/dist/chunks/typescript-JT3CCYWL.js +30 -0
  162. package/dist/chunks/velin-accordion-FBIPAEXG.js +105 -0
  163. package/dist/chunks/velin-accordion-QAQO7BI7.js +117 -0
  164. package/dist/chunks/velin-announcer-PVTXXCWR.js +33 -0
  165. package/dist/chunks/velin-bottom-nav-2N2TYWOF.js +86 -0
  166. package/dist/chunks/velin-bottom-nav-7GEMPIM6.js +86 -0
  167. package/dist/chunks/velin-bottom-nav-CTU6FFZV.js +101 -0
  168. package/dist/chunks/velin-bottom-nav-N3DFQR66.js +86 -0
  169. package/dist/chunks/velin-carousel-Y5VCOABZ.js +213 -0
  170. package/dist/chunks/velin-carousel-ZTBANFQQ.js +213 -0
  171. package/dist/chunks/velin-code-block-ASUBTAQV.js +119 -0
  172. package/dist/chunks/velin-code-block-CIAURDRJ.js +132 -0
  173. package/dist/chunks/velin-code-block-TSUKPY4C.js +123 -0
  174. package/dist/chunks/velin-code-block-Y6CM726Q.js +119 -0
  175. package/dist/chunks/velin-collapse-5XYBUIID.js +80 -0
  176. package/dist/chunks/velin-combobox-2KDTCQ7N.js +155 -0
  177. package/dist/chunks/velin-combobox-NXS4QB4R.js +155 -0
  178. package/dist/chunks/velin-combobox-UGA56HP3.js +155 -0
  179. package/dist/chunks/velin-command-CKDNO4BW.js +148 -0
  180. package/dist/chunks/velin-command-M7RNHUPR.js +136 -0
  181. package/dist/chunks/velin-command-ONKO2A3J.js +136 -0
  182. package/dist/chunks/velin-command-TMLSRGIU.js +136 -0
  183. package/dist/chunks/velin-copy-G2TZ5YBB.js +81 -0
  184. package/dist/chunks/velin-copy-NYDBOKXT.js +81 -0
  185. package/dist/chunks/velin-copy-T5KDTDXP.js +81 -0
  186. package/dist/chunks/velin-countdown-4ZVDGK4R.js +101 -0
  187. package/dist/chunks/velin-countdown-5XSTN3BH.js +101 -0
  188. package/dist/chunks/velin-countdown-7AIY66CU.js +101 -0
  189. package/dist/chunks/velin-counter-ISCTEAHI.js +118 -0
  190. package/dist/chunks/velin-counter-L5FYJF7A.js +121 -0
  191. package/dist/chunks/velin-dialog-D2GUHSCD.js +144 -0
  192. package/dist/chunks/velin-dialog-ELFOZIXZ.js +152 -0
  193. package/dist/chunks/velin-dialog-GTTZI564.js +147 -0
  194. package/dist/chunks/velin-dialog-IJLFDXAJ.js +144 -0
  195. package/dist/chunks/velin-dialog-TNS3WXMB.js +144 -0
  196. package/dist/chunks/velin-drawer-BE6TYN3H.js +130 -0
  197. package/dist/chunks/velin-drawer-DLL2GLT6.js +130 -0
  198. package/dist/chunks/velin-drawer-MJS6WCF7.js +130 -0
  199. package/dist/chunks/velin-dropdown-PLUIFA5M.js +172 -0
  200. package/dist/chunks/velin-email-N5B5ZYTE.js +90 -0
  201. package/dist/chunks/velin-email-NTM6DG3V.js +90 -0
  202. package/dist/chunks/velin-email-RBX6ZR4S.js +90 -0
  203. package/dist/chunks/velin-haptic-4QQTM3RK.js +50 -0
  204. package/dist/chunks/velin-icon-7M76DOPB.js +164 -0
  205. package/dist/chunks/velin-icon-KZO3IEHG.js +164 -0
  206. package/dist/chunks/velin-icon-WTFPG2DD.js +191 -0
  207. package/dist/chunks/velin-icon-ZTSKUOVN.js +193 -0
  208. package/dist/chunks/velin-lightbox-6E7CAATP.js +149 -0
  209. package/dist/chunks/velin-lightbox-I75U6JF4.js +140 -0
  210. package/dist/chunks/velin-lightbox-QOTB4PRL.js +140 -0
  211. package/dist/chunks/velin-lightbox-UCD6N7HF.js +140 -0
  212. package/dist/chunks/velin-live-dot-RJHX2DGY.js +74 -0
  213. package/dist/chunks/velin-live-dot-XHUZCIDZ.js +67 -0
  214. package/dist/chunks/velin-menubar-I426AED2.js +86 -0
  215. package/dist/chunks/velin-menubar-J66JXRWW.js +86 -0
  216. package/dist/chunks/velin-menubar-SFEXJE56.js +86 -0
  217. package/dist/chunks/velin-modal-2HOBXE6F.js +176 -0
  218. package/dist/chunks/velin-modal-5HYNNNUI.js +176 -0
  219. package/dist/chunks/velin-modal-AEOTZ67O.js +177 -0
  220. package/dist/chunks/velin-modal-GLI2XZZB.js +176 -0
  221. package/dist/chunks/velin-persist-DFPL3QP4.js +110 -0
  222. package/dist/chunks/velin-popover-EXINRIGJ.js +145 -0
  223. package/dist/chunks/velin-popover-HQW6Q2Y6.js +172 -0
  224. package/dist/chunks/velin-popover-OXX7MRZ6.js +145 -0
  225. package/dist/chunks/velin-popover-T72HK3DF.js +151 -0
  226. package/dist/chunks/velin-popover-YKCCROJG.js +145 -0
  227. package/dist/chunks/velin-progress-ring-E4YRLZHH.js +66 -0
  228. package/dist/chunks/velin-rating-6CDBI6DG.js +91 -0
  229. package/dist/chunks/velin-rating-N4DI2XNL.js +91 -0
  230. package/dist/chunks/velin-rating-XRQJV4LO.js +91 -0
  231. package/dist/chunks/velin-scroll-top-F2FCZNYD.js +58 -0
  232. package/dist/chunks/velin-scroll-top-OHYVVHHY.js +58 -0
  233. package/dist/chunks/velin-scrollspy-OKCT4FDV.js +50 -0
  234. package/dist/chunks/velin-search-2XRQFBCS.js +556 -0
  235. package/dist/chunks/velin-search-4YHJWYSS.js +556 -0
  236. package/dist/chunks/velin-search-7B4KJ6TX.js +557 -0
  237. package/dist/chunks/velin-search-LWHY23Q5.js +474 -0
  238. package/dist/chunks/velin-secure-field-6PV7RZDJ.js +95 -0
  239. package/dist/chunks/velin-secure-field-H7FSBUJW.js +95 -0
  240. package/dist/chunks/velin-secure-field-OFNAXCDP.js +95 -0
  241. package/dist/chunks/velin-segmented-control-EKL4E3BL.js +109 -0
  242. package/dist/chunks/velin-segmented-control-GYD5BIXQ.js +109 -0
  243. package/dist/chunks/velin-segmented-control-PQX6LKOJ.js +109 -0
  244. package/dist/chunks/velin-sheet-3OGI4HD7.js +119 -0
  245. package/dist/chunks/velin-sheet-OUK6572T.js +119 -0
  246. package/dist/chunks/velin-sheet-R2Y67X6H.js +119 -0
  247. package/dist/chunks/velin-sparkline-GVEANJVW.js +184 -0
  248. package/dist/chunks/velin-sparkline-KDA3GQAN.js +162 -0
  249. package/dist/chunks/velin-sparkline-XVTFC6GE.js +181 -0
  250. package/dist/chunks/velin-stepper-2ZIHLKGM.js +141 -0
  251. package/dist/chunks/velin-stepper-7ECRUYHD.js +148 -0
  252. package/dist/chunks/velin-stepper-FYEUEWE6.js +141 -0
  253. package/dist/chunks/velin-stepper-X54WGHDG.js +141 -0
  254. package/dist/chunks/velin-stepper-wc-QU3KRVQR.js +133 -0
  255. package/dist/chunks/velin-tabs-5UQ5ZVMV.js +138 -0
  256. package/dist/chunks/velin-theme-toggle-32J2CBNC.js +291 -0
  257. package/dist/chunks/velin-theme-toggle-BNNS7WLV.js +285 -0
  258. package/dist/chunks/velin-theme-toggle-NO7V4TWI.js +285 -0
  259. package/dist/chunks/velin-theme-toggle-QELCJM2Q.js +291 -0
  260. package/dist/chunks/velin-toast-OMMOA2DK.js +109 -0
  261. package/dist/chunks/velin-toast-RCZ4CSUC.js +109 -0
  262. package/dist/chunks/velin-toast-RSF2IHT3.js +113 -0
  263. package/dist/chunks/velin-toast-WEUBTJG6.js +109 -0
  264. package/dist/chunks/velin-tooltip-664IOHZA.js +112 -0
  265. package/dist/chunks/velin-tooltip-BDHGRTQB.js +112 -0
  266. package/dist/chunks/velin-tooltip-HVUOKNVX.js +112 -0
  267. package/dist/chunks/velin-tooltip-wc-LXDVT6DE.js +103 -0
  268. package/dist/chunks/worker-client-R6DBYPFT.js +46 -0
  269. package/dist/llms.test.txt +40 -0
  270. package/dist/llms.txt +40 -0
  271. package/dist/search-index.json +1773 -0
  272. package/dist/search-index.test.json +1773 -0
  273. package/dist/themes/brutalist.min.css +1 -1
  274. package/dist/themes/midnight.min.css +1 -1
  275. package/dist/themes/pastel.min.css +1 -1
  276. package/dist/themes/retro.min.css +1 -1
  277. package/dist/themes/sunset.min.css +1 -1
  278. package/dist/velin-agent.json +684 -0
  279. package/dist/velin-agent.test.json +684 -0
  280. package/dist/velinstyle-components.iife.js +7959 -2199
  281. package/dist/velinstyle-components.js +7982 -2174
  282. package/dist/velinstyle-components.min.js +521 -90
  283. package/dist/velinstyle.css +1290 -282
  284. package/dist/velinstyle.d.ts +54 -0
  285. package/dist/velinstyle.min.css +1 -1
  286. package/examples/search-index.schema.json +33 -0
  287. package/package.json +57 -10
  288. package/src/a11y/authentication.css +37 -0
  289. package/src/a11y/consistent-help.css +22 -0
  290. package/src/a11y/dragging-alternatives.css +30 -0
  291. package/src/a11y/focus-appearance.css +20 -0
  292. package/src/a11y/high-contrast-aaa.css +16 -26
  293. package/src/a11y/security.css +18 -0
  294. package/src/a11y/skip-link.css +3 -1
  295. package/src/a11y/sr-only.css +1 -1
  296. package/src/base/reset.css +0 -25
  297. package/src/base/wc-placeholder.css +102 -0
  298. package/src/components/attributes.css +42 -0
  299. package/src/components/highlight.css +182 -0
  300. package/src/components/input-group.css +1 -2
  301. package/src/components/nav.css +151 -151
  302. package/src/components/search.css +95 -0
  303. package/src/components/stepper.css +2 -4
  304. package/src/components/timeline.css +1 -2
  305. package/src/components/tooltip.css +2 -4
  306. package/src/layout/container.css +5 -5
  307. package/src/layout/grid.css +8 -8
  308. package/src/layout/patterns.css +5 -5
  309. package/src/themes/brutalist.css +2 -11
  310. package/src/themes/corporate.css +0 -9
  311. package/src/themes/earth.css +0 -9
  312. package/src/themes/forest.css +0 -9
  313. package/src/themes/midnight.css +1 -10
  314. package/src/themes/neon.css +0 -9
  315. package/src/themes/nordic.css +0 -9
  316. package/src/themes/ocean.css +0 -9
  317. package/src/themes/pastel.css +1 -10
  318. package/src/themes/retro.css +2 -11
  319. package/src/themes/sharp.css +0 -7
  320. package/src/themes/soft.css +0 -7
  321. package/src/themes/sunset.css +1 -10
  322. package/src/tokens/color.css +45 -46
  323. package/src/tokens/fonts.css +10 -0
  324. package/src/tokens/motion.css +7 -0
  325. package/src/tokens/typography.css +4 -5
  326. package/src/utilities/animation.css +99 -3
  327. package/src/utilities/chart-animation.css +101 -0
  328. package/src/utilities/display.css +3 -3
  329. package/src/utilities/divide.css +2 -6
  330. package/src/utilities/filter-effects.css +103 -0
  331. package/src/utilities/responsive.css +4 -4
  332. package/src/utilities/safe-area.css +39 -0
  333. package/src/utilities/scroll-animation.css +34 -0
  334. package/src/utilities/spacing.css +17 -8
  335. package/src/utilities/text.css +4 -1
  336. package/src/velinstyle.css +12 -0
@@ -0,0 +1,33 @@
1
+ /** @import { LexerFn } from '../types.js' */
2
+ import { tokenizeWithKeywords } from './_utils.js';
3
+
4
+ const KEYWORDS = {
5
+ if: 1,
6
+ then: 1,
7
+ else: 1,
8
+ fi: 1,
9
+ for: 1,
10
+ do: 1,
11
+ done: 1,
12
+ while: 1,
13
+ case: 1,
14
+ esac: 1,
15
+ function: 1,
16
+ return: 1,
17
+ export: 1,
18
+ local: 1,
19
+ };
20
+
21
+ const RULES = [
22
+ { type: 'comment', re: /#[^\n]*/y },
23
+ { type: 'string', re: /"(?:\\.|[^"\\])*"/y },
24
+ { type: 'string', re: /'[^']*'/y },
25
+ { type: 'number', re: /\b\d+\b/y },
26
+ { type: 'operator', re: /[|&<>]/y },
27
+ { type: 'punctuation', re: /[();]/y },
28
+ ];
29
+
30
+ /** @type {LexerFn} */
31
+ export default function lexShell(code) {
32
+ return tokenizeWithKeywords(code, KEYWORDS, RULES);
33
+ }
@@ -0,0 +1,20 @@
1
+ /** @import { LexerFn } from '../types.js' */
2
+ import { tokenize } from './_utils.js';
3
+
4
+ const RULES = [
5
+ { type: 'comment', re: /--[^\n]*/y },
6
+ { type: 'comment', re: /\/\*[\s\S]*?\*\//y },
7
+ { type: 'string', re: /'(?:''|[^'])*'/y },
8
+ { type: 'number', re: /\b\d+(?:\.\d+)?\b/y },
9
+ {
10
+ type: 'keyword',
11
+ re: /\b(?:SELECT|FROM|WHERE|INSERT|INTO|VALUES|UPDATE|SET|DELETE|JOIN|LEFT|RIGHT|INNER|OUTER|ON|AND|OR|NOT|NULL|AS|ORDER|BY|GROUP|HAVING|LIMIT|CREATE|TABLE|INDEX)\b/yi,
12
+ },
13
+ { type: 'operator', re: /[=<>!]+|,/y },
14
+ { type: 'punctuation', re: /[();]/y },
15
+ ];
16
+
17
+ /** @type {LexerFn} */
18
+ export default function lexSql(code) {
19
+ return tokenize(code, RULES);
20
+ }
@@ -0,0 +1,28 @@
1
+ /** @import { LexerFn } from '../types.js' */
2
+ import lexJs from './js.js';
3
+
4
+ const TS_KEYWORDS = new Set([
5
+ 'type',
6
+ 'interface',
7
+ 'enum',
8
+ 'implements',
9
+ 'declare',
10
+ 'namespace',
11
+ 'readonly',
12
+ 'public',
13
+ 'private',
14
+ 'protected',
15
+ 'abstract',
16
+ 'as',
17
+ 'satisfies',
18
+ 'keyof',
19
+ ]);
20
+
21
+ /** @type {LexerFn} */
22
+ export default function lexTypeScript(code) {
23
+ return lexJs(code).map((t) =>
24
+ t.type === 'identifier' && TS_KEYWORDS.has(t.value)
25
+ ? { type: 'keyword', value: t.value }
26
+ : t,
27
+ );
28
+ }
@@ -0,0 +1,53 @@
1
+ import { highlightElement } from './highlight.js';
2
+ import { observeInView } from '../motion/scheduler.js';
3
+
4
+ /**
5
+ * Lazy-highlight code blocks when they enter the viewport.
6
+ * @param {ParentNode} [root]
7
+ * @param {object} [options]
8
+ * @param {string} [options.selector]
9
+ * @param {boolean} [options.immediate]
10
+ */
11
+ export function initHighlight(root = document, options = {}) {
12
+ if (typeof document === 'undefined') return () => {};
13
+
14
+ const selector =
15
+ options.selector ||
16
+ [
17
+ 'pre[velin-code]',
18
+ 'pre[language]',
19
+ 'pre[data-language]',
20
+ 'pre code[class*="language-"]',
21
+ 'velin-code-block pre',
22
+ '.velin-doc-example__code pre',
23
+ ].join(',');
24
+
25
+ const nodes = root.querySelectorAll(selector);
26
+ const teardowns = [];
27
+
28
+ const reduced =
29
+ typeof matchMedia !== 'undefined' &&
30
+ matchMedia('(prefers-reduced-motion: reduce)').matches;
31
+
32
+ for (const node of nodes) {
33
+ const pre = node.tagName === 'PRE' ? node : node.closest('pre');
34
+ if (!pre || pre.dataset.velinObserve === '1') continue;
35
+ pre.dataset.velinObserve = '1';
36
+
37
+ if (reduced || options.immediate) {
38
+ void highlightElement(pre);
39
+ continue;
40
+ }
41
+
42
+ pre.classList.add('velin-syntax-pending');
43
+ const stop = observeInView(pre, async (el) => {
44
+ await highlightElement(el);
45
+ });
46
+ teardowns.push(stop);
47
+ }
48
+
49
+ return () => teardowns.forEach((fn) => fn());
50
+ }
51
+
52
+ /** @deprecated alias */
53
+ export const observeCodeBlocks = initHighlight;
@@ -0,0 +1,107 @@
1
+ /** @import { LexerFn } from './types.js' */
2
+
3
+ /** @type {Map<string, LexerFn>} */
4
+ const languages = new Map();
5
+
6
+ /** @type {Map<string, Promise<LexerFn>>} */
7
+ const loading = new Map();
8
+
9
+ const LAZY_LOADERS = {
10
+ js: () => import('./languages/js.js'),
11
+ javascript: () => import('./languages/js.js'),
12
+ ts: () => import('./languages/typescript.js'),
13
+ typescript: () => import('./languages/typescript.js'),
14
+ html: () => import('./languages/html.js'),
15
+ xml: () => import('./languages/html.js'),
16
+ css: () => import('./languages/css.js'),
17
+ json: () => import('./languages/json.js'),
18
+ md: () => import('./languages/markdown.js'),
19
+ markdown: () => import('./languages/markdown.js'),
20
+ shell: () => import('./languages/shell.js'),
21
+ bash: () => import('./languages/shell.js'),
22
+ sh: () => import('./languages/shell.js'),
23
+ sql: () => import('./languages/sql.js'),
24
+ text: () => import('./languages/plain.js'),
25
+ plain: () => import('./languages/plain.js'),
26
+ txt: () => import('./languages/plain.js'),
27
+ markup: () => import('./languages/html.js'),
28
+ console: () => import('./languages/plain.js'),
29
+ php: () => import('./languages/php.js'),
30
+ blade: () => import('./languages/blade.js'),
31
+ };
32
+
33
+ /** @param {string} name */
34
+ export function normalizeLanguage(name) {
35
+ const n = (name || '').trim().toLowerCase();
36
+ if (!n) return '';
37
+ if (n.startsWith('language-')) return normalizeLanguage(n.slice(9));
38
+ const map = {
39
+ javascript: 'js',
40
+ jsx: 'js',
41
+ typescript: 'ts',
42
+ tsx: 'ts',
43
+ markup: 'html',
44
+ xml: 'html',
45
+ svg: 'html',
46
+ bash: 'shell',
47
+ sh: 'shell',
48
+ zsh: 'shell',
49
+ md: 'markdown',
50
+ plaintext: 'text',
51
+ 'plain-text': 'text',
52
+ yml: 'text',
53
+ yaml: 'text',
54
+ toml: 'text',
55
+ ini: 'text',
56
+ php8: 'php',
57
+ };
58
+ return map[n] || n;
59
+ }
60
+
61
+ /**
62
+ * @param {string} name
63
+ * @param {LexerFn} lexerFn
64
+ */
65
+ export function registerLanguage(name, lexerFn) {
66
+ languages.set(normalizeLanguage(name), lexerFn);
67
+ }
68
+
69
+ /**
70
+ * @param {string} name
71
+ * @returns {LexerFn|undefined}
72
+ */
73
+ export function getLanguage(name) {
74
+ return languages.get(normalizeLanguage(name));
75
+ }
76
+
77
+ /**
78
+ * @param {string} name
79
+ * @returns {Promise<LexerFn|undefined>}
80
+ */
81
+ export async function lazyLoadLanguage(name) {
82
+ const key = normalizeLanguage(name);
83
+ if (!key) return undefined;
84
+ if (languages.has(key)) return languages.get(key);
85
+ if (loading.has(key)) return loading.get(key);
86
+
87
+ const loader = LAZY_LOADERS[key];
88
+ if (!loader) return undefined;
89
+
90
+ const p = loader().then((mod) => {
91
+ const fn = mod.default;
92
+ languages.set(key, fn);
93
+ loading.delete(key);
94
+ return fn;
95
+ });
96
+ loading.set(key, p);
97
+ return p;
98
+ }
99
+
100
+ /** @returns {string[]} */
101
+ export function listLanguages() {
102
+ return [...new Set([...languages.keys(), ...Object.keys(LAZY_LOADERS)])];
103
+ }
104
+
105
+ // Eager-register JS for zero-config demos
106
+ import lexJs from './languages/js.js';
107
+ registerLanguage('js', lexJs);
@@ -0,0 +1,35 @@
1
+ /** @import { Token } from './types.js' */
2
+
3
+ const ESC = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;' };
4
+
5
+ /**
6
+ * @param {string} s
7
+ */
8
+ export function escapeHtml(s) {
9
+ return s.replace(/[&<>"]/g, (c) => ESC[c] || c);
10
+ }
11
+
12
+ /**
13
+ * @param {Token[]} tokens
14
+ * @returns {string}
15
+ */
16
+ export function renderTokens(tokens) {
17
+ return tokens
18
+ .map((t) => {
19
+ const type = t.type === 'plain' ? '' : t.type;
20
+ const cls = type ? `velin-token velin-token--${type}` : 'velin-token';
21
+ return `<span class="${cls}">${escapeHtml(t.value)}</span>`;
22
+ })
23
+ .join('');
24
+ }
25
+
26
+ /**
27
+ * @param {HTMLElement} codeEl
28
+ * @param {Token[]} tokens
29
+ */
30
+ export function applyHighlight(codeEl, tokens) {
31
+ codeEl.innerHTML = renderTokens(tokens);
32
+ codeEl.classList.add('velin-syntax-ready');
33
+ codeEl.closest('pre')?.classList.add('velin-syntax-ready');
34
+ codeEl.closest('.velin-code-block')?.classList.add('velin-syntax-ready');
35
+ }
@@ -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
+ ];