@velarscript/web 0.30.1 → 0.32.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 (385) hide show
  1. package/README.md +1 -1
  2. package/dist/analysis/calls/intrinsics/config.d.ts +10 -0
  3. package/dist/analysis/calls/intrinsics/config.d.ts.map +1 -0
  4. package/dist/analysis/calls/intrinsics/config.js +19 -0
  5. package/dist/analysis/calls/intrinsics/config.js.map +1 -0
  6. package/dist/analysis/calls/intrinsics/forms.d.ts +10 -0
  7. package/dist/analysis/calls/intrinsics/forms.d.ts.map +1 -0
  8. package/dist/analysis/calls/intrinsics/forms.js +38 -0
  9. package/dist/analysis/calls/intrinsics/forms.js.map +1 -0
  10. package/dist/analysis/calls/intrinsics/http.d.ts +10 -0
  11. package/dist/analysis/calls/intrinsics/http.d.ts.map +1 -0
  12. package/dist/analysis/calls/intrinsics/http.js +37 -0
  13. package/dist/analysis/calls/intrinsics/http.js.map +1 -0
  14. package/dist/analysis/calls/intrinsics/reactive.d.ts +10 -0
  15. package/dist/analysis/calls/intrinsics/reactive.d.ts.map +1 -0
  16. package/dist/analysis/calls/intrinsics/reactive.js +30 -0
  17. package/dist/analysis/calls/intrinsics/reactive.js.map +1 -0
  18. package/dist/analysis/calls/intrinsics/storage.d.ts +12 -0
  19. package/dist/analysis/calls/intrinsics/storage.d.ts.map +1 -0
  20. package/dist/analysis/calls/intrinsics/storage.js +86 -0
  21. package/dist/analysis/calls/intrinsics/storage.js.map +1 -0
  22. package/dist/analysis/calls/intrinsics/web.d.ts +10 -0
  23. package/dist/analysis/calls/intrinsics/web.d.ts.map +1 -0
  24. package/dist/analysis/calls/intrinsics/web.js +100 -0
  25. package/dist/analysis/calls/intrinsics/web.js.map +1 -0
  26. package/dist/analysis/calls/intrinsics.d.ts +13 -0
  27. package/dist/analysis/calls/intrinsics.d.ts.map +1 -0
  28. package/dist/analysis/calls/intrinsics.js +31 -0
  29. package/dist/analysis/calls/intrinsics.js.map +1 -0
  30. package/dist/analysis/components/contracts.d.ts +19 -0
  31. package/dist/analysis/components/contracts.d.ts.map +1 -0
  32. package/dist/analysis/components/contracts.js +83 -0
  33. package/dist/analysis/components/contracts.js.map +1 -0
  34. package/dist/analysis/components/declaration.d.ts +4 -0
  35. package/dist/analysis/components/declaration.d.ts.map +1 -0
  36. package/dist/analysis/components/declaration.js +163 -0
  37. package/dist/analysis/components/declaration.js.map +1 -0
  38. package/dist/analysis/components/host.d.ts +61 -0
  39. package/dist/analysis/components/host.d.ts.map +1 -0
  40. package/dist/analysis/components/host.js +22 -0
  41. package/dist/analysis/components/host.js.map +1 -0
  42. package/dist/analysis/components/lifecycle.d.ts +22 -0
  43. package/dist/analysis/components/lifecycle.d.ts.map +1 -0
  44. package/dist/analysis/components/lifecycle.js +33 -0
  45. package/dist/analysis/components/lifecycle.js.map +1 -0
  46. package/dist/analysis/components/ownership.d.ts +74 -0
  47. package/dist/analysis/components/ownership.d.ts.map +1 -0
  48. package/dist/analysis/components/ownership.js +106 -0
  49. package/dist/analysis/components/ownership.js.map +1 -0
  50. package/dist/analysis/declarations.d.ts +99 -0
  51. package/dist/analysis/declarations.d.ts.map +1 -0
  52. package/dist/analysis/declarations.js +176 -0
  53. package/dist/analysis/declarations.js.map +1 -0
  54. package/dist/analysis/inference.d.ts +67 -0
  55. package/dist/analysis/inference.d.ts.map +1 -0
  56. package/dist/analysis/inference.js +236 -0
  57. package/dist/analysis/inference.js.map +1 -0
  58. package/dist/analysis/jsx/attributes.d.ts +103 -0
  59. package/dist/analysis/jsx/attributes.d.ts.map +1 -0
  60. package/dist/analysis/jsx/attributes.js +601 -0
  61. package/dist/analysis/jsx/attributes.js.map +1 -0
  62. package/dist/analysis/jsx/elements.d.ts +17 -0
  63. package/dist/analysis/jsx/elements.d.ts.map +1 -0
  64. package/dist/analysis/jsx/elements.js +213 -0
  65. package/dist/analysis/jsx/elements.js.map +1 -0
  66. package/dist/analysis/jsx/host.d.ts +61 -0
  67. package/dist/analysis/jsx/host.d.ts.map +1 -0
  68. package/dist/analysis/jsx/host.js +15 -0
  69. package/dist/analysis/jsx/host.js.map +1 -0
  70. package/dist/analysis/jsx/keys.d.ts +15 -0
  71. package/dist/analysis/jsx/keys.d.ts.map +1 -0
  72. package/dist/analysis/jsx/keys.js +67 -0
  73. package/dist/analysis/jsx/keys.js.map +1 -0
  74. package/dist/analysis/jsx/security.d.ts +29 -0
  75. package/dist/analysis/jsx/security.d.ts.map +1 -0
  76. package/dist/analysis/jsx/security.js +61 -0
  77. package/dist/analysis/jsx/security.js.map +1 -0
  78. package/dist/analysis/jsx-detection.d.ts +49 -0
  79. package/dist/analysis/jsx-detection.d.ts.map +1 -0
  80. package/dist/analysis/jsx-detection.js +196 -0
  81. package/dist/analysis/jsx-detection.js.map +1 -0
  82. package/dist/analysis/keyed-rebuild.d.ts +148 -0
  83. package/dist/analysis/keyed-rebuild.d.ts.map +1 -0
  84. package/dist/analysis/keyed-rebuild.js +299 -0
  85. package/dist/analysis/keyed-rebuild.js.map +1 -0
  86. package/dist/analysis/keyframes-analysis.d.ts +6 -0
  87. package/dist/analysis/keyframes-analysis.d.ts.map +1 -0
  88. package/dist/analysis/keyframes-analysis.js +79 -0
  89. package/dist/analysis/keyframes-analysis.js.map +1 -0
  90. package/dist/analysis/look/builders.d.ts +29 -0
  91. package/dist/analysis/look/builders.d.ts.map +1 -0
  92. package/dist/analysis/look/builders.js +168 -0
  93. package/dist/analysis/look/builders.js.map +1 -0
  94. package/dist/analysis/look/conditions.d.ts +13 -0
  95. package/dist/analysis/look/conditions.d.ts.map +1 -0
  96. package/dist/analysis/look/conditions.js +84 -0
  97. package/dist/analysis/look/conditions.js.map +1 -0
  98. package/dist/analysis/look/edits.d.ts +25 -0
  99. package/dist/analysis/look/edits.d.ts.map +1 -0
  100. package/dist/analysis/look/edits.js +57 -0
  101. package/dist/analysis/look/edits.js.map +1 -0
  102. package/dist/analysis/look/entries.d.ts +56 -0
  103. package/dist/analysis/look/entries.d.ts.map +1 -0
  104. package/dist/analysis/look/entries.js +223 -0
  105. package/dist/analysis/look/entries.js.map +1 -0
  106. package/dist/analysis/look/host.d.ts +47 -0
  107. package/dist/analysis/look/host.d.ts.map +1 -0
  108. package/dist/analysis/look/host.js +16 -0
  109. package/dist/analysis/look/host.js.map +1 -0
  110. package/dist/analysis/look/tokens.d.ts +75 -0
  111. package/dist/analysis/look/tokens.d.ts.map +1 -0
  112. package/dist/analysis/look/tokens.js +151 -0
  113. package/dist/analysis/look/tokens.js.map +1 -0
  114. package/dist/analysis/look/values.d.ts +45 -0
  115. package/dist/analysis/look/values.d.ts.map +1 -0
  116. package/dist/analysis/look/values.js +148 -0
  117. package/dist/analysis/look/values.js.map +1 -0
  118. package/dist/analysis/look-conditions.d.ts +47 -0
  119. package/dist/analysis/look-conditions.d.ts.map +1 -0
  120. package/dist/analysis/look-conditions.js +157 -0
  121. package/dist/analysis/look-conditions.js.map +1 -0
  122. package/dist/analysis/look-sites.d.ts +54 -0
  123. package/dist/analysis/look-sites.d.ts.map +1 -0
  124. package/dist/analysis/look-sites.js +104 -0
  125. package/dist/analysis/look-sites.js.map +1 -0
  126. package/dist/analysis/look-vocabulary-guidance.d.ts +76 -0
  127. package/dist/analysis/look-vocabulary-guidance.d.ts.map +1 -0
  128. package/dist/analysis/look-vocabulary-guidance.js +338 -0
  129. package/dist/analysis/look-vocabulary-guidance.js.map +1 -0
  130. package/dist/analysis/media-conditions.d.ts +33 -0
  131. package/dist/analysis/media-conditions.d.ts.map +1 -0
  132. package/dist/analysis/media-conditions.js +92 -0
  133. package/dist/analysis/media-conditions.js.map +1 -0
  134. package/dist/analysis/program-passes.d.ts +106 -0
  135. package/dist/analysis/program-passes.d.ts.map +1 -0
  136. package/dist/analysis/program-passes.js +149 -0
  137. package/dist/analysis/program-passes.js.map +1 -0
  138. package/dist/analysis/reactivity/bindings.d.ts +37 -0
  139. package/dist/analysis/reactivity/bindings.d.ts.map +1 -0
  140. package/dist/analysis/reactivity/bindings.js +88 -0
  141. package/dist/analysis/reactivity/bindings.js.map +1 -0
  142. package/dist/analysis/reactivity/derived.d.ts +39 -0
  143. package/dist/analysis/reactivity/derived.d.ts.map +1 -0
  144. package/dist/analysis/reactivity/derived.js +80 -0
  145. package/dist/analysis/reactivity/derived.js.map +1 -0
  146. package/dist/analysis/reactivity/host.d.ts +38 -0
  147. package/dist/analysis/reactivity/host.d.ts.map +1 -0
  148. package/dist/analysis/reactivity/host.js +14 -0
  149. package/dist/analysis/reactivity/host.js.map +1 -0
  150. package/dist/analysis/reactivity/retired-accessors.d.ts +82 -0
  151. package/dist/analysis/reactivity/retired-accessors.d.ts.map +1 -0
  152. package/dist/analysis/reactivity/retired-accessors.js +118 -0
  153. package/dist/analysis/reactivity/retired-accessors.js.map +1 -0
  154. package/dist/analysis/renderable.d.ts +47 -0
  155. package/dist/analysis/renderable.d.ts.map +1 -0
  156. package/dist/analysis/renderable.js +105 -0
  157. package/dist/analysis/renderable.js.map +1 -0
  158. package/dist/analysis/routes.d.ts +64 -0
  159. package/dist/analysis/routes.d.ts.map +1 -0
  160. package/dist/analysis/routes.js +182 -0
  161. package/dist/analysis/routes.js.map +1 -0
  162. package/dist/analysis/url-attributes.d.ts +12 -0
  163. package/dist/analysis/url-attributes.d.ts.map +1 -0
  164. package/dist/analysis/url-attributes.js +48 -0
  165. package/dist/analysis/url-attributes.js.map +1 -0
  166. package/dist/analysis/watch-cycles.d.ts +102 -0
  167. package/dist/analysis/watch-cycles.d.ts.map +1 -1
  168. package/dist/analysis/watch-cycles.js +240 -1
  169. package/dist/analysis/watch-cycles.js.map +1 -1
  170. package/dist/analysis/watch-subject.d.ts +45 -0
  171. package/dist/analysis/watch-subject.d.ts.map +1 -0
  172. package/dist/analysis/watch-subject.js +272 -0
  173. package/dist/analysis/watch-subject.js.map +1 -0
  174. package/dist/analysis/web-types.d.ts +27 -0
  175. package/dist/analysis/web-types.d.ts.map +1 -0
  176. package/dist/analysis/web-types.js +170 -0
  177. package/dist/analysis/web-types.js.map +1 -0
  178. package/dist/analyzer.d.ts +18 -617
  179. package/dist/analyzer.d.ts.map +1 -1
  180. package/dist/analyzer.js +208 -4853
  181. package/dist/analyzer.js.map +1 -1
  182. package/dist/compiler.d.ts +20 -0
  183. package/dist/compiler.d.ts.map +1 -1
  184. package/dist/compiler.js +29 -864
  185. package/dist/compiler.js.map +1 -1
  186. package/dist/documentation.d.ts +28 -0
  187. package/dist/documentation.d.ts.map +1 -0
  188. package/dist/documentation.js +67 -0
  189. package/dist/documentation.js.map +1 -0
  190. package/dist/editor/completions.d.ts +12 -0
  191. package/dist/editor/completions.d.ts.map +1 -0
  192. package/dist/editor/completions.js +6 -0
  193. package/dist/editor/completions.js.map +1 -0
  194. package/dist/editor/jsx-completion.d.ts +12 -0
  195. package/dist/editor/jsx-completion.d.ts.map +1 -0
  196. package/dist/editor/jsx-completion.js +137 -0
  197. package/dist/editor/jsx-completion.js.map +1 -0
  198. package/dist/editor/look-completion.d.ts +29 -0
  199. package/dist/editor/look-completion.d.ts.map +1 -0
  200. package/dist/editor/look-completion.js +159 -0
  201. package/dist/editor/look-completion.js.map +1 -0
  202. package/dist/editor.d.ts.map +1 -1
  203. package/dist/editor.js +12 -288
  204. package/dist/editor.js.map +1 -1
  205. package/dist/emit/components.d.ts +33 -0
  206. package/dist/emit/components.d.ts.map +1 -0
  207. package/dist/emit/components.js +135 -0
  208. package/dist/emit/components.js.map +1 -0
  209. package/dist/emit/jsx.d.ts +57 -0
  210. package/dist/emit/jsx.d.ts.map +1 -0
  211. package/dist/emit/jsx.js +384 -0
  212. package/dist/emit/jsx.js.map +1 -0
  213. package/dist/emit/look-css.d.ts +44 -0
  214. package/dist/emit/look-css.d.ts.map +1 -0
  215. package/dist/emit/look-css.js +177 -0
  216. package/dist/emit/look-css.js.map +1 -0
  217. package/dist/emit/look.d.ts +39 -0
  218. package/dist/emit/look.d.ts.map +1 -0
  219. package/dist/emit/look.js +218 -0
  220. package/dist/emit/look.js.map +1 -0
  221. package/dist/emit/runtime-imports.d.ts +40 -0
  222. package/dist/emit/runtime-imports.d.ts.map +1 -0
  223. package/dist/emit/runtime-imports.js +184 -0
  224. package/dist/emit/runtime-imports.js.map +1 -0
  225. package/dist/emitter.d.ts +15 -68
  226. package/dist/emitter.d.ts.map +1 -1
  227. package/dist/emitter.js +79 -1008
  228. package/dist/emitter.js.map +1 -1
  229. package/dist/look/animation.d.ts +7 -0
  230. package/dist/look/animation.d.ts.map +1 -0
  231. package/dist/look/animation.js +13 -0
  232. package/dist/look/animation.js.map +1 -0
  233. package/dist/look/builders.d.ts +35 -0
  234. package/dist/look/builders.d.ts.map +1 -0
  235. package/dist/look/builders.js +74 -0
  236. package/dist/look/builders.js.map +1 -0
  237. package/dist/look/css-functions.d.ts +28 -0
  238. package/dist/look/css-functions.d.ts.map +1 -0
  239. package/dist/look/css-functions.js +54 -0
  240. package/dist/look/css-functions.js.map +1 -0
  241. package/dist/look/keyword-sets.d.ts +41 -0
  242. package/dist/look/keyword-sets.d.ts.map +1 -0
  243. package/dist/look/keyword-sets.js +117 -0
  244. package/dist/look/keyword-sets.js.map +1 -0
  245. package/dist/look/keywords.d.ts +55 -0
  246. package/dist/look/keywords.d.ts.map +1 -0
  247. package/dist/look/keywords.js +387 -0
  248. package/dist/look/keywords.js.map +1 -0
  249. package/dist/look/media.d.ts +19 -0
  250. package/dist/look/media.d.ts.map +1 -0
  251. package/dist/look/media.js +27 -0
  252. package/dist/look/media.js.map +1 -0
  253. package/dist/look/naming.d.ts +9 -0
  254. package/dist/look/naming.d.ts.map +1 -0
  255. package/dist/look/naming.js +45 -0
  256. package/dist/look/naming.js.map +1 -0
  257. package/dist/look/properties.d.ts +16 -0
  258. package/dist/look/properties.d.ts.map +1 -0
  259. package/dist/look/properties.js +52 -0
  260. package/dist/look/properties.js.map +1 -0
  261. package/dist/look/shorthands.d.ts +25 -0
  262. package/dist/look/shorthands.d.ts.map +1 -0
  263. package/dist/look/shorthands.js +130 -0
  264. package/dist/look/shorthands.js.map +1 -0
  265. package/dist/look/tokens.d.ts +38 -0
  266. package/dist/look/tokens.d.ts.map +1 -0
  267. package/dist/look/tokens.js +59 -0
  268. package/dist/look/tokens.js.map +1 -0
  269. package/dist/look/units.d.ts +24 -0
  270. package/dist/look/units.d.ts.map +1 -0
  271. package/dist/look/units.js +33 -0
  272. package/dist/look/units.js.map +1 -0
  273. package/dist/look.d.ts +32 -227
  274. package/dist/look.d.ts.map +1 -1
  275. package/dist/look.js +28 -933
  276. package/dist/look.js.map +1 -1
  277. package/dist/module-roster.d.ts +16 -0
  278. package/dist/module-roster.d.ts.map +1 -0
  279. package/dist/module-roster.js +28 -0
  280. package/dist/module-roster.js.map +1 -0
  281. package/dist/modules/app.d.ts +9 -0
  282. package/dist/modules/app.d.ts.map +1 -0
  283. package/dist/modules/app.js +20 -0
  284. package/dist/modules/app.js.map +1 -0
  285. package/dist/modules/browser-test.d.ts +9 -0
  286. package/dist/modules/browser-test.d.ts.map +1 -0
  287. package/dist/modules/browser-test.js +67 -0
  288. package/dist/modules/browser-test.js.map +1 -0
  289. package/dist/modules/browser.d.ts +10 -0
  290. package/dist/modules/browser.d.ts.map +1 -0
  291. package/dist/modules/browser.js +89 -0
  292. package/dist/modules/browser.js.map +1 -0
  293. package/dist/modules/config.d.ts +9 -0
  294. package/dist/modules/config.d.ts.map +1 -0
  295. package/dist/modules/config.js +14 -0
  296. package/dist/modules/config.js.map +1 -0
  297. package/dist/modules/files.d.ts +9 -0
  298. package/dist/modules/files.d.ts.map +1 -0
  299. package/dist/modules/files.js +16 -0
  300. package/dist/modules/files.js.map +1 -0
  301. package/dist/modules/forms.d.ts +9 -0
  302. package/dist/modules/forms.d.ts.map +1 -0
  303. package/dist/modules/forms.js +26 -0
  304. package/dist/modules/forms.js.map +1 -0
  305. package/dist/modules/http.d.ts +9 -0
  306. package/dist/modules/http.d.ts.map +1 -0
  307. package/dist/modules/http.js +127 -0
  308. package/dist/modules/http.js.map +1 -0
  309. package/dist/modules/look.d.ts +9 -0
  310. package/dist/modules/look.d.ts.map +1 -0
  311. package/dist/modules/look.js +58 -0
  312. package/dist/modules/look.js.map +1 -0
  313. package/dist/modules/realtime.d.ts +9 -0
  314. package/dist/modules/realtime.d.ts.map +1 -0
  315. package/dist/modules/realtime.js +163 -0
  316. package/dist/modules/realtime.js.map +1 -0
  317. package/dist/modules/storage.d.ts +9 -0
  318. package/dist/modules/storage.d.ts.map +1 -0
  319. package/dist/modules/storage.js +59 -0
  320. package/dist/modules/storage.js.map +1 -0
  321. package/dist/modules/types.d.ts +78 -0
  322. package/dist/modules/types.d.ts.map +1 -0
  323. package/dist/modules/types.js +154 -0
  324. package/dist/modules/types.js.map +1 -0
  325. package/dist/modules/web.d.ts +9 -0
  326. package/dist/modules/web.d.ts.map +1 -0
  327. package/dist/modules/web.js +63 -0
  328. package/dist/modules/web.js.map +1 -0
  329. package/dist/modules/websocket.d.ts +11 -0
  330. package/dist/modules/websocket.d.ts.map +1 -0
  331. package/dist/modules/websocket.js +75 -0
  332. package/dist/modules/websocket.js.map +1 -0
  333. package/dist/parser/expressions/jsx.d.ts +17 -0
  334. package/dist/parser/expressions/jsx.d.ts.map +1 -0
  335. package/dist/parser/expressions/jsx.js +43 -0
  336. package/dist/parser/expressions/jsx.js.map +1 -0
  337. package/dist/parser/expressions/keyframes.d.ts +15 -0
  338. package/dist/parser/expressions/keyframes.d.ts.map +1 -0
  339. package/dist/parser/expressions/keyframes.js +33 -0
  340. package/dist/parser/expressions/keyframes.js.map +1 -0
  341. package/dist/parser/expressions/look.d.ts +16 -0
  342. package/dist/parser/expressions/look.d.ts.map +1 -0
  343. package/dist/parser/expressions/look.js +37 -0
  344. package/dist/parser/expressions/look.js.map +1 -0
  345. package/dist/parser/expressions/visual-block.d.ts +17 -0
  346. package/dist/parser/expressions/visual-block.d.ts.map +1 -0
  347. package/dist/parser/expressions/visual-block.js +21 -0
  348. package/dist/parser/expressions/visual-block.js.map +1 -0
  349. package/dist/parser/keyframes-source.d.ts +24 -0
  350. package/dist/parser/keyframes-source.d.ts.map +1 -0
  351. package/dist/parser/keyframes-source.js +133 -0
  352. package/dist/parser/keyframes-source.js.map +1 -0
  353. package/dist/parser/look-source.d.ts +25 -0
  354. package/dist/parser/look-source.d.ts.map +1 -0
  355. package/dist/parser/look-source.js +189 -0
  356. package/dist/parser/look-source.js.map +1 -0
  357. package/dist/parser/spans.d.ts +24 -0
  358. package/dist/parser/spans.d.ts.map +1 -0
  359. package/dist/parser/spans.js +113 -0
  360. package/dist/parser/spans.js.map +1 -0
  361. package/dist/parser/statements/components.d.ts +37 -0
  362. package/dist/parser/statements/components.d.ts.map +1 -0
  363. package/dist/parser/statements/components.js +185 -0
  364. package/dist/parser/statements/components.js.map +1 -0
  365. package/dist/parser/statements/heads.d.ts +38 -0
  366. package/dist/parser/statements/heads.d.ts.map +1 -0
  367. package/dist/parser/statements/heads.js +55 -0
  368. package/dist/parser/statements/heads.js.map +1 -0
  369. package/dist/parser/statements/imports.d.ts +9 -0
  370. package/dist/parser/statements/imports.d.ts.map +1 -0
  371. package/dist/parser/statements/imports.js +31 -0
  372. package/dist/parser/statements/imports.js.map +1 -0
  373. package/dist/parser/statements/reactive.d.ts +31 -0
  374. package/dist/parser/statements/reactive.d.ts.map +1 -0
  375. package/dist/parser/statements/reactive.js +68 -0
  376. package/dist/parser/statements/reactive.js.map +1 -0
  377. package/dist/parser/statements/unsafe-css.d.ts +21 -0
  378. package/dist/parser/statements/unsafe-css.d.ts.map +1 -0
  379. package/dist/parser/statements/unsafe-css.js +42 -0
  380. package/dist/parser/statements/unsafe-css.js.map +1 -0
  381. package/dist/parser.d.ts +37 -50
  382. package/dist/parser.d.ts.map +1 -1
  383. package/dist/parser.js +98 -882
  384. package/dist/parser.js.map +1 -1
  385. package/package.json +2 -2
package/dist/look.js CHANGED
@@ -1,937 +1,32 @@
1
1
  /**
2
- * One source of truth for every suffix owned by the Web visual language.
3
- * The lexer, analyzer, public-interface inference, and editor all consume this
4
- * table so a unit cannot silently mean different things at different stages.
5
- */
6
- export const LOOK_UNIT_TYPES = new Map([
7
- ...["px", "rem", "em", "vw", "vh", "vmin", "vmax"].map((unit) => [unit, "Length"]),
8
- ["%", "Percentage"],
9
- ["fr", "TrackFraction"],
10
- ...["ms", "s"].map((unit) => [unit, "Duration"]),
11
- ...["deg", "turn"].map((unit) => [unit, "Angle"]),
12
- ]);
13
- export const LOOK_MEDIA_LENGTH_UNITS = new Set(["px", "rem", "em"]);
14
- /**
15
- * The closed set of media-condition subjects a Look condition may name. Every
16
- * subject lowers to a CSS media query, so the whole set stays live for the
17
- * lifetime of the page. The names are reserved bindings in a Web module: a
18
- * user binding of the same name would otherwise be shadowed by this table
19
- * inside Look conditions only (LOK-D4).
20
- */
21
- export const LOOK_MEDIA_SUBJECTS = new Map([
22
- ["viewport", new Set(["width", "height"])],
23
- ["scheme", new Set(["dark", "light"])],
24
- ["motion", new Set(["reduced"])],
25
- ]);
26
- /** Media features a Web developer may reach for that Look deliberately omits. */
27
- export const LOOK_ABSENT_MEDIA_SUBJECTS = new Set(["container", "print", "orientation", "screen", "device", "pointer", "resolution", "display", "contrast", "colors"]);
28
- /**
29
- * Properties whose CSS grammar takes a bare number. Every other numeric Look
30
- * property is a length, so a unitless number would reach CSS as a dead
31
- * declaration; the property tables reject it and the diagnostic teaches the
32
- * unit (LOK-D3).
33
- */
34
- export const LOOK_UNITLESS_PROPERTIES = new Set([
35
- "lineHeight", "opacity", "zIndex", "fontWeight", "flex", "flexGrow", "flexShrink", "order", "scale", "aspectRatio",
36
- ]);
37
- /** Builders that compose lengths: a unitless argument other than 0 is dead CSS. */
38
- export const LOOK_LENGTH_BUILDERS = new Set(["spacing", "tracks", "minmax", "min", "max", "clamp", "border", "shadow", "blur", "dropShadow"]);
39
- /**
40
- * The numeric domains the velar/look builders enforce at run time: name, bounds,
41
- * and the unit the value is written in (LK-I3: hsl's are the language's own `%`).
42
- * A literal argument is checked the same way while the module compiles (LOK-U8).
43
- */
44
- export const LOOK_BUILDER_NUMERIC_RANGES = new Map([
45
- ["rgb", [["RGB channel 1", 0, 255], ["RGB channel 2", 0, 255], ["RGB channel 3", 0, 255]]],
46
- ["rgba", [["RGB channel 1", 0, 255], ["RGB channel 2", 0, 255], ["RGB channel 3", 0, 255], ["RGB alpha", 0, 1]]],
47
- ["hsl", [null, ["HSL saturation", 0, 100, "%"], ["HSL lightness", 0, 100, "%"]]],
48
- ["alpha", [null, ["Color opacity", 0, 1]]],
49
- ["lighten", [null, ["Color amount", 0, 1]]],
50
- ["darken", [null, ["Color amount", 0, 1]]],
51
- ["brightness", [["Filter brightness", 0, 1_000_000]]],
52
- ["contrast", [["Filter contrast", 0, 1_000_000]]],
53
- ["grayscale", [["Filter grayscale", 0, 1]]],
54
- ["invert", [["Filter inversion", 0, 1]]],
55
- ["filterOpacity", [["Filter opacity", 0, 1]]],
56
- ["saturate", [["Filter saturation", 0, 1_000_000]]],
57
- ["sepia", [["Filter sepia", 0, 1]]],
58
- ]);
59
- /** The border styles the border builder accepts, mirroring its runtime guard. */
60
- export const LOOK_BORDER_STYLE_NAMES = new Set(["none", "hidden", "dotted", "dashed", "solid", "double", "groove", "ridge", "inset", "outset"]);
61
- export const LOOK_ARITHMETIC_HINT = "@velarscript/web:look-arithmetic";
62
- export const LOOK_NUMERIC_TYPE_NAMES = new Set([
63
- "Length", "Percentage", "LengthPercentage", "TrackFraction", "Duration", "Angle",
64
- ]);
65
- // D50 rule 92: 'Opacity' never appeared here. No builder produces it and the
66
- // 'opacity' property's declared type is number, so the name was unreachable —
67
- // publishing an unreachable name is worse than publishing nothing.
68
- export const LOOK_PUBLIC_TYPE_NAMES = Object.freeze([
69
- "Look", "Length", "Percentage", "LengthPercentage", "TrackFraction", "Color", "Duration", "Angle",
70
- "Border", "Shadow", "Filter", "Image", "Track", "TrackList", "Transition", "Spacing", "Keyframes", "Animation",
71
- ]);
72
- export const LOOK_HOOKS = new Set([
73
- "hover", "focus", "focusVisible", "active", "current", "disabled", "checked", "invalid", "open",
74
- ]);
75
- export const LOOK_TARGETS = new Set([
76
- "before", "after", "backdrop", "placeholder", "selection", "marker", "fileSelectorButton",
77
- ]);
78
- /**
79
- * Every velar/look builder and the shape of its call. Three consumers read this
80
- * one table — the published module interface, the named-argument check, and the
81
- * static lowering that has to put a named argument back at its position when a
82
- * builder call appears inside a `keyframes:` stop. D57 rule 134: a list two
83
- * places need is written once and derived from.
84
- */
85
- export const LOOK_BUILDER_SIGNATURES = new Map([
86
- // D103: the design-system reference. One parameter and no second one — see
87
- // LOOK_TOKEN_NO_FALLBACK_GUIDANCE for why a fallback is not a parameter.
88
- ["token", { parameters: ["name"], required: 1, result: "string" }],
89
- ["color", { parameters: ["value"], required: 1, result: "color" }],
90
- ["rgb", { parameters: ["red", "green", "blue"], required: 3, result: "color" }],
91
- ["rgba", { parameters: ["red", "green", "blue", "alpha"], required: 4, result: "color" }],
92
- ["hsl", { parameters: ["hue", "saturation", "lightness"], required: 3, result: "color" }],
93
- ["alpha", { parameters: ["color", "opacity"], required: 2, result: "color" }],
94
- ["lighten", { parameters: ["color", "amount"], required: 2, result: "color" }],
95
- ["darken", { parameters: ["color", "amount"], required: 2, result: "color" }],
96
- ["border", { parameters: ["width", "color", "style"], required: 2, result: "border" }],
97
- ["shadow", { parameters: ["x", "y", "blur", "color", "spread", "inset"], required: 4, result: "shadow" }],
98
- ["blur", { parameters: ["radius"], required: 1, result: "filter" }],
99
- ["brightness", { parameters: ["amount"], required: 1, result: "filter" }],
100
- ["contrast", { parameters: ["amount"], required: 1, result: "filter" }],
101
- ["dropShadow", { parameters: ["x", "y", "blur", "color"], required: 4, result: "filter" }],
102
- ["grayscale", { parameters: ["amount"], required: 1, result: "filter" }],
103
- ["hueRotate", { parameters: ["angle"], required: 1, result: "filter" }],
104
- ["invert", { parameters: ["amount"], required: 1, result: "filter" }],
105
- ["filterOpacity", { parameters: ["amount"], required: 1, result: "filter" }],
106
- ["saturate", { parameters: ["amount"], required: 1, result: "filter" }],
107
- ["sepia", { parameters: ["amount"], required: 1, result: "filter" }],
108
- ["filters", { parameters: ["first"], required: 1, rest: true, result: "filter" }],
109
- ["linearGradient", { parameters: ["angle", "start", "end"], required: 3, result: "image" }],
110
- ["asset", { parameters: ["path"], required: 1, result: "image" }],
111
- ["minmax", { parameters: ["minimum", "maximum"], required: 2, result: "track" }],
112
- ["repeat", { parameters: ["count", "size"], required: 2, result: "track-list" }],
113
- ["tracks", { parameters: ["first"], required: 1, rest: true, result: "track-list" }],
114
- ["transition", { parameters: ["property", "duration", "easing", "delay"], required: 2, result: "transition" }],
115
- ["spacing", { parameters: ["first", "second", "third", "fourth"], required: 1, result: "spacing" }],
116
- // LK-C3: a length-percentage result, because mixing `%` with `px` is what these three exist for; an all-one-kind call folds back to that kind in the analyzer.
117
- ["min", { parameters: ["first", "second"], required: 2, result: "length-percentage" }],
118
- ["max", { parameters: ["first", "second"], required: 2, result: "length-percentage" }],
119
- ["clamp", { parameters: ["minimum", "preferred", "maximum"], required: 3, result: "length-percentage" }],
120
- ["animate", { parameters: ["frames", "duration", "easing", "delay", "count", "loop", "direction", "fill"], required: 2, result: "animation" }],
121
- ]);
122
- export const LOOK_BUILDERS = new Set(LOOK_BUILDER_SIGNATURES.keys());
123
- // ── D103: checked design-token references ─────────────────────────────────────
124
- // A design system's contract is a set of CSS custom properties, and the checked
125
- // Look value vocabulary had no spelling that could read one: the colour kinds
126
- // passed an arbitrary string through, the free-text kinds passed anything
127
- // through, and every metric, shadow and transition property refused. `token()`
128
- // is the one spelling, legal wherever a Look value is written.
129
- //
130
- // What is checked is the *reference* — its spelling and its position. The value
131
- // behind the name belongs to the design system, which the compiler cannot see:
132
- // no `@velaros-ai/ui` stylesheet is an input to this compile. That boundary is
133
- // declared rather than papered over, and it is exactly why the name must be a
134
- // literal: a computed name would leave nothing checkable at all.
135
- /**
136
- * A CSS custom property identifier, as a Look token name. `--` and at least one
137
- * more character, from the ASCII ident set a design system's tokens are written
138
- * with. CSS itself also admits non-ASCII ident code points and backslash
139
- * escapes; both are outside this set on purpose, because the text goes straight
140
- * into a compiler-owned stylesheet where an escape is a way out of the
141
- * declaration (the same reasoning LOK-U9 applies to `keyframes:` values).
142
- */
143
- export const LOOK_TOKEN_NAME_PATTERN = /^--[A-Za-z0-9_-]+$/u;
144
- /** The whole rule, in the terms a diagnostic teaches it. */
145
- export const LOOK_TOKEN_NAME_RULE = "a design token name is a literal string holding a CSS custom property identifier: '--' followed by one or more letters, digits, hyphens, or underscores";
146
- /**
147
- * D103 rule 5 — why there is no second parameter. A design token is the design
148
- * system's closed contract; a token that is missing is a defect in that system,
149
- * to be fixed once where it is defined, rather than a decision each of hundreds
150
- * of use sites re-makes for itself. A per-site fallback would also be the one
151
- * part of the reference the compiler could neither see nor check.
152
- */
153
- export const LOOK_TOKEN_NO_FALLBACK_GUIDANCE = "token(name) takes the token name and nothing else: a design token is the design system's closed contract, so a token that is missing is a defect to fix where the token is defined rather than a fallback decided again at every use site";
154
- export function isLookTokenName(name) {
155
- return LOOK_TOKEN_NAME_PATTERN.test(name);
156
- }
157
- /** The CSS text a checked token reference lowers to. */
158
- export function lookTokenReference(name) {
159
- return `var(${name})`;
160
- }
161
- /**
162
- * The token name a whole `var(--name)` string names, or null. Only the complete
163
- * value is read: `var()` inside a larger value — the tail of a font stack, one
164
- * layer of a filter — is a legitimate free-text spelling with no single token
165
- * to rewrite it to, so it is not this function's business. A `var(--x, red)`
166
- * fallback form answers null here and is diagnosed by its own message, because
167
- * the closed contract above has no fallback to migrate it to.
168
- */
169
- export function lookVarReferenceName(text) {
170
- const match = /^\s*var\(\s*(--[A-Za-z0-9_-]+)\s*\)\s*$/u.exec(text);
171
- return match ? match[1] : null;
172
- }
173
- /** Whether a whole string is a `var(...)` reference of any shape, fallback included. */
174
- export function isLookVarReference(text) {
175
- return /^\s*var\(\s*--/u.test(text) && /\)\s*$/u.test(text);
176
- }
177
- export const LOOK_ANIMATION_EASINGS = new Set([
178
- "linear", "ease", "ease-in", "ease-out", "ease-in-out", "step-start", "step-end",
179
- ]);
180
- export const LOOK_ANIMATION_DIRECTIONS = new Set(["normal", "reverse", "alternate", "alternate-reverse"]);
181
- export const LOOK_ANIMATION_FILLS = new Set(["none", "forwards", "backwards", "both"]);
182
- /** Properties whose CSS values do not participate in interpolated animation. */
183
- export const LOOK_NON_ANIMATABLE_PROPERTIES = new Set([
184
- "display", "position", "overflow", "overflowX", "overflowY", "pointerEvents", "cursor", "userSelect",
185
- "content", "visibility", "resize", "touchAction", "scrollBehavior", "appearance", "isolation", "contain",
186
- "animation", "transition", "transitionProperty", "transitionDuration", "transitionDelay", "transitionTimingFunction",
187
- ]);
188
- /** Published Look vocabulary, grouped by the job each property performs. */
189
- export const LOOK_PROPERTY_GROUPS = Object.freeze([
190
- { family: "layout and containment", properties: ["display", "position", "boxSizing", "isolation", "contain", "visibility", "zIndex", "overflow", "overflowX", "overflowY", "resize", "clip", "clipPath", "objectFit", "objectPosition", "aspectRatio"] },
191
- { family: "grid", properties: ["gridTemplateColumns", "gridTemplateRows", "gridTemplateAreas", "gridAutoColumns", "gridAutoRows", "gridAutoFlow", "gridColumn", "gridColumnStart", "gridColumnEnd", "gridRow", "gridRowStart", "gridRowEnd", "gridArea"] },
192
- { family: "flex and alignment", properties: ["flex", "flexDirection", "flexGrow", "flexShrink", "flexBasis", "flexWrap", "order", "gap", "rowGap", "columnGap", "alignItems", "justifyItems", "justifyContent", "alignContent", "alignSelf", "justifySelf", "placeItems", "placeContent", "placeSelf"] },
193
- { family: "size and inset", properties: ["width", "height", "minWidth", "maxWidth", "minHeight", "maxHeight", "inlineSize", "blockSize", "minInlineSize", "maxInlineSize", "minBlockSize", "maxBlockSize", "inset", "top", "right", "bottom", "left", "insetInline", "insetBlock", "insetInlineStart", "insetInlineEnd", "insetBlockStart", "insetBlockEnd"] },
194
- { family: "spacing", properties: ["padding", "paddingTop", "paddingRight", "paddingBottom", "paddingLeft", "paddingInline", "paddingBlock", "paddingInlineStart", "paddingInlineEnd", "paddingBlockStart", "paddingBlockEnd", "margin", "marginTop", "marginRight", "marginBottom", "marginLeft", "marginInline", "marginBlock", "marginInlineStart", "marginInlineEnd", "marginBlockStart", "marginBlockEnd"] },
195
- { family: "background", properties: ["background", "backgroundColor", "backgroundImage", "backgroundPosition", "backgroundSize", "backgroundRepeat", "backgroundAttachment", "backgroundClip", "backgroundOrigin", "backgroundBlendMode"] },
196
- { family: "border and outline", properties: ["border", "borderWidth", "borderStyle", "borderColor", "borderTop", "borderRight", "borderBottom", "borderLeft", "borderTopWidth", "borderRightWidth", "borderBottomWidth", "borderLeftWidth", "borderTopStyle", "borderRightStyle", "borderBottomStyle", "borderLeftStyle", "borderTopColor", "borderRightColor", "borderBottomColor", "borderLeftColor", "borderRadius", "borderTopLeftRadius", "borderTopRightRadius", "borderBottomRightRadius", "borderBottomLeftRadius", "outline", "outlineWidth", "outlineStyle", "outlineColor", "outlineOffset"] },
197
- { family: "effects", properties: ["boxShadow", "textShadow", "opacity", "filter", "backdropFilter", "content"] },
198
- // D104: `font` is not here. It is the one shorthand whose whole value space
199
- // this family already publishes as checked longhands, and see
200
- // LOOK_EXCLUDED_PROPERTIES for why publishing it beside them was worse than
201
- // publishing nothing.
202
- { family: "typography and international text", properties: ["color", "fontFamily", "fontSize", "fontWeight", "fontStyle", "fontStretch", "fontVariant", "fontKerning", "fontOpticalSizing", "fontFeatureSettings", "fontVariationSettings", "lineHeight", "verticalAlign", "letterSpacing", "wordSpacing", "textAlign", "textIndent", "textDecoration", "textDecorationColor", "textDecorationLine", "textDecorationStyle", "textDecorationThickness", "textUnderlineOffset", "textUnderlinePosition", "textTransform", "textRendering", "whiteSpace", "textOverflow", "textWrap", "overflowWrap", "wordBreak", "hyphens", "tabSize", "writingMode", "textOrientation", "direction", "unicodeBidi"] },
203
- { family: "lists", properties: ["listStyle", "listStyleType", "listStylePosition", "listStyleImage"] },
204
- { family: "SVG paint", properties: ["fill", "stroke", "strokeWidth", "strokeLinecap", "strokeLinejoin", "strokeDasharray", "strokeDashoffset"] },
205
- { family: "transform and transition", properties: ["translate", "scale", "rotate", "transform", "transformOrigin", "transition", "transitionProperty", "transitionDuration", "transitionDelay", "transitionTimingFunction", "animation"] },
206
- { family: "interaction and form theme", properties: ["cursor", "pointerEvents", "userSelect", "touchAction", "appearance", "accentColor", "caretColor", "colorScheme"] },
207
- { family: "scroll", properties: ["scrollBehavior", "scrollMargin", "scrollMarginTop", "scrollMarginRight", "scrollMarginBottom", "scrollMarginLeft", "scrollPadding", "scrollPaddingTop", "scrollPaddingRight", "scrollPaddingBottom", "scrollPaddingLeft", "scrollSnapAlign", "scrollSnapStop", "scrollSnapType", "overscrollBehavior", "overscrollBehaviorX", "overscrollBehaviorY", "scrollbarColor", "scrollbarWidth"] },
208
- ]);
209
- export const LOOK_PROPERTIES = new Set(LOOK_PROPERTY_GROUPS.flatMap((group) => group.properties));
210
- /** Stable editor-documentation key for one checked Look property. */
211
- export function lookPropertyDocumentationKey(property) {
212
- return `look:property:${property}`;
213
- }
214
- const propertyKinds = [
215
- ["animation", ["animation"]],
216
- ["angle", ["rotate"]],
217
- ["background", ["background"]],
218
- ["border", ["border", "borderTop", "borderRight", "borderBottom", "borderLeft", "outline"]],
219
- ["color", ["color", "backgroundColor", "borderColor", "borderTopColor", "borderRightColor", "borderBottomColor", "borderLeftColor", "outlineColor", "textDecorationColor", "accentColor", "caretColor", "fill", "stroke"]],
220
- ["duration", ["transitionDuration", "transitionDelay"]],
221
- ["filter", ["filter", "backdropFilter"]],
222
- ["image", ["backgroundImage", "listStyleImage"]],
223
- ["line-height", ["lineHeight"]],
224
- ["metric", ["gap", "rowGap", "columnGap", "width", "height", "minWidth", "maxWidth", "minHeight", "maxHeight", "inlineSize", "blockSize", "minInlineSize", "maxInlineSize", "minBlockSize", "maxBlockSize", "inset", "top", "right", "bottom", "left", "insetInline", "insetBlock", "insetInlineStart", "insetInlineEnd", "insetBlockStart", "insetBlockEnd", "padding", "paddingTop", "paddingRight", "paddingBottom", "paddingLeft", "paddingInline", "paddingBlock", "paddingInlineStart", "paddingInlineEnd", "paddingBlockStart", "paddingBlockEnd", "margin", "marginTop", "marginRight", "marginBottom", "marginLeft", "marginInline", "marginBlock", "marginInlineStart", "marginInlineEnd", "marginBlockStart", "marginBlockEnd", "flexBasis", "borderWidth", "borderTopWidth", "borderRightWidth", "borderBottomWidth", "borderLeftWidth", "borderRadius", "borderTopLeftRadius", "borderTopRightRadius", "borderBottomRightRadius", "borderBottomLeftRadius", "outlineWidth", "outlineOffset", "fontSize", "verticalAlign", "letterSpacing", "wordSpacing", "textIndent", "textDecorationThickness", "textUnderlineOffset", "strokeWidth", "strokeDashoffset", "scrollMargin", "scrollMarginTop", "scrollMarginRight", "scrollMarginBottom", "scrollMarginLeft", "scrollPadding", "scrollPaddingTop", "scrollPaddingRight", "scrollPaddingBottom", "scrollPaddingLeft", "translate", "transformOrigin", "backgroundPosition", "objectPosition", "backgroundSize"]],
225
- ["number", ["opacity", "zIndex", "flexGrow", "flexShrink", "order", "tabSize"]],
226
- ["number-keyword", ["fontWeight", "aspectRatio", "scale", "flex"]],
227
- ["shadow", ["boxShadow", "textShadow"]],
228
- ["text", ["content", "fontFamily", "fontFeatureSettings", "fontVariationSettings", "gridTemplateAreas", "gridColumn", "gridColumnStart", "gridColumnEnd", "gridRow", "gridRowStart", "gridRowEnd", "gridArea", "clip", "clipPath", "strokeDasharray", "scrollbarColor"]],
229
- ["track", ["gridTemplateColumns", "gridTemplateRows", "gridAutoColumns", "gridAutoRows"]],
230
- ["transform", ["transform"]],
231
- ["transition", ["transition"]],
232
- ["keyword", ["display", "position", "boxSizing", "isolation", "contain", "visibility", "overflow", "overflowX", "overflowY", "resize", "objectFit", "gridAutoFlow", "flexDirection", "flexWrap", "alignItems", "justifyItems", "justifyContent", "alignContent", "alignSelf", "justifySelf", "placeItems", "placeContent", "placeSelf", "backgroundRepeat", "backgroundAttachment", "backgroundClip", "backgroundOrigin", "backgroundBlendMode", "borderStyle", "borderTopStyle", "borderRightStyle", "borderBottomStyle", "borderLeftStyle", "outlineStyle", "fontStyle", "fontStretch", "fontVariant", "fontKerning", "fontOpticalSizing", "textAlign", "textDecoration", "textDecorationLine", "textDecorationStyle", "textUnderlinePosition", "textTransform", "textRendering", "whiteSpace", "textOverflow", "textWrap", "overflowWrap", "wordBreak", "hyphens", "writingMode", "textOrientation", "direction", "unicodeBidi", "listStyle", "listStyleType", "listStylePosition", "strokeLinecap", "strokeLinejoin", "transitionProperty", "transitionTimingFunction", "cursor", "pointerEvents", "userSelect", "touchAction", "appearance", "colorScheme", "scrollBehavior", "scrollSnapAlign", "scrollSnapStop", "scrollSnapType", "overscrollBehavior", "overscrollBehaviorX", "overscrollBehaviorY", "scrollbarWidth"]],
233
- ];
234
- export const LOOK_PROPERTY_VALUE_KINDS = new Map(propertyKinds.flatMap(([kind, properties]) => properties.map((property) => [property, kind])));
235
- for (const property of LOOK_PROPERTIES) {
236
- if (!LOOK_PROPERTY_VALUE_KINDS.has(property))
237
- throw new Error(`Look property '${property}' has no declared value kind`);
238
- }
239
- const cssWideKeywords = ["inherit", "initial", "revert", "revert-layer", "unset"];
240
- const keywords = (...values) => new Set([...cssWideKeywords, ...values]);
241
- /**
242
- * The five keywords every CSS property accepts. They are kept apart from a
243
- * property's own vocabulary so a diagnostic can lead with the values that
244
- * belong to the property being written (D67 rule 174).
245
- */
246
- export const LOOK_CSS_WIDE_KEYWORDS = Object.freeze([...cssWideKeywords]);
247
- const cssWideKeywordSet = new Set(cssWideKeywords);
248
- /** Shared sizing words accepted by metric properties without a property-specific table. */
249
- export const LOOK_SHARED_METRIC_KEYWORDS = Object.freeze([
250
- "auto", "none", "normal", "min-content", "max-content", "fit-content", "stretch",
251
- ]);
252
- /** Named colors accepted by the checked color and background value kinds. */
253
- export const LOOK_COLOR_KEYWORDS = Object.freeze([
254
- ...LOOK_CSS_WIDE_KEYWORDS, "transparent", "currentColor", "black", "silver", "gray", "white", "maroon", "red", "purple",
255
- "fuchsia", "green", "lime", "olive", "yellow", "navy", "blue", "teal", "aqua", "orange", "aliceblue", "rebeccapurple",
256
- ]);
257
- const lookFilterFunctions = Object.freeze([
258
- { name: "blur", example: "blur(4px)" },
259
- { name: "brightness", example: "brightness(1)" },
260
- { name: "contrast", example: "contrast(1)" },
261
- { name: "drop-shadow", example: "drop-shadow(0px 2px 4px rgba(0, 0, 0, 0.25))" },
262
- { name: "grayscale", example: "grayscale(1)" },
263
- { name: "hue-rotate", example: "hue-rotate(0deg)" },
264
- { name: "invert", example: "invert(1)" },
265
- { name: "opacity", example: "opacity(1)" },
266
- { name: "saturate", example: "saturate(1)" },
267
- { name: "sepia", example: "sepia(1)" },
268
- { name: "url", example: "url('#filter')" },
269
- ]);
270
- /**
271
- * Free-text CSS functions that are legal for a specific Look property. This is
272
- * editor vocabulary, not a second validator: only free-text properties appear
273
- * here, while closed properties keep using their checked keyword/builder sets.
274
- */
275
- export const LOOK_PROPERTY_CSS_FUNCTIONS = new Map([
276
- ["filter", lookFilterFunctions],
277
- ["backdropFilter", lookFilterFunctions],
278
- ["clipPath", Object.freeze([
279
- { name: "inset", example: "inset(0px)" },
280
- { name: "circle", example: "circle(50%)" },
281
- { name: "ellipse", example: "ellipse(50% 50%)" },
282
- { name: "polygon", example: "polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)" },
283
- ])],
284
- ]);
285
- /**
286
- * D60 rule 150: `transitionProperty` published a name no author could reach —
287
- * its only accepted values were the generic defaults, so no property name was
288
- * writable. The vocabulary is derived from the Look property table rather than
289
- * listed by hand (D57 rule 134): every animatable Look property, spelled the
290
- * way CSS spells it, plus the two aggregate keywords. A property that does not
291
- * participate in interpolation is excluded for the same reason `keyframes:`
292
- * rejects it.
293
- *
294
- * The set is published because the longhand is not its only reader: charter
295
- * section 3549 says the `transition(property, ...)` builder takes the same
296
- * vocabulary, so the analyzer's literal-argument check and the builder's own
297
- * runtime guard read this table rather than restating it.
298
- */
299
- export const LOOK_TRANSITION_PROPERTY_KEYWORDS = keywords("none", "all", ...[...LOOK_PROPERTIES]
300
- .filter((property) => !LOOK_NON_ANIMATABLE_PROPERTIES.has(property))
301
- .map(cssPropertyName));
302
- /**
303
- * Every `left right` value of a grammar that takes one token from each of two
304
- * positions — `y mandatory`, `left top`. D65 rule 169: a closed set holds the
305
- * complete value the author writes, so a multi-token CSS value is written out
306
- * here rather than turned into a builder or a token grammar of its own.
307
- */
308
- function lookValuePairs(left, right) {
309
- const second = [...right];
310
- return [...left].flatMap((first) => second.map((last) => `${first} ${last}`));
311
- }
312
- /**
313
- * Every value of a CSS `||` combination: each non-empty selection of the tokens
314
- * in every order the combinator accepts, so `dense row` is the same value as
315
- * `row dense` to the author and to the browser.
316
- */
317
- function lookValueOrderings(tokens) {
318
- return tokens.flatMap((token, index) => {
319
- const rest = [...tokens.slice(0, index), ...tokens.slice(index + 1)];
320
- return [token, ...lookValueOrderings(rest).map((tail) => `${token} ${tail}`)];
321
- });
322
- }
323
- /** Every value of a `[ … ]{1,2}` repetition — `scrollSnapAlign: start end`. */
324
- function lookValueRepetitions(tokens) {
325
- return [...tokens, ...lookValuePairs(tokens, tokens)];
326
- }
327
- // `<position>`'s keyword grid: one placement word, or one from each axis in
328
- // either order. D67 rule 172: the three properties that take a `<position>` are
329
- // all `metric`, so the length and percentage forms are the unit half of that
330
- // kind rather than a value space anyone has to record as excluded.
331
- const horizontalPositions = ["left", "center", "right"];
332
- const verticalPositions = ["top", "center", "bottom"];
333
- const positionKeywords = [
334
- ...horizontalPositions, ...verticalPositions,
335
- ...lookValuePairs(horizontalPositions, verticalPositions),
336
- ...lookValuePairs(verticalPositions, horizontalPositions),
337
- ];
338
- // The line part of the text-decoration family, written once: `textDecoration`
339
- // is the shorthand whose only closed part is this one (D57 rule 134).
340
- const textDecorationLineKeywords = ["none", ...lookValueOrderings(["underline", "overline", "line-through"])];
341
- // The predefined counter styles of CSS Counter Styles 3 §6, by its own
342
- // grouping. A `<string>` marker and a custom `@counter-style` name are the open
343
- // part and are recorded as excluded.
344
- const listStyleTypeKeywords = [
345
- "none",
346
- // §6.1 numeric
347
- "decimal", "decimal-leading-zero", "arabic-indic", "armenian", "upper-armenian", "lower-armenian", "bengali",
348
- "cambodian", "khmer", "cjk-decimal", "devanagari", "georgian", "gujarati", "gurmukhi", "hebrew", "kannada", "lao",
349
- "malayalam", "mongolian", "myanmar", "oriya", "persian", "lower-roman", "upper-roman", "tamil", "telugu", "thai", "tibetan",
350
- // §6.2 alphabetic
351
- "lower-alpha", "lower-latin", "upper-alpha", "upper-latin", "lower-greek",
352
- "hiragana", "hiragana-iroha", "katakana", "katakana-iroha",
353
- // §6.3 symbolic
354
- "disc", "circle", "square", "disclosure-open", "disclosure-closed",
355
- // §6.4 fixed
356
- "cjk-earthly-branch", "cjk-heavenly-stem",
357
- // §6.5 complex, and the two aliases CSS 2.1 shipped
358
- "japanese-informal", "japanese-formal", "korean-hangul-formal", "korean-hanja-informal", "korean-hanja-formal",
359
- "simp-chinese-informal", "simp-chinese-formal", "trad-chinese-informal", "trad-chinese-formal",
360
- "cjk-ideographic", "ethiopic-numeric",
361
- ];
362
- const listStylePositionKeywords = ["inside", "outside"];
363
- // `color-scheme` names the same two schemes `if scheme.dark:` conditions on, so
364
- // it reads that table rather than restating it. `only` may lead or trail the
365
- // scheme list.
366
- const colorSchemeOrderings = lookValueOrderings([...LOOK_MEDIA_SUBJECTS.get("scheme") ?? []]);
367
- const scrollSnapAxes = ["x", "y", "block", "inline", "both"];
368
- const overscrollBehaviors = ["auto", "contain", "none"];
369
- // CSS Box Alignment 3's shared value groups. Nine Look properties select from
370
- // them, and each selects a different combination, so the groups are written
371
- // once and the nine read them (D57 rule 134). The `<overflow-position>` safe
372
- // and unsafe prefixes are the part no set holds, and every one of the nine
373
- // records it. D67 rule 173: `self-start`, `self-end` and the baseline
374
- // positions are real values all nine used to refuse.
375
- const alignBaselinePositions = ["baseline", "first baseline", "last baseline"];
376
- const alignSelfPositions = ["center", "start", "end", "self-start", "self-end", "flex-start", "flex-end"];
377
- const alignContentPositions = ["center", "start", "end", "flex-start", "flex-end"];
378
- const alignContentDistributions = ["space-between", "space-around", "space-evenly", "stretch"];
379
- // `touch-action`'s single tokens, including the four one-way pans and the pinch
380
- // gesture. D67 rule 173: the property published five of these ten, so
381
- // `pan-left` and `pinch-zoom` -- values a scroll container really takes -- were
382
- // refused. The `||` combinations of a horizontal pan, a vertical pan and
383
- // pinch-zoom are the part no set holds and are recorded as excluded.
384
- const touchActionKeywords = [
385
- "auto", "none", "pan-x", "pan-left", "pan-right", "pan-y", "pan-up", "pan-down", "pinch-zoom", "manipulation",
386
- ];
387
- // `background-repeat`'s `<repeat-style>`: the two one-axis shorthands, or one
388
- // token per axis. D67 rule 173: `backgroundRepeat = "repeat no-repeat"` is the
389
- // ordinary way to repeat on one axis only, and the set used to hold six of the
390
- // twenty-two values that spell it.
391
- const backgroundRepeatKeywords = [
392
- "repeat-x", "repeat-y", ...lookValueRepetitions(["repeat", "space", "round", "no-repeat"]),
393
- ];
394
- export const LOOK_PROPERTY_KEYWORDS = new Map([
395
- // D67 rule 173: `list-item` is a real display type with no other spelling, so
396
- // it joins the set. The two-keyword form does not: every pair it writes has a
397
- // single-keyword name already here, and the table and ruby display types stay
398
- // out with the table formatting properties LOOK_EXCLUDED_PROPERTIES excludes.
399
- ["display", keywords("none", "block", "inline", "inline-block", "flow-root", "flex", "inline-flex", "grid", "inline-grid", "contents", "list-item")],
400
- ["isolation", keywords("auto", "isolate")],
401
- ["contain", keywords("none", "strict", "content", "size", "inline-size", "layout", "style", "paint")],
402
- ["backgroundSize", keywords("auto", "cover", "contain")],
403
- // D67 rule 172: `backgroundPosition`, `transformOrigin` and `objectPosition`
404
- // are one CSS grammar, so they are one `metric` kind reading one table. The
405
- // two that used to hold five of the twenty-two placements refused
406
- // `backgroundPosition = "top left"`, a value the property really has.
407
- ["backgroundPosition", keywords(...positionKeywords)],
408
- ["transformOrigin", keywords(...positionKeywords)],
409
- ["objectPosition", keywords(...positionKeywords)],
410
- ["transitionProperty", LOOK_TRANSITION_PROPERTY_KEYWORDS],
411
- ["transitionTimingFunction", keywords(...LOOK_ANIMATION_EASINGS)],
412
- ["position", keywords("static", "relative", "absolute", "fixed", "sticky")],
413
- ["boxSizing", keywords("content-box", "border-box")],
414
- ["visibility", keywords("visible", "hidden", "collapse")],
415
- ["overflow", keywords("visible", "hidden", "clip", "scroll", "auto")],
416
- ["overflowX", keywords("visible", "hidden", "clip", "scroll", "auto")],
417
- ["overflowY", keywords("visible", "hidden", "clip", "scroll", "auto")],
418
- ["objectFit", keywords("fill", "contain", "cover", "none", "scale-down")],
419
- ["flexDirection", keywords("row", "row-reverse", "column", "column-reverse")],
420
- ["flexWrap", keywords("nowrap", "wrap", "wrap-reverse")],
421
- // Each of the nine takes a different selection of the alignment groups, and
422
- // the differences are the property's own grammar rather than an oversight:
423
- // `justifyContent` has no baseline position, `alignContent` has no
424
- // self-position, and the three `place*` shorthands take only what both of
425
- // their halves take.
426
- ["alignItems", keywords("normal", "stretch", ...alignBaselinePositions, ...alignSelfPositions)],
427
- ["alignContent", keywords("normal", ...alignBaselinePositions, ...alignContentDistributions, ...alignContentPositions)],
428
- ["alignSelf", keywords("auto", "normal", "stretch", ...alignBaselinePositions, ...alignSelfPositions)],
429
- ["justifyItems", keywords("normal", "stretch", ...alignBaselinePositions, ...alignSelfPositions, "left", "right")],
430
- ["justifyContent", keywords("normal", ...alignContentDistributions, ...alignContentPositions, "left", "right")],
431
- ["justifySelf", keywords("auto", "normal", "stretch", ...alignBaselinePositions, ...alignSelfPositions, "left", "right")],
432
- ["placeItems", keywords("normal", "stretch", ...alignBaselinePositions, ...alignSelfPositions)],
433
- ["placeContent", keywords("normal", ...alignContentDistributions, ...alignContentPositions)],
434
- ["placeSelf", keywords("auto", "normal", "stretch", ...alignBaselinePositions, ...alignSelfPositions)],
435
- // D67 rule 173: `all-scroll` was the one CSS Basic UI cursor keyword missing.
436
- ["cursor", keywords("auto", "default", "none", "context-menu", "help", "pointer", "progress", "wait", "cell", "crosshair", "text", "vertical-text", "alias", "copy", "move", "no-drop", "not-allowed", "grab", "grabbing", "all-scroll", "col-resize", "row-resize", "n-resize", "e-resize", "s-resize", "w-resize", "ne-resize", "nw-resize", "se-resize", "sw-resize", "ew-resize", "ns-resize", "nesw-resize", "nwse-resize", "zoom-in", "zoom-out")],
437
- ["textAlign", keywords("start", "end", "left", "right", "center", "justify", "match-parent")],
438
- ["textTransform", keywords("none", "capitalize", "uppercase", "lowercase", "full-width", "full-size-kana")],
439
- ["textDecoration", keywords(...textDecorationLineKeywords)],
440
- ["whiteSpace", keywords("normal", "pre", "nowrap", "pre-wrap", "pre-line", "break-spaces")],
441
- ["textOverflow", keywords("clip", "ellipsis")],
442
- ["textWrap", keywords("wrap", "nowrap", "balance", "pretty", "stable")],
443
- ["overflowWrap", keywords("normal", "break-word", "anywhere")],
444
- ["wordBreak", keywords("normal", "break-all", "keep-all", "break-word")],
445
- ["hyphens", keywords("none", "manual", "auto")],
446
- ["listStyle", keywords(...listStyleTypeKeywords, ...listStylePositionKeywords)],
447
- ["resize", keywords("none", "both", "horizontal", "vertical", "block", "inline")],
448
- ["pointerEvents", keywords("auto", "none", "visiblePainted", "visibleFill", "visibleStroke", "visible", "painted", "fill", "stroke", "all")],
449
- ["userSelect", keywords("auto", "text", "none", "contain", "all")],
450
- ["touchAction", keywords(...touchActionKeywords)],
451
- ["appearance", keywords("none", "auto", "textfield", "menulist-button")],
452
- ["scrollBehavior", keywords("auto", "smooth")],
453
- ["scrollbarWidth", keywords("auto", "thin", "none")],
454
- ["backgroundRepeat", keywords(...backgroundRepeatKeywords)],
455
- ["backgroundAttachment", keywords("scroll", "fixed", "local")],
456
- ["backgroundClip", keywords("border-box", "padding-box", "content-box", "text")],
457
- ["backgroundOrigin", keywords("border-box", "padding-box", "content-box")],
458
- // D104 rule 3: the property an inline badge sits on. It is `metric` because
459
- // its non-keyword half is a length or a percentage of the line height, and it
460
- // carries its own table for the same reason `backgroundSize` does — the
461
- // shared sizing words are not its vocabulary. CSS 2.1 §10.8.1 is the whole
462
- // set, and nothing is recorded as left out: CSS Inline Layout 3's `first` and
463
- // `last` baseline sources are unimplemented everywhere, and a `metric`
464
- // property records no partial exclusion for the reason D67 rule 172 revoked
465
- // `objectPosition`'s — the lengths are the unit half of the kind rather than
466
- // a value space to record.
467
- ["verticalAlign", keywords("baseline", "sub", "super", "text-top", "text-bottom", "middle", "top", "bottom")],
468
- ["fontStyle", keywords("normal", "italic", "oblique")],
469
- ["fontKerning", keywords("auto", "normal", "none")],
470
- ["fontOpticalSizing", keywords("auto", "none")],
471
- ["writingMode", keywords("horizontal-tb", "vertical-rl", "vertical-lr")],
472
- ["textOrientation", keywords("mixed", "upright", "sideways")],
473
- ["direction", keywords("ltr", "rtl")],
474
- ["unicodeBidi", keywords("normal", "embed", "isolate", "bidi-override", "isolate-override", "plaintext")],
475
- // ── D65 rule 168 ────────────────────────────────────────────────────────
476
- // Every entry below used to be absent, and a keyword property with no
477
- // vocabulary of its own fell back to a shared list that knew nothing about
478
- // it: it refused `borderStyle = "groove"` and accepted `strokeLinecap =
479
- // "none"`, which reaches the browser as a declaration it discards. A value
480
- // set that already exists in another table is read from that table rather
481
- // than restated (D57 rule 134).
482
- ["gridAutoFlow", keywords(...lookValueOrderings(["row", "dense"]), ...lookValueOrderings(["column", "dense"]))],
483
- ["backgroundBlendMode", keywords("normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity")],
484
- // The five border-style properties and the border() builder's style argument
485
- // are one vocabulary, so they are one table.
486
- ...["borderStyle", "borderTopStyle", "borderRightStyle", "borderBottomStyle", "borderLeftStyle"]
487
- .map((property) => [property, keywords(...LOOK_BORDER_STYLE_NAMES)]),
488
- // An outline takes the border styles plus `auto`, minus `hidden`: CSS Basic
489
- // UI says `hidden` is not a legal outline style, and a border table read
490
- // straight through would have published a twenty-seventh dead value.
491
- ["outlineStyle", keywords(...[...LOOK_BORDER_STYLE_NAMES].filter((style) => style !== "hidden"), "auto")],
492
- ["fontStretch", keywords("normal", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded")],
493
- // Every single-token value of the shorthand's six sub-properties: position,
494
- // caps, numeric, alternates, ligatures, and East Asian.
495
- ["fontVariant", keywords("normal", "none", "sub", "super", "small-caps", "all-small-caps", "petite-caps", "all-petite-caps", "titling-caps", "unicase", "lining-nums", "oldstyle-nums", "proportional-nums", "tabular-nums", "diagonal-fractions", "stacked-fractions", "ordinal", "slashed-zero", "historical-forms", "common-ligatures", "no-common-ligatures", "discretionary-ligatures", "no-discretionary-ligatures", "historical-ligatures", "no-historical-ligatures", "contextual", "no-contextual", "jis78", "jis83", "jis90", "jis04", "simplified", "traditional", "full-width", "proportional-width", "ruby")],
496
- ["textDecorationLine", keywords(...textDecorationLineKeywords)],
497
- ["textDecorationStyle", keywords("solid", "double", "dotted", "dashed", "wavy")],
498
- ["textUnderlinePosition", keywords("auto", "from-font", ...lookValueOrderings(["under", "left"]), ...lookValueOrderings(["under", "right"]))],
499
- ["textRendering", keywords("auto", "optimizeSpeed", "optimizeLegibility", "geometricPrecision")],
500
- ["listStyleType", keywords(...listStyleTypeKeywords)],
501
- ["listStylePosition", keywords(...listStylePositionKeywords)],
502
- ["strokeLinecap", keywords("butt", "round", "square")],
503
- ["strokeLinejoin", keywords("miter", "round", "bevel")],
504
- ["colorScheme", keywords("normal", ...colorSchemeOrderings.flatMap((schemes) => [schemes, `only ${schemes}`, `${schemes} only`]))],
505
- ["scrollSnapAlign", keywords(...lookValueRepetitions(["none", "start", "end", "center"]))],
506
- ["scrollSnapStop", keywords("normal", "always")],
507
- ["scrollSnapType", keywords("none", ...scrollSnapAxes, ...lookValuePairs(scrollSnapAxes, ["mandatory", "proximity"]))],
508
- ["overscrollBehavior", keywords(...lookValueRepetitions(overscrollBehaviors))],
509
- ["overscrollBehaviorX", keywords(...overscrollBehaviors)],
510
- ["overscrollBehaviorY", keywords(...overscrollBehaviors)],
511
- // ── D73 rule 187: the kinds outside `keyword` that also decide a string ────
512
- // Each of these used to be answered by a 46-word list shared across every
513
- // property that had no table of its own. That list both accepted values the
514
- // property never had — `fontWeight = "circle"` compiled and reached CSS as a
515
- // declaration the browser drops — and made the diagnostic promise "the closed
516
- // fontWeight keywords", a table that did not exist. The sets below come from
517
- // the CSS grammar of each property; what the grammar leaves open is recorded
518
- // in LOOK_PARTIAL_KEYWORD_PROPERTIES rather than waved through.
519
- // The shorthands whose non-keyword values are written with a builder. `none`
520
- // is the whole of their keyword half.
521
- ...["border", "borderTop", "borderRight", "borderBottom", "borderLeft", "outline"]
522
- .map((property) => [property, keywords("none")]),
523
- ["boxShadow", keywords("none")],
524
- ["textShadow", keywords("none")],
525
- // CSS Fonts 4: the four named weights. The numeric half is the `number` this
526
- // property's type already accepts.
527
- ["fontWeight", keywords("normal", "bold", "bolder", "lighter")],
528
- ["aspectRatio", keywords("auto")],
529
- ["scale", keywords("none")],
530
- // CSS Flexbox 1: the single-token forms of the shorthand — `none`, and the
531
- // `<'flex-basis'>` keywords, which are the sizing words.
532
- ["flex", keywords("none", "auto", "content", "min-content", "max-content", "fit-content")],
533
- ["lineHeight", keywords("normal")],
534
- ["rotate", keywords("none")],
535
- // CSS Transitions: `<time>#`. There is no keyword half at all, so the closed
536
- // set is the CSS-wide words and nothing else — which is a truthful answer
537
- // where "one of the closed keywords" was not.
538
- ["transitionDuration", keywords()],
539
- ["transitionDelay", keywords()],
540
- ["transition", keywords("none")],
541
- ["opacity", keywords()],
542
- ["zIndex", keywords("auto")],
543
- ["flexGrow", keywords()],
544
- ["flexShrink", keywords()],
545
- ["order", keywords()],
546
- ["tabSize", keywords()],
547
- // CSS Grid: a template is written with `tracks(...)`, so `none` is its only
548
- // text. An implicit track takes the three `<track-size>` keywords.
549
- ["gridTemplateColumns", keywords("none")],
550
- ["gridTemplateRows", keywords("none")],
551
- ["gridAutoColumns", keywords("auto", "min-content", "max-content")],
552
- ["gridAutoRows", keywords("auto", "min-content", "max-content")],
553
- ]);
554
- /**
555
- * D73 rule 187 — every kind whose string values are decided per property. D65
556
- * rule 168 drew this line at `kind === "keyword"`, which was that wave's
557
- * boundary rather than the principle: the principle is that publishing a
558
- * surface which cannot be reached, or which swallows a false value, is worse
559
- * than not publishing it (D50 rule 92), and that principle does not know about
560
- * kinds. `metric` is absent because it answers with the sizing words when it
561
- * has no table of its own, and `color`, `background` and `image` are absent
562
- * because their diagnostics name a real vocabulary — a color keyword, a builder
563
- * — rather than a table. `text`, `filter`, `transform` and `animation` accept
564
- * arbitrary text by construction.
565
- */
566
- export const LOOK_KEYWORD_DECIDED_KINDS = new Set([
567
- "keyword", "border", "shadow", "number", "number-keyword", "line-height", "angle", "duration", "track", "transition",
568
- ]);
569
- /**
570
- * D65 rule 168, widened by D73 rule 187 — a property whose values are decided
571
- * per property carries its own closed set or the module refuses to load. The
572
- * shared fallback vocabulary this replaces was worse than a missing check: it
573
- * decided values for a property it had never heard of, so the same table that
574
- * rejected `listStyleType = "upper-roman"` accepted `colorScheme = "none"` and
575
- * `fontWeight = "circle"` and emitted them as declarations the browser drops.
576
- * A published name whose values are decided by a table that does not know the
577
- * property is not a checked property, so this is a load-time fact rather than
578
- * a test — the same shape as the value-kind invariant above.
579
- */
580
- for (const [property, kind] of LOOK_PROPERTY_VALUE_KINDS) {
581
- if (LOOK_KEYWORD_DECIDED_KINDS.has(kind) && !LOOK_PROPERTY_KEYWORDS.has(property)) {
582
- throw new Error(`Look property '${property}' accepts string keywords and has no closed keyword set`);
583
- }
584
- }
585
- /** A property's own closed values, without the CSS-wide keywords every property shares. */
586
- export function lookOwnKeywords(property) {
587
- const values = LOOK_PROPERTY_KEYWORDS.get(property);
588
- return values === undefined ? [] : [...values].filter((value) => !cssWideKeywordSet.has(value));
589
- }
590
- /** Closed, directly writable string values worth offering for one Look property. */
591
- export function lookPropertyCompletionKeywords(property) {
592
- const kind = LOOK_PROPERTY_VALUE_KINDS.get(property);
593
- if (!kind || kind === "animation")
594
- return [];
595
- const own = LOOK_PROPERTY_KEYWORDS.get(property);
596
- if (kind === "metric" && own === undefined)
597
- return [...LOOK_CSS_WIDE_KEYWORDS, ...LOOK_SHARED_METRIC_KEYWORDS];
598
- if (kind === "color" || kind === "background")
599
- return LOOK_COLOR_KEYWORDS;
600
- if (kind === "image" || kind === "filter" || kind === "transform")
601
- return [...LOOK_CSS_WIDE_KEYWORDS, "none"];
602
- if (kind === "text")
603
- return LOOK_CSS_WIDE_KEYWORDS;
604
- return own === undefined ? LOOK_CSS_WIDE_KEYWORDS : [...own];
605
- }
606
- /** Whether a velar/look builder's result can be assigned directly to a property. */
607
- export function lookBuilderSupportsProperty(builder, property) {
608
- const result = LOOK_BUILDER_SIGNATURES.get(builder)?.result;
609
- const kind = LOOK_PROPERTY_VALUE_KINDS.get(property);
610
- if (!result || !kind)
611
- return false;
612
- switch (result) {
613
- case "string": return kind !== "animation";
614
- case "animation": return kind === "animation";
615
- case "border": return kind === "border";
616
- case "color": return kind === "color" || kind === "background";
617
- case "filter": return kind === "filter";
618
- case "image": return kind === "image" || kind === "background";
619
- case "length": return kind === "metric" || kind === "line-height";
620
- case "length-percentage": return kind === "metric"; // a percentage is no bare line height
621
- case "shadow": return kind === "shadow";
622
- case "spacing": return kind === "metric" || kind === "number-keyword";
623
- case "track": return false;
624
- case "track-list": return kind === "track";
625
- case "transition": return kind === "transition";
626
- }
627
- }
628
- /**
629
- * D67 rule 174 — how many of a property's own values a diagnostic writes out
630
- * before it names the shape of the set instead.
2
+ * The Web visual vocabulary's front door. `look.ts` was one 1,041-line module of
3
+ * pure tables; D115 P4 R3e split it into `look/` by the question each part
4
+ * answers, and this facade re-exports every one of the 55 names it published, so
5
+ * no import path in the repository changed.
631
6
  *
632
- * The number is not load-bearing at its exact value: the published tables fall
633
- * into two clumps with nothing between them, the largest single-grammar set
634
- * holding twenty-two values and the next set up holding thirty-five. Anything
635
- * in that gap draws the same line. What matters is that a set on the far side
636
- * of it still says something an author can act on, which is what
637
- * LOOK_LARGE_KEYWORD_SETS below is for.
638
- */
639
- export const LOOK_KEYWORD_LISTING_LIMIT = 24;
640
- /**
641
- * What a vocabulary too long to write out holds, in the terms the author would
642
- * look it up by. A diagnostic reads this when the value it rejected is not a
643
- * near miss of anything, so that "one of the closed keywords" is never the
644
- * whole of the answer (D67 rule 174).
645
- */
646
- export const LOOK_LARGE_KEYWORD_SETS = new Map([
647
- ["cursor", "the CSS Basic UI cursor keywords, including the eight directional and four bidirectional resize cursors"],
648
- ["fontVariant", "the single-token values of the six font-variant feature groups: position, caps, numeric, alternates, ligatures, and East Asian"],
649
- ["listStyleType", "the predefined counter styles of CSS Counter Styles 3, by numeric, alphabetic, symbolic, fixed, and complex system"],
650
- ["listStyle", "the predefined counter styles of CSS Counter Styles 3 plus the inside and outside marker positions"],
651
- ["transitionProperty", "none, all, and the CSS spelling of every animatable Look property"],
652
- ]);
653
- for (const [property] of LOOK_PROPERTY_KEYWORDS) {
654
- const own = lookOwnKeywords(property);
655
- if (own.length > LOOK_KEYWORD_LISTING_LIMIT && !LOOK_LARGE_KEYWORD_SETS.has(property)) {
656
- throw new Error(`Look property '${property}' publishes ${own.length} keywords, more than a diagnostic writes out, and records no description of what the set holds`);
657
- }
658
- }
659
- for (const [property] of LOOK_LARGE_KEYWORD_SETS) {
660
- if (lookOwnKeywords(property).length <= LOOK_KEYWORD_LISTING_LIMIT) {
661
- throw new Error(`Look property '${property}' describes its keyword set but is small enough to write out, so the description would never be read`);
662
- }
663
- }
664
- /**
665
- * D65 rule 169 — what a partly closable property leaves out, and why.
7
+ * Where to look:
666
8
  *
667
- * Some CSS value spaces cannot be written as a set: `listStyleType` reaches
668
- * into `@counter-style` names, `fontVariant` into a combination of six feature
669
- * groups, `fontStretch` into percentages. Such a property publishes the subset it
670
- * can close and records the remainder here, so the boundary is visible in the
671
- * table and in the diagnostic instead of being waved through by a fallback
672
- * vocabulary. This is the per-value sibling of LOOK_EXCLUDED_PROPERTIES, which
673
- * records the properties left out whole.
674
- */
675
- export const LOOK_PARTIAL_KEYWORD_PROPERTIES = new Map([
676
- // D67 rule 172 revoked `objectPosition`'s record: the lengths it named as
677
- // excluded are the unit half of the `metric` kind it now shares with the
678
- // other two `<position>` properties, so nothing is left out to record.
679
- ["contain", "Combinations of size, layout, style and paint are outside the closed set, which holds the single tokens plus the named strict and content shorthands"],
680
- ["backgroundBlendMode", "A comma-separated per-layer blend list is outside the closed set, because a checked Look background is one layer"],
681
- ["borderStyle", "The one-to-four value per-side form is outside the closed set; borderTopStyle, borderRightStyle, borderBottomStyle and borderLeftStyle write it"],
682
- ["fontStretch", "Percentage font widths are outside the closed set, which holds the named widths"],
683
- ["fontVariant", "Combining feature groups in one value, and the annotation(), character-variant(), ornaments(), styleset() and swash() notations, are outside the closed set, which holds each group's single-token values; fontFeatureSettings carries a combination"],
684
- ["textDecorationLine", "The blink line is outside the closed set: browsers parse it and draw nothing, so it is a declaration with no effect. The spelling-error and grammar-error lines are outside it too, because a document cannot ask for them the way a spell checker does"],
685
- ["strokeLinejoin", "The SVG2 arcs and miter-clip joins are outside the closed set, because no browser implements them"],
686
- ["textDecoration", "The style, color and thickness parts of the shorthand are outside the closed set; textDecorationStyle, textDecorationColor and textDecorationThickness write them"],
687
- ["listStyle", "The image part and multi-part combinations of the shorthand are outside the closed set; listStyleType, listStylePosition and listStyleImage write them"],
688
- ["listStyleType", "A literal string marker and a custom @counter-style name are outside the closed set, which holds the predefined counter styles"],
689
- // ── D67 rule 173 ────────────────────────────────────────────────────────
690
- // The rest of the seventy-seven, recorded rather than completed. Rule 173's
691
- // deliverable is the boundary, not the value count: a property may publish a
692
- // subset of its CSS grammar as long as the subset's edge is written down here
693
- // and the diagnostic reads it out. Each entry below names a value space that
694
- // is open (a string, an angle, a custom ident), redundant with a spelling the
695
- // set already holds, owned by another property, or unimplemented.
696
- ["display", "The two-keyword <display-outside> <display-inside> form is outside the closed set, and writes nothing the single-keyword names here do not: block flow is block, inline flow-root is inline-block. The table, ruby and run-in display types are outside it too, with the table formatting properties and for the same reason"],
697
- ["overflow", "The two-value x y form is outside the closed set; overflowX and overflowY write it"],
698
- ["fontStyle", "An oblique slant angle such as 'oblique 14deg' is outside the closed set, which holds the named slants"],
699
- ["textOverflow", "A literal ellipsis string, and the two-value start end form, are outside the closed set, which holds clip and ellipsis"],
700
- ["textAlign", "The justify-all keyword is outside the closed set, because no browser justifies the last line for it"],
701
- ["textTransform", "Combining a case transform with full-width or full-size-kana in one value is outside the closed set, which holds each of them alone"],
702
- ["writingMode", "The sideways-rl and sideways-lr modes are outside the closed set, because only one browser engine implements them"],
703
- ["touchAction", "Combining a horizontal pan, a vertical pan and pinch-zoom in one value is outside the closed set, which holds each of them alone"],
704
- ["appearance", "The compat-auto aliases such as button, checkbox and menulist are outside the closed set, because each of them renders exactly as auto"],
705
- ["colorScheme", "A custom scheme ident is outside the closed set, which holds the two schemes 'if scheme.dark:' conditions on"],
706
- ["cursor", "A url() cursor image and its fallback list are outside the closed set, which holds the keyword cursors"],
707
- // D49 gave `animate(easing=)` and this property one easing table, so the
708
- // functions absent from it are absent on purpose. Recording that is how the
709
- // closure stays legible without being mistaken for a gap to fill.
710
- ["transitionTimingFunction", "The cubic-bezier(), steps() and linear() easing functions are outside the closed set, which is the same easing table animate(easing=) reads"],
711
- // D60 rule 150 derived this set from the Look property table minus the
712
- // properties that do not interpolate. The subtraction is the boundary.
713
- ["transitionProperty", "A property whose value does not interpolate is outside the closed set, for the same reason a 'keyframes:' stop rejects it"],
714
- // The nine Box Alignment properties. Each records the overflow-position
715
- // prefixes; the three shorthands also record the two-value form, the way
716
- // borderStyle records its per-side form.
717
- ...["alignItems", "alignContent", "alignSelf", "justifyItems", "justifyContent", "justifySelf"]
718
- .map((property) => [property, "The safe and unsafe overflow-position prefixes are outside the closed set, which holds the alignments themselves"]),
719
- ["placeItems", "The two-value form and the safe and unsafe overflow-position prefixes are outside the closed set; alignItems and justifyItems write the two halves separately"],
720
- ["placeContent", "The two-value form and the safe and unsafe overflow-position prefixes are outside the closed set; alignContent and justifyContent write the two halves separately"],
721
- ["placeSelf", "The two-value form and the safe and unsafe overflow-position prefixes are outside the closed set; alignSelf and justifySelf write the two halves separately"],
722
- // The background layer properties. A checked Look background is one layer,
723
- // which is one design fact met in five places, so it is recorded in all five.
724
- ...["backgroundRepeat", "backgroundAttachment", "backgroundClip", "backgroundOrigin"]
725
- .map((property) => [property, "A comma-separated per-layer list is outside the closed set, because a checked Look background is one layer"]),
726
- // ── D73 rule 187: what the newly closed kinds leave open ───────────────────
727
- // Each of these has a real CSS value space that no set can hold, and each has
728
- // a checked Look spelling that reaches it. Recording that is what keeps the
729
- // closure legible rather than looking like a gap to fill.
730
- ...["border", "borderTop", "borderRight", "borderBottom", "borderLeft", "outline"]
731
- .map((property) => [property, "The width, style and color halves are outside the closed set; they are written with the border(width, color, style) builder"]),
732
- ...["boxShadow", "textShadow"]
733
- .map((property) => [property, "The offsets, blur, spread and color are outside the closed set; they are written with the shadow(x, y, blur, color) builder"]),
734
- ["aspectRatio", "The <ratio> form such as 16 / 9 is outside the closed set; write the ratio as a number"],
735
- ["scale", "The two- and three-axis forms are outside the closed set; a single number scales every axis"],
736
- ["flex", "The multi-value form such as 1 1 auto is outside the closed set; write flexGrow, flexShrink and flexBasis separately"],
737
- ["rotate", "The axis forms such as x 45deg are outside the closed set; a plain angle rotates in the plane"],
738
- ["transition", "Every transition other than none is outside the closed set; it is written with the transition(property, duration, easing, delay) builder, for the same reason a multi-part border string is"],
739
- ...["gridTemplateColumns", "gridTemplateRows"]
740
- .map((property) => [property, "Track lists, subgrid and masonry are outside the closed set; a track list is written with the tracks(...) builder"]),
741
- ...["gridAutoColumns", "gridAutoRows"]
742
- .map((property) => [property, "The minmax() and fit-content() track functions are outside the closed set; they are written with the minmax(...) builder inside tracks(...)"]),
743
- ]);
744
- for (const [property] of LOOK_PARTIAL_KEYWORD_PROPERTIES) {
745
- if (!LOOK_PROPERTY_KEYWORDS.has(property))
746
- throw new Error(`Look property '${property}' records an excluded value space but publishes no keyword set`);
747
- }
748
- /** Real CSS properties deliberately outside the checked Look domain. */
749
- export const LOOK_EXCLUDED_PROPERTIES = new Map([
750
- // D104 rule 1. `font` was a published `text` property, so `font =
751
- // token("--ui-font-body")` type-checked, emitted `font:var(--…)`, and — when
752
- // the token held a size and no family — was invalid at computed-value time,
753
- // which resets every longhand the shorthand owns rather than dropping one
754
- // declaration. Look emits one rule per property, so that reset reached the
755
- // font-weight, font-family and line-height written three lines above it: a
756
- // consumer carried thirty-six such declarations, none of them live and none
757
- // of them diagnosed. Nothing in the value was checkable, because free text is
758
- // what the kind accepted; and nothing needed to be, because this family
759
- // publishes every part of the shorthand as a checked longhand. That is the
760
- // surface D50 rule 92 calls worse than publishing nothing.
761
- ["font", "the font shorthand is owned by its longhands — fontStyle, fontVariant, fontWeight, fontStretch, fontSize, lineHeight and fontFamily — because a shorthand's value is free text no compile can check, and a value that is not a legal shorthand fails at computed-value time and resets all seven, including the ones written beside it. A design token carrying a size belongs in fontSize"],
762
- ["float", "legacy float layout is outside the Grid and Flex layout model"],
763
- ["clear", "legacy float clearing is outside the Grid and Flex layout model"],
764
- ...["tableLayout", "borderCollapse", "borderSpacing", "captionSide", "emptyCells"].map((name) => [name, "table formatting properties remain excluded until a typed table-layout contract has evidence"]),
765
- ...["columns", "columnCount", "columnWidth", "columnFill", "columnRule", "columnRuleColor", "columnRuleStyle", "columnRuleWidth", "columnSpan"].map((name) => [name, "multi-column layout remains excluded until its value and fragmentation model is typed"]),
766
- ...["animationName", "animationDuration", "animationTimingFunction", "animationDelay", "animationIterationCount", "animationDirection", "animationFillMode", "animationPlayState", "animationTimeline", "animationRangeStart", "animationRangeEnd"].map((name) => [name, "animation longhands are owned by keyframes plus animate()"]),
767
- ...["counterIncrement", "counterReset", "counterSet", "quotes"].map((name) => [name, "generated-content counters and quoting are not modeled by checked Look values"]),
768
- ...["breakAfter", "breakBefore", "breakInside", "orphans", "widows"].map((name) => [name, "paged and fragmented media are outside the Web application target"]),
769
- ]);
770
- export function cssPropertyName(name) {
771
- return name.replace(/[A-Z]/gu, (character) => `-${character.toLowerCase()}`);
772
- }
773
- // ── D104 rule 2: which Look properties write the same CSS declaration ─────────
774
- // A Look block reads like a rule, and it is not one. Every entry lowers to its
775
- // own single-declaration rule at equal specificity — `[data-velar-look~="base:
776
- // padding"]{padding:var(--…)}` — and those rules are sorted by condition rank
777
- // first and by *first appearance anywhere in the module* second. So between two
778
- // entries of equal rank the stylesheet's winner is decided by unrelated code:
779
- // a look earlier in the file that happened to mention `paddingTop` puts
780
- // `padding-top` ahead of `padding` for every look in the module, and a block
781
- // that writes `padding` and then `paddingTop` gets the opposite of what it
782
- // reads like. The order LOK-U8 pinned for conditions was never available
783
- // between a shorthand and a longhand it writes.
784
- //
785
- // CSS resolves this with source order. Look cannot, because the rule for a
786
- // property is shared by every look that uses it, so there is no per-block order
787
- // to honour. That leaves one honest answer: two entries in one scope that write
788
- // the same CSS longhand have no winner the author chose, which is exactly the
789
- // defect VEL5039 already refuses when the two entries have the same name. This
790
- // table is what makes the wider case decidable.
791
- //
792
- // Only *direct* containment is written; the closure below derives the rest, so
793
- // `border` reaching `borderTopWidth` through `borderWidth` is not a third place
794
- // to keep in step (D57 rule 134). Logical and physical boxes stay separate
795
- // families: CSS cascades `inset-inline-start` and `left` independently, and
796
- // pretending otherwise would refuse a pair the browser resolves by writing
797
- // mode.
798
- const lookDirectShorthands = [
799
- ["overflow", ["overflowX", "overflowY"]],
800
- ["overscrollBehavior", ["overscrollBehaviorX", "overscrollBehaviorY"]],
801
- ["flex", ["flexGrow", "flexShrink", "flexBasis"]],
802
- ["gap", ["rowGap", "columnGap"]],
803
- ["placeItems", ["alignItems", "justifyItems"]],
804
- ["placeContent", ["alignContent", "justifyContent"]],
805
- ["placeSelf", ["alignSelf", "justifySelf"]],
806
- ["inset", ["top", "right", "bottom", "left"]],
807
- ["insetInline", ["insetInlineStart", "insetInlineEnd"]],
808
- ["insetBlock", ["insetBlockStart", "insetBlockEnd"]],
809
- ["padding", ["paddingTop", "paddingRight", "paddingBottom", "paddingLeft"]],
810
- ["paddingInline", ["paddingInlineStart", "paddingInlineEnd"]],
811
- ["paddingBlock", ["paddingBlockStart", "paddingBlockEnd"]],
812
- ["margin", ["marginTop", "marginRight", "marginBottom", "marginLeft"]],
813
- ["marginInline", ["marginInlineStart", "marginInlineEnd"]],
814
- ["marginBlock", ["marginBlockStart", "marginBlockEnd"]],
815
- ["scrollMargin", ["scrollMarginTop", "scrollMarginRight", "scrollMarginBottom", "scrollMarginLeft"]],
816
- ["scrollPadding", ["scrollPaddingTop", "scrollPaddingRight", "scrollPaddingBottom", "scrollPaddingLeft"]],
817
- ["background", ["backgroundColor", "backgroundImage", "backgroundPosition", "backgroundSize", "backgroundRepeat", "backgroundAttachment", "backgroundOrigin", "backgroundClip"]],
818
- ["border", ["borderWidth", "borderStyle", "borderColor", "borderTop", "borderRight", "borderBottom", "borderLeft"]],
819
- ["borderWidth", ["borderTopWidth", "borderRightWidth", "borderBottomWidth", "borderLeftWidth"]],
820
- ["borderStyle", ["borderTopStyle", "borderRightStyle", "borderBottomStyle", "borderLeftStyle"]],
821
- ["borderColor", ["borderTopColor", "borderRightColor", "borderBottomColor", "borderLeftColor"]],
822
- ["borderTop", ["borderTopWidth", "borderTopStyle", "borderTopColor"]],
823
- ["borderRight", ["borderRightWidth", "borderRightStyle", "borderRightColor"]],
824
- ["borderBottom", ["borderBottomWidth", "borderBottomStyle", "borderBottomColor"]],
825
- ["borderLeft", ["borderLeftWidth", "borderLeftStyle", "borderLeftColor"]],
826
- // `outline` writes the three parts and leaves outlineOffset alone.
827
- ["outline", ["outlineWidth", "outlineStyle", "outlineColor"]],
828
- ["borderRadius", ["borderTopLeftRadius", "borderTopRightRadius", "borderBottomRightRadius", "borderBottomLeftRadius"]],
829
- ["textDecoration", ["textDecorationLine", "textDecorationStyle", "textDecorationColor", "textDecorationThickness"]],
830
- ["listStyle", ["listStyleType", "listStylePosition", "listStyleImage"]],
831
- ["transition", ["transitionProperty", "transitionDuration", "transitionTimingFunction", "transitionDelay"]],
832
- ["gridColumn", ["gridColumnStart", "gridColumnEnd"]],
833
- ["gridRow", ["gridRowStart", "gridRowEnd"]],
834
- ["gridArea", ["gridRow", "gridColumn"]],
835
- ];
836
- function lookShorthandClosure() {
837
- const direct = new Map(lookDirectShorthands.map(([shorthand, longhands]) => [shorthand, longhands]));
838
- const closed = new Map();
839
- const expand = (shorthand, seen) => {
840
- const cached = closed.get(shorthand);
841
- if (cached)
842
- return cached;
843
- if (seen.has(shorthand))
844
- throw new Error(`Look shorthand '${shorthand}' contains itself`);
845
- const inner = new Set([...seen, shorthand]);
846
- const reached = new Set();
847
- for (const longhand of direct.get(shorthand) ?? []) {
848
- reached.add(longhand);
849
- if (direct.has(longhand))
850
- for (const nested of expand(longhand, inner))
851
- reached.add(nested);
852
- }
853
- closed.set(shorthand, reached);
854
- return reached;
855
- };
856
- for (const [shorthand] of direct)
857
- expand(shorthand, new Set());
858
- return closed;
859
- }
860
- /**
861
- * Every Look property a shorthand writes, transitively. `border` reaches all
862
- * twelve side parts through the three per-side shorthands, so a block that
863
- * writes `border` and `borderTopColor` is caught by the same lookup as one that
864
- * writes `border` and `borderWidth`.
865
- */
866
- export const LOOK_SHORTHAND_LONGHANDS = lookShorthandClosure();
867
- for (const [shorthand, longhands] of LOOK_SHORTHAND_LONGHANDS) {
868
- if (!LOOK_PROPERTIES.has(shorthand))
869
- throw new Error(`Look shorthand '${shorthand}' is not a published Look property`);
870
- for (const longhand of longhands) {
871
- if (!LOOK_PROPERTIES.has(longhand))
872
- throw new Error(`Look shorthand '${shorthand}' names '${longhand}', which is not a published Look property`);
873
- }
874
- }
875
- /**
876
- * The two properties' overlap, when one writes what the other does — the
877
- * shorthand first. Null when the two are independent declarations, which is
878
- * every pair the browser resolves on its own.
879
- */
880
- export function lookShorthandOverlap(left, right) {
881
- if (LOOK_SHORTHAND_LONGHANDS.get(left)?.has(right) === true)
882
- return { shorthand: left, longhand: right };
883
- if (LOOK_SHORTHAND_LONGHANDS.get(right)?.has(left) === true)
884
- return { shorthand: right, longhand: left };
885
- return null;
886
- }
887
- /**
888
- * What a refusal offers instead of the pair: the shorthand's own longhands, so
889
- * the author can write the one they meant to override beside its siblings. The
890
- * list is the direct level rather than the closure — `border` answers with
891
- * borderWidth, borderStyle and borderColor rather than with all twelve side
892
- * parts, because that is the level a reader replaces it at.
893
- */
894
- export function lookShorthandParts(shorthand) {
895
- return lookDirectShorthands.find(([name]) => name === shorthand)?.[1] ?? [];
896
- }
897
- function nameDistance(left, right) {
898
- if (left.length === right.length) {
899
- const mismatches = [];
900
- for (let index = 0; index < left.length; index += 1)
901
- if (left[index] !== right[index])
902
- mismatches.push(index);
903
- if (mismatches.length === 2 && mismatches[1] === mismatches[0] + 1
904
- && left[mismatches[0]] === right[mismatches[1]] && left[mismatches[1]] === right[mismatches[0]])
905
- return 1;
906
- }
907
- const previous = Array.from({ length: right.length + 1 }, (_, index) => index);
908
- for (let row = 1; row <= left.length; row += 1) {
909
- let diagonal = previous[0];
910
- previous[0] = row;
911
- for (let column = 1; column <= right.length; column += 1) {
912
- const candidate = Math.min(previous[column] + 1, previous[column - 1] + 1, diagonal + (left[row - 1] === right[column - 1] ? 0 : 1));
913
- diagonal = previous[column];
914
- previous[column] = candidate;
915
- }
916
- }
917
- return previous[right.length];
918
- }
919
- /**
920
- * The closest vocabulary entry to a misspelling, or null when nothing is close
921
- * enough to name. Case differences and one or two edits count as near misses;
922
- * anything further apart is a different word and gets the full vocabulary.
923
- */
924
- export function nearestLookName(name, vocabulary) {
925
- let best = null;
926
- let bestDistance = Number.POSITIVE_INFINITY;
927
- const limit = 2;
928
- for (const candidate of vocabulary) {
929
- const distance = nameDistance(name.toLowerCase(), candidate.toLowerCase());
930
- if (distance < bestDistance || (distance === bestDistance && best !== null && candidate < best)) {
931
- best = candidate;
932
- bestDistance = distance;
933
- }
934
- }
935
- return best !== null && bestDistance <= limit ? best : null;
936
- }
9
+ * - `look/units.ts` the unit suffixes and the type names they carry
10
+ * - `look/media.ts` media subjects, `@hook` states, `@target` targets
11
+ * - `look/builders.ts` every `velar/look` builder's call shape and numeric domain
12
+ * - `look/tokens.ts` checked design-token references (D103)
13
+ * - `look/animation.ts` easings, directions, fills, what cannot interpolate
14
+ * - `look/properties.ts` the published property roster and each one's value kind
15
+ * - `look/keyword-sets.ts` the shared pieces the keyword table is assembled from
16
+ * - `look/css-functions.ts` free-text CSS functions, and the transition vocabulary
17
+ * - `look/keywords.ts` each property's closed set, and what the closure leaves open
18
+ * - `look/shorthands.ts` which properties write the same CSS declaration
19
+ * - `look/naming.ts` the CSS spelling of a Look name, and nearest-name search
20
+ */
21
+ export { LOOK_ARITHMETIC_HINT, LOOK_NUMERIC_TYPE_NAMES, LOOK_PUBLIC_TYPE_NAMES, LOOK_UNITLESS_PROPERTIES, LOOK_UNIT_TYPES } from "./look/units.js";
22
+ export { LOOK_ABSENT_MEDIA_SUBJECTS, LOOK_HOOKS, LOOK_MEDIA_LENGTH_UNITS, LOOK_MEDIA_SUBJECTS, LOOK_TARGETS } from "./look/media.js";
23
+ export { LOOK_BORDER_STYLE_NAMES, LOOK_BUILDERS, LOOK_BUILDER_NUMERIC_RANGES, LOOK_BUILDER_SIGNATURES, LOOK_LENGTH_BUILDERS } from "./look/builders.js";
24
+ export { LOOK_TOKEN_NAME_PATTERN, LOOK_TOKEN_NAME_RULE, LOOK_TOKEN_NO_FALLBACK_GUIDANCE, isLookTokenName, isLookVarReference, lookTokenReference, lookVarReferenceName } from "./look/tokens.js";
25
+ export { LOOK_ANIMATION_DIRECTIONS, LOOK_ANIMATION_EASINGS, LOOK_ANIMATION_FILLS, LOOK_NON_ANIMATABLE_PROPERTIES } from "./look/animation.js";
26
+ export { LOOK_PROPERTIES, LOOK_PROPERTY_GROUPS, LOOK_PROPERTY_VALUE_KINDS, lookPropertyDocumentationKey } from "./look/properties.js";
27
+ export { LOOK_COLOR_KEYWORDS, LOOK_CSS_WIDE_KEYWORDS, LOOK_SHARED_METRIC_KEYWORDS } from "./look/keyword-sets.js";
28
+ export { LOOK_PROPERTY_CSS_FUNCTIONS, LOOK_TRANSITION_PROPERTY_KEYWORDS } from "./look/css-functions.js";
29
+ export { LOOK_EXCLUDED_PROPERTIES, LOOK_KEYWORD_DECIDED_KINDS, LOOK_KEYWORD_LISTING_LIMIT, LOOK_LARGE_KEYWORD_SETS, LOOK_PARTIAL_KEYWORD_PROPERTIES, LOOK_PROPERTY_KEYWORDS, lookBuilderSupportsProperty, lookOwnKeywords, lookPropertyCompletionKeywords } from "./look/keywords.js";
30
+ export { LOOK_SHORTHAND_LONGHANDS, lookShorthandOverlap, lookShorthandParts } from "./look/shorthands.js";
31
+ export { cssPropertyName, nearestLookName } from "./look/naming.js";
937
32
  //# sourceMappingURL=look.js.map