@bookklik/senangstart-css 0.1.8 → 0.2.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 (341) hide show
  1. package/README.md +38 -0
  2. package/dist/senangstart-css.js +2269 -1955
  3. package/dist/senangstart-css.min.js +141 -1479
  4. package/docs/.vitepress/config.js +2 -0
  5. package/docs/guide/responsive.md +25 -0
  6. package/docs/index.md +1 -1
  7. package/docs/ms/guide/responsive.md +25 -0
  8. package/docs/ms/index.md +1 -1
  9. package/docs/ms/reference/breakpoints.md +23 -0
  10. package/docs/ms/reference/layout/align-content.md +57 -4
  11. package/docs/ms/reference/layout/align-items.md +81 -4
  12. package/docs/ms/reference/layout/align-self.md +25 -4
  13. package/docs/ms/reference/layout/aspect-ratio.md +27 -8
  14. package/docs/ms/reference/layout/border-collapse.md +81 -4
  15. package/docs/ms/reference/layout/border-spacing.md +43 -8
  16. package/docs/ms/reference/layout/box-sizing.md +21 -4
  17. package/docs/ms/reference/layout/caption-side.md +69 -4
  18. package/docs/ms/reference/layout/columns.md +21 -4
  19. package/docs/ms/reference/layout/container.md +21 -4
  20. package/docs/ms/reference/layout/display.md +39 -7
  21. package/docs/ms/reference/layout/flex-basis.md +29 -8
  22. package/docs/ms/reference/layout/flex-direction.md +81 -4
  23. package/docs/ms/reference/layout/flex-items.md +51 -4
  24. package/docs/ms/reference/layout/flex-wrap.md +55 -4
  25. package/docs/ms/reference/layout/flex.md +54 -7
  26. package/docs/ms/reference/layout/float-clear.md +23 -4
  27. package/docs/ms/reference/layout/grid-auto-flow.md +57 -4
  28. package/docs/ms/reference/layout/grid-auto-sizing.md +25 -4
  29. package/docs/ms/reference/layout/grid-column-span.md +59 -4
  30. package/docs/ms/reference/layout/grid-columns.md +61 -4
  31. package/docs/ms/reference/layout/grid-row-span.md +29 -4
  32. package/docs/ms/reference/layout/grid-rows.md +31 -4
  33. package/docs/ms/reference/layout/inset.md +56 -7
  34. package/docs/ms/reference/layout/isolation.md +21 -4
  35. package/docs/ms/reference/layout/justify-content.md +81 -4
  36. package/docs/ms/reference/layout/justify-items.md +25 -4
  37. package/docs/ms/reference/layout/justify-self.md +25 -4
  38. package/docs/ms/reference/layout/object-fit.md +57 -4
  39. package/docs/ms/reference/layout/object-position.md +29 -8
  40. package/docs/ms/reference/layout/order.md +53 -4
  41. package/docs/ms/reference/layout/overflow.md +45 -4
  42. package/docs/ms/reference/layout/overscroll.md +21 -4
  43. package/docs/ms/reference/layout/place-content.md +23 -4
  44. package/docs/ms/reference/layout/place-items.md +25 -4
  45. package/docs/ms/reference/layout/place-self.md +25 -4
  46. package/docs/ms/reference/layout/position.md +47 -4
  47. package/docs/ms/reference/layout/shorthand-alignment.md +47 -4
  48. package/docs/ms/reference/layout/table-layout.md +69 -4
  49. package/docs/ms/reference/layout/visibility.md +25 -4
  50. package/docs/ms/reference/layout/z-index.md +27 -4
  51. package/docs/ms/reference/space/gap.md +71 -7
  52. package/docs/ms/reference/space/height.md +61 -7
  53. package/docs/ms/reference/space/margin.md +61 -7
  54. package/docs/ms/reference/space/padding.md +65 -7
  55. package/docs/ms/reference/space/width.md +61 -7
  56. package/docs/ms/reference/visual/accent-color.md +29 -8
  57. package/docs/ms/reference/visual/animation-builtin.md +29 -8
  58. package/docs/ms/reference/visual/animation-delay.md +25 -8
  59. package/docs/ms/reference/visual/animation-direction.md +25 -4
  60. package/docs/ms/reference/visual/animation-duration.md +27 -8
  61. package/docs/ms/reference/visual/animation-fill.md +25 -4
  62. package/docs/ms/reference/visual/animation-iteration.md +23 -4
  63. package/docs/ms/reference/visual/animation-play.md +23 -4
  64. package/docs/ms/reference/visual/appearance.md +23 -4
  65. package/docs/ms/reference/visual/backdrop-blur.md +29 -8
  66. package/docs/ms/reference/visual/backdrop-brightness.md +29 -8
  67. package/docs/ms/reference/visual/backdrop-contrast.md +29 -8
  68. package/docs/ms/reference/visual/backdrop-grayscale.md +27 -8
  69. package/docs/ms/reference/visual/backdrop-hue-rotate.md +29 -8
  70. package/docs/ms/reference/visual/backdrop-invert.md +27 -8
  71. package/docs/ms/reference/visual/backdrop-opacity.md +29 -8
  72. package/docs/ms/reference/visual/backdrop-saturate.md +29 -8
  73. package/docs/ms/reference/visual/backdrop-sepia.md +27 -8
  74. package/docs/ms/reference/visual/background-attachment.md +23 -4
  75. package/docs/ms/reference/visual/background-blend-mode.md +25 -4
  76. package/docs/ms/reference/visual/background-clip.md +21 -4
  77. package/docs/ms/reference/visual/background-color.md +33 -8
  78. package/docs/ms/reference/visual/background-image.md +27 -8
  79. package/docs/ms/reference/visual/background-origin.md +25 -4
  80. package/docs/ms/reference/visual/background-position.md +29 -8
  81. package/docs/ms/reference/visual/background-repeat.md +25 -4
  82. package/docs/ms/reference/visual/background-size.md +29 -8
  83. package/docs/ms/reference/visual/blend-modes.md +23 -4
  84. package/docs/ms/reference/visual/border-radius.md +36 -4
  85. package/docs/ms/reference/visual/border-style.md +25 -4
  86. package/docs/ms/reference/visual/border-width.md +29 -8
  87. package/docs/ms/reference/visual/border.md +56 -7
  88. package/docs/ms/reference/visual/box-shadow.md +34 -4
  89. package/docs/ms/reference/visual/caret-color.md +25 -8
  90. package/docs/ms/reference/visual/color-scheme.md +23 -4
  91. package/docs/ms/reference/visual/cursor.md +25 -4
  92. package/docs/ms/reference/visual/field-sizing.md +23 -4
  93. package/docs/ms/reference/visual/fill.md +29 -8
  94. package/docs/ms/reference/visual/filter-blur.md +29 -8
  95. package/docs/ms/reference/visual/filter-brightness.md +29 -8
  96. package/docs/ms/reference/visual/filter-contrast.md +29 -8
  97. package/docs/ms/reference/visual/filter-drop-shadow.md +29 -8
  98. package/docs/ms/reference/visual/filter-grayscale.md +29 -8
  99. package/docs/ms/reference/visual/filter-hue-rotate.md +29 -8
  100. package/docs/ms/reference/visual/filter-invert.md +27 -8
  101. package/docs/ms/reference/visual/filter-saturate.md +29 -8
  102. package/docs/ms/reference/visual/filter-sepia.md +29 -8
  103. package/docs/ms/reference/visual/font-family.md +25 -4
  104. package/docs/ms/reference/visual/font-smoothing.md +23 -4
  105. package/docs/ms/reference/visual/font-style.md +23 -4
  106. package/docs/ms/reference/visual/font-variant-numeric.md +23 -4
  107. package/docs/ms/reference/visual/font-weight.md +35 -4
  108. package/docs/ms/reference/visual/forced-color-adjust.md +23 -4
  109. package/docs/ms/reference/visual/hyphens.md +25 -4
  110. package/docs/ms/reference/visual/letter-spacing.md +29 -8
  111. package/docs/ms/reference/visual/line-clamp.md +29 -8
  112. package/docs/ms/reference/visual/line-height.md +29 -8
  113. package/docs/ms/reference/visual/list-style.md +25 -4
  114. package/docs/ms/reference/visual/mask.md +25 -8
  115. package/docs/ms/reference/visual/opacity.md +27 -4
  116. package/docs/ms/reference/visual/outline.md +25 -8
  117. package/docs/ms/reference/visual/pointer-events.md +23 -4
  118. package/docs/ms/reference/visual/resize.md +27 -4
  119. package/docs/ms/reference/visual/scroll-behavior.md +23 -4
  120. package/docs/ms/reference/visual/scroll-margin.md +25 -8
  121. package/docs/ms/reference/visual/scroll-padding.md +25 -8
  122. package/docs/ms/reference/visual/scroll-snap-align.md +25 -4
  123. package/docs/ms/reference/visual/scroll-snap-stop.md +23 -4
  124. package/docs/ms/reference/visual/scroll-snap-type.md +25 -4
  125. package/docs/ms/reference/visual/state-prefixes.md +21 -4
  126. package/docs/ms/reference/visual/stroke-width.md +29 -8
  127. package/docs/ms/reference/visual/stroke.md +27 -8
  128. package/docs/ms/reference/visual/text-alignment.md +25 -4
  129. package/docs/ms/reference/visual/text-color.md +31 -8
  130. package/docs/ms/reference/visual/text-decoration.md +23 -4
  131. package/docs/ms/reference/visual/text-indent.md +25 -8
  132. package/docs/ms/reference/visual/text-overflow.md +21 -4
  133. package/docs/ms/reference/visual/text-shadow.md +25 -8
  134. package/docs/ms/reference/visual/text-size.md +41 -7
  135. package/docs/ms/reference/visual/text-transform.md +25 -4
  136. package/docs/ms/reference/visual/text-wrap.md +25 -4
  137. package/docs/ms/reference/visual/touch-action.md +25 -4
  138. package/docs/ms/reference/visual/transform-backface.md +23 -4
  139. package/docs/ms/reference/visual/transform-origin.md +27 -8
  140. package/docs/ms/reference/visual/transform-perspective-origin.md +25 -8
  141. package/docs/ms/reference/visual/transform-perspective.md +25 -8
  142. package/docs/ms/reference/visual/transform-rotate.md +29 -8
  143. package/docs/ms/reference/visual/transform-scale.md +29 -8
  144. package/docs/ms/reference/visual/transform-skew.md +29 -8
  145. package/docs/ms/reference/visual/transform-style.md +23 -4
  146. package/docs/ms/reference/visual/transform-translate.md +29 -8
  147. package/docs/ms/reference/visual/transition-delay.md +25 -8
  148. package/docs/ms/reference/visual/transition-duration.md +27 -8
  149. package/docs/ms/reference/visual/transition-property.md +21 -4
  150. package/docs/ms/reference/visual/transition-timing.md +29 -8
  151. package/docs/ms/reference/visual/typography-keywords.md +27 -4
  152. package/docs/ms/reference/visual/user-select.md +23 -4
  153. package/docs/ms/reference/visual/vertical-align.md +25 -4
  154. package/docs/ms/reference/visual/whitespace.md +25 -4
  155. package/docs/ms/reference/visual/will-change.md +23 -4
  156. package/docs/ms/reference/visual/word-break.md +25 -4
  157. package/docs/public/assets/senangstart-css-logo.svg +1 -0
  158. package/docs/reference/breakpoints.md +23 -0
  159. package/docs/reference/layout/align-content.md +57 -4
  160. package/docs/reference/layout/align-items.md +81 -4
  161. package/docs/reference/layout/align-self.md +25 -4
  162. package/docs/reference/layout/aspect-ratio.md +27 -8
  163. package/docs/reference/layout/border-collapse.md +81 -4
  164. package/docs/reference/layout/border-spacing.md +43 -8
  165. package/docs/reference/layout/box-sizing.md +21 -4
  166. package/docs/reference/layout/caption-side.md +69 -4
  167. package/docs/reference/layout/columns.md +21 -4
  168. package/docs/reference/layout/container.md +21 -4
  169. package/docs/reference/layout/display.md +39 -7
  170. package/docs/reference/layout/flex-basis.md +29 -8
  171. package/docs/reference/layout/flex-direction.md +81 -4
  172. package/docs/reference/layout/flex-items.md +51 -4
  173. package/docs/reference/layout/flex-wrap.md +55 -4
  174. package/docs/reference/layout/flex.md +54 -7
  175. package/docs/reference/layout/float-clear.md +23 -4
  176. package/docs/reference/layout/grid-auto-flow.md +57 -4
  177. package/docs/reference/layout/grid-auto-sizing.md +25 -4
  178. package/docs/reference/layout/grid-column-span.md +59 -4
  179. package/docs/reference/layout/grid-columns.md +61 -4
  180. package/docs/reference/layout/grid-row-span.md +29 -4
  181. package/docs/reference/layout/grid-rows.md +31 -4
  182. package/docs/reference/layout/inset.md +56 -7
  183. package/docs/reference/layout/isolation.md +21 -4
  184. package/docs/reference/layout/justify-content.md +81 -4
  185. package/docs/reference/layout/justify-items.md +25 -4
  186. package/docs/reference/layout/justify-self.md +25 -4
  187. package/docs/reference/layout/object-fit.md +57 -4
  188. package/docs/reference/layout/object-position.md +29 -8
  189. package/docs/reference/layout/order.md +53 -4
  190. package/docs/reference/layout/overflow.md +45 -4
  191. package/docs/reference/layout/overscroll.md +21 -4
  192. package/docs/reference/layout/place-content.md +23 -4
  193. package/docs/reference/layout/place-items.md +25 -4
  194. package/docs/reference/layout/place-self.md +25 -4
  195. package/docs/reference/layout/position.md +47 -4
  196. package/docs/reference/layout/shorthand-alignment.md +47 -4
  197. package/docs/reference/layout/table-layout.md +69 -4
  198. package/docs/reference/layout/visibility.md +25 -4
  199. package/docs/reference/layout/z-index.md +27 -4
  200. package/docs/reference/space/gap.md +71 -7
  201. package/docs/reference/space/height.md +61 -7
  202. package/docs/reference/space/margin.md +61 -7
  203. package/docs/reference/space/padding.md +65 -7
  204. package/docs/reference/space/width.md +61 -7
  205. package/docs/reference/visual/accent-color.md +29 -8
  206. package/docs/reference/visual/animation-builtin.md +29 -8
  207. package/docs/reference/visual/animation-delay.md +25 -8
  208. package/docs/reference/visual/animation-direction.md +25 -4
  209. package/docs/reference/visual/animation-duration.md +27 -8
  210. package/docs/reference/visual/animation-fill.md +25 -4
  211. package/docs/reference/visual/animation-iteration.md +23 -4
  212. package/docs/reference/visual/animation-play.md +23 -4
  213. package/docs/reference/visual/appearance.md +23 -4
  214. package/docs/reference/visual/backdrop-blur.md +29 -8
  215. package/docs/reference/visual/backdrop-brightness.md +29 -8
  216. package/docs/reference/visual/backdrop-contrast.md +29 -8
  217. package/docs/reference/visual/backdrop-grayscale.md +27 -8
  218. package/docs/reference/visual/backdrop-hue-rotate.md +29 -8
  219. package/docs/reference/visual/backdrop-invert.md +27 -8
  220. package/docs/reference/visual/backdrop-opacity.md +29 -8
  221. package/docs/reference/visual/backdrop-saturate.md +29 -8
  222. package/docs/reference/visual/backdrop-sepia.md +27 -8
  223. package/docs/reference/visual/background-attachment.md +23 -4
  224. package/docs/reference/visual/background-blend-mode.md +25 -4
  225. package/docs/reference/visual/background-clip.md +21 -4
  226. package/docs/reference/visual/background-color.md +33 -8
  227. package/docs/reference/visual/background-image.md +27 -8
  228. package/docs/reference/visual/background-origin.md +25 -4
  229. package/docs/reference/visual/background-position.md +29 -8
  230. package/docs/reference/visual/background-repeat.md +25 -4
  231. package/docs/reference/visual/background-size.md +29 -8
  232. package/docs/reference/visual/blend-modes.md +23 -4
  233. package/docs/reference/visual/border-radius.md +36 -4
  234. package/docs/reference/visual/border-style.md +25 -4
  235. package/docs/reference/visual/border-width.md +29 -8
  236. package/docs/reference/visual/border.md +56 -7
  237. package/docs/reference/visual/box-shadow.md +34 -4
  238. package/docs/reference/visual/caret-color.md +25 -8
  239. package/docs/reference/visual/color-scheme.md +23 -4
  240. package/docs/reference/visual/cursor.md +25 -4
  241. package/docs/reference/visual/field-sizing.md +23 -4
  242. package/docs/reference/visual/fill.md +29 -8
  243. package/docs/reference/visual/filter-blur.md +29 -8
  244. package/docs/reference/visual/filter-brightness.md +29 -8
  245. package/docs/reference/visual/filter-contrast.md +29 -8
  246. package/docs/reference/visual/filter-drop-shadow.md +29 -8
  247. package/docs/reference/visual/filter-grayscale.md +29 -8
  248. package/docs/reference/visual/filter-hue-rotate.md +29 -8
  249. package/docs/reference/visual/filter-invert.md +27 -8
  250. package/docs/reference/visual/filter-saturate.md +29 -8
  251. package/docs/reference/visual/filter-sepia.md +29 -8
  252. package/docs/reference/visual/font-family.md +25 -4
  253. package/docs/reference/visual/font-smoothing.md +23 -4
  254. package/docs/reference/visual/font-style.md +23 -4
  255. package/docs/reference/visual/font-variant-numeric.md +23 -4
  256. package/docs/reference/visual/font-weight.md +35 -4
  257. package/docs/reference/visual/forced-color-adjust.md +23 -4
  258. package/docs/reference/visual/hyphens.md +25 -4
  259. package/docs/reference/visual/letter-spacing.md +29 -8
  260. package/docs/reference/visual/line-clamp.md +29 -8
  261. package/docs/reference/visual/line-height.md +29 -8
  262. package/docs/reference/visual/list-style.md +25 -4
  263. package/docs/reference/visual/mask.md +25 -8
  264. package/docs/reference/visual/opacity.md +27 -4
  265. package/docs/reference/visual/outline.md +25 -8
  266. package/docs/reference/visual/pointer-events.md +23 -4
  267. package/docs/reference/visual/resize.md +27 -4
  268. package/docs/reference/visual/scroll-behavior.md +23 -4
  269. package/docs/reference/visual/scroll-margin.md +25 -8
  270. package/docs/reference/visual/scroll-padding.md +25 -8
  271. package/docs/reference/visual/scroll-snap-align.md +25 -4
  272. package/docs/reference/visual/scroll-snap-stop.md +23 -4
  273. package/docs/reference/visual/scroll-snap-type.md +25 -4
  274. package/docs/reference/visual/state-prefixes.md +21 -4
  275. package/docs/reference/visual/stroke-width.md +29 -8
  276. package/docs/reference/visual/stroke.md +27 -8
  277. package/docs/reference/visual/text-alignment.md +25 -4
  278. package/docs/reference/visual/text-color.md +31 -8
  279. package/docs/reference/visual/text-decoration.md +23 -4
  280. package/docs/reference/visual/text-indent.md +25 -8
  281. package/docs/reference/visual/text-overflow.md +21 -4
  282. package/docs/reference/visual/text-shadow.md +25 -8
  283. package/docs/reference/visual/text-size.md +41 -7
  284. package/docs/reference/visual/text-transform.md +25 -4
  285. package/docs/reference/visual/text-wrap.md +25 -4
  286. package/docs/reference/visual/touch-action.md +25 -4
  287. package/docs/reference/visual/transform-backface.md +23 -4
  288. package/docs/reference/visual/transform-origin.md +27 -8
  289. package/docs/reference/visual/transform-perspective-origin.md +25 -8
  290. package/docs/reference/visual/transform-perspective.md +25 -8
  291. package/docs/reference/visual/transform-rotate.md +29 -8
  292. package/docs/reference/visual/transform-scale.md +29 -8
  293. package/docs/reference/visual/transform-skew.md +29 -8
  294. package/docs/reference/visual/transform-style.md +23 -4
  295. package/docs/reference/visual/transform-translate.md +29 -8
  296. package/docs/reference/visual/transition-delay.md +25 -8
  297. package/docs/reference/visual/transition-duration.md +27 -8
  298. package/docs/reference/visual/transition-property.md +21 -4
  299. package/docs/reference/visual/transition-timing.md +29 -8
  300. package/docs/reference/visual/typography-keywords.md +27 -4
  301. package/docs/reference/visual/user-select.md +23 -4
  302. package/docs/reference/visual/vertical-align.md +25 -4
  303. package/docs/reference/visual/whitespace.md +25 -4
  304. package/docs/reference/visual/will-change.md +23 -4
  305. package/docs/reference/visual/word-break.md +25 -4
  306. package/package.json +2 -1
  307. package/playground/jit-tw-mix-test.html +238 -0
  308. package/playground/tw-convertor.html +696 -0
  309. package/scripts/build-dist.js +34 -29
  310. package/scripts/bundle-jit.js +45 -0
  311. package/scripts/convert-tailwind.js +759 -0
  312. package/scripts/generate-docs.js +65 -16
  313. package/src/cdn/jit.js +313 -102
  314. package/src/cli/commands/build.js +14 -6
  315. package/src/cli/commands/dev.js +28 -10
  316. package/src/compiler/generators/css.js +187 -28
  317. package/src/compiler/parser.js +23 -10
  318. package/src/compiler/tokenizer.js +19 -137
  319. package/src/config/defaults.js +45 -18
  320. package/src/core/constants.js +427 -0
  321. package/src/core/tokenizer-core.js +233 -0
  322. package/src/definitions/layout-alignment.js +210 -0
  323. package/src/definitions/layout-flex.js +155 -0
  324. package/src/definitions/layout-grid.js +134 -0
  325. package/src/definitions/layout-positioning.js +64 -0
  326. package/src/definitions/layout-table.js +129 -0
  327. package/src/definitions/layout-utilities.js +164 -0
  328. package/src/definitions/space.js +172 -0
  329. package/src/definitions/visual-backgrounds.js +231 -0
  330. package/src/definitions/visual-borders.js +66 -0
  331. package/src/definitions/visual-filters.js +111 -0
  332. package/src/definitions/visual-interactivity.js +159 -0
  333. package/src/definitions/visual-svg.js +41 -0
  334. package/src/definitions/visual-transform3d.js +74 -0
  335. package/src/definitions/visual-transforms.js +69 -0
  336. package/src/definitions/visual-transitions.js +144 -0
  337. package/src/definitions/visual-typography.js +214 -0
  338. package/src/definitions/visual.js +306 -1
  339. package/tests/integration/compiler.test.js +63 -2
  340. package/tests/unit/convert-tailwind.test.js +324 -0
  341. package/tests/unit/security.test.js +206 -0
@@ -1,1955 +1,2269 @@
1
- /**
2
- * SenangStart CSS - Browser JIT Runtime
3
- * Zero-config, browser-based CSS compilation
4
- *
5
- * Usage:
6
- * <script src="https://unpkg.com/@bookklik/senangstart-css/dist/senangstart-css.min.js"></script>
7
- *
8
- * Or with custom config:
9
- * <script type="senangstart/config">{ "theme": { "colors": { "brand": "#8B5CF6" } } }</script>
10
- * <script src="https://unpkg.com/@bookklik/senangstart-css/dist/senangstart-css.min.js"></script>
11
- */
12
-
13
- (function() {
14
- 'use strict';
15
-
16
- // ============================================
17
- // DEFAULT CONFIGURATION
18
- // ============================================
19
-
20
- const defaultConfig = {
21
- theme: {
22
- spacing: {
23
- 'none': '0px',
24
- 'tiny': '4px',
25
- 'small': '8px',
26
- 'medium': '16px',
27
- 'big': '32px',
28
- 'giant': '64px',
29
- 'vast': '128px'
30
- },
31
- radius: {
32
- 'none': '0px',
33
- 'small': '4px',
34
- 'medium': '8px',
35
- 'big': '16px',
36
- 'round': '9999px'
37
- },
38
- shadow: {
39
- 'none': 'none',
40
- 'small': '0 1px 2px rgba(0,0,0,0.05)',
41
- 'medium': '0 4px 6px rgba(0,0,0,0.1)',
42
- 'big': '0 10px 15px rgba(0,0,0,0.15)',
43
- 'giant': '0 25px 50px rgba(0,0,0,0.25)'
44
- },
45
- fontSize: {
46
- 'tiny': '12px',
47
- 'small': '14px',
48
- 'medium': '16px',
49
- 'big': '20px',
50
- 'giant': '32px',
51
- 'vast': '48px'
52
- },
53
- fontWeight: {
54
- 'normal': '400',
55
- 'medium': '500',
56
- 'bold': '700'
57
- },
58
- screens: {
59
- 'mob': '480px',
60
- 'tab': '768px',
61
- 'lap': '1024px',
62
- 'desk': '1280px'
63
- },
64
- colors: {
65
- // Base colors
66
- 'white': '#FFFFFF',
67
- 'black': '#000000',
68
-
69
- // Brand/Semantic colors
70
- 'grey': '#6B7280',
71
- 'dark': '#3E4A5D',
72
- 'light': '#DBEAFE',
73
- 'primary': '#2563EB',
74
- 'secondary': '#DBEAFE',
75
- 'success': '#10B981',
76
- 'warning': '#F59E0B',
77
- 'danger': '#EF4444',
78
-
79
- // Red
80
- 'red-50': '#FEF2F2', 'red-100': '#FEE2E2', 'red-200': '#FECACA', 'red-300': '#FCA5A5', 'red-400': '#F87171',
81
- 'red-500': '#EF4444', 'red-600': '#DC2626', 'red-700': '#B91C1C', 'red-800': '#991B1B', 'red-900': '#7F1D1D', 'red-950': '#450A0A',
82
-
83
- // Orange
84
- 'orange-50': '#FFF7ED', 'orange-100': '#FFEDD5', 'orange-200': '#FED7AA', 'orange-300': '#FDBA74', 'orange-400': '#FB923C',
85
- 'orange-500': '#F97316', 'orange-600': '#EA580C', 'orange-700': '#C2410C', 'orange-800': '#9A3412', 'orange-900': '#7C2D12', 'orange-950': '#431407',
86
-
87
- // Amber
88
- 'amber-50': '#FFFBEB', 'amber-100': '#FEF3C7', 'amber-200': '#FDE68A', 'amber-300': '#FCD34D', 'amber-400': '#FBBF24',
89
- 'amber-500': '#F59E0B', 'amber-600': '#D97706', 'amber-700': '#B45309', 'amber-800': '#92400E', 'amber-900': '#78350F', 'amber-950': '#451A03',
90
-
91
- // Yellow
92
- 'yellow-50': '#FEFCE8', 'yellow-100': '#FEF9C3', 'yellow-200': '#FEF08A', 'yellow-300': '#FDE047', 'yellow-400': '#FACC15',
93
- 'yellow-500': '#EAB308', 'yellow-600': '#CA8A04', 'yellow-700': '#A16207', 'yellow-800': '#854D0E', 'yellow-900': '#713F12', 'yellow-950': '#422006',
94
-
95
- // Lime
96
- 'lime-50': '#F7FEE7', 'lime-100': '#ECFCCB', 'lime-200': '#D9F99D', 'lime-300': '#BEF264', 'lime-400': '#A3E635',
97
- 'lime-500': '#84CC16', 'lime-600': '#65A30D', 'lime-700': '#4D7C0F', 'lime-800': '#3F6212', 'lime-900': '#365314', 'lime-950': '#1A2E05',
98
-
99
- // Green
100
- 'green-50': '#F0FDF4', 'green-100': '#DCFCE7', 'green-200': '#BBF7D0', 'green-300': '#86EFAC', 'green-400': '#4ADE80',
101
- 'green-500': '#22C55E', 'green-600': '#16A34A', 'green-700': '#15803D', 'green-800': '#166534', 'green-900': '#14532D', 'green-950': '#052E16',
102
-
103
- // Emerald
104
- 'emerald-50': '#ECFDF5', 'emerald-100': '#D1FAE5', 'emerald-200': '#A7F3D0', 'emerald-300': '#6EE7B7', 'emerald-400': '#34D399',
105
- 'emerald-500': '#10B981', 'emerald-600': '#059669', 'emerald-700': '#047857', 'emerald-800': '#065F46', 'emerald-900': '#064E3B', 'emerald-950': '#022C22',
106
-
107
- // Teal
108
- 'teal-50': '#F0FDFA', 'teal-100': '#CCFBF1', 'teal-200': '#99F6E4', 'teal-300': '#5EEAD4', 'teal-400': '#2DD4BF',
109
- 'teal-500': '#14B8A6', 'teal-600': '#0D9488', 'teal-700': '#0F766E', 'teal-800': '#115E59', 'teal-900': '#134E4A', 'teal-950': '#042F2E',
110
-
111
- // Cyan
112
- 'cyan-50': '#ECFEFF', 'cyan-100': '#CFFAFE', 'cyan-200': '#A5F3FC', 'cyan-300': '#67E8F9', 'cyan-400': '#22D3EE',
113
- 'cyan-500': '#06B6D4', 'cyan-600': '#0891B2', 'cyan-700': '#0E7490', 'cyan-800': '#155E75', 'cyan-900': '#164E63', 'cyan-950': '#083344',
114
-
115
- // Sky
116
- 'sky-50': '#F0F9FF', 'sky-100': '#E0F2FE', 'sky-200': '#BAE6FD', 'sky-300': '#7DD3FC', 'sky-400': '#38BDF8',
117
- 'sky-500': '#0EA5E9', 'sky-600': '#0284C7', 'sky-700': '#0369A1', 'sky-800': '#075985', 'sky-900': '#0C4A6E', 'sky-950': '#082F49',
118
-
119
- // Blue
120
- 'blue-50': '#EFF6FF', 'blue-100': '#DBEAFE', 'blue-200': '#BFDBFE', 'blue-300': '#93C5FD', 'blue-400': '#60A5FA',
121
- 'blue-500': '#3B82F6', 'blue-600': '#2563EB', 'blue-700': '#1D4ED8', 'blue-800': '#1E40AF', 'blue-900': '#1E3A8A', 'blue-950': '#172554',
122
-
123
- // Indigo
124
- 'indigo-50': '#EEF2FF', 'indigo-100': '#E0E7FF', 'indigo-200': '#C7D2FE', 'indigo-300': '#A5B4FC', 'indigo-400': '#818CF8',
125
- 'indigo-500': '#6366F1', 'indigo-600': '#4F46E5', 'indigo-700': '#4338CA', 'indigo-800': '#3730A3', 'indigo-900': '#312E81', 'indigo-950': '#1E1B4B',
126
-
127
- // Violet
128
- 'violet-50': '#F5F3FF', 'violet-100': '#EDE9FE', 'violet-200': '#DDD6FE', 'violet-300': '#C4B5FD', 'violet-400': '#A78BFA',
129
- 'violet-500': '#8B5CF6', 'violet-600': '#7C3AED', 'violet-700': '#6D28D9', 'violet-800': '#5B21B6', 'violet-900': '#4C1D95', 'violet-950': '#2E1065',
130
-
131
- // Purple
132
- 'purple-50': '#FAF5FF', 'purple-100': '#F3E8FF', 'purple-200': '#E9D5FF', 'purple-300': '#D8B4FE', 'purple-400': '#C084FC',
133
- 'purple-500': '#A855F7', 'purple-600': '#9333EA', 'purple-700': '#7E22CE', 'purple-800': '#6B21A8', 'purple-900': '#581C87', 'purple-950': '#3B0764',
134
-
135
- // Fuchsia
136
- 'fuchsia-50': '#FDF4FF', 'fuchsia-100': '#FAE8FF', 'fuchsia-200': '#F5D0FE', 'fuchsia-300': '#F0ABFC', 'fuchsia-400': '#E879F9',
137
- 'fuchsia-500': '#D946EF', 'fuchsia-600': '#C026D3', 'fuchsia-700': '#A21CAF', 'fuchsia-800': '#86198F', 'fuchsia-900': '#701A75', 'fuchsia-950': '#4A044E',
138
-
139
- // Pink
140
- 'pink-50': '#FDF2F8', 'pink-100': '#FCE7F3', 'pink-200': '#FBCFE8', 'pink-300': '#F9A8D4', 'pink-400': '#F472B6',
141
- 'pink-500': '#EC4899', 'pink-600': '#DB2777', 'pink-700': '#BE185D', 'pink-800': '#9D174D', 'pink-900': '#831843', 'pink-950': '#500724',
142
-
143
- // Rose
144
- 'rose-50': '#FFF1F2', 'rose-100': '#FFE4E6', 'rose-200': '#FECDD3', 'rose-300': '#FDA4AF', 'rose-400': '#FB7185',
145
- 'rose-500': '#F43F5E', 'rose-600': '#E11D48', 'rose-700': '#BE123C', 'rose-800': '#9F1239', 'rose-900': '#881337', 'rose-950': '#4C0519',
146
-
147
- // Slate
148
- 'slate-50': '#F8FAFC', 'slate-100': '#F1F5F9', 'slate-200': '#E2E8F0', 'slate-300': '#CBD5E1', 'slate-400': '#94A3B8',
149
- 'slate-500': '#64748B', 'slate-600': '#475569', 'slate-700': '#334155', 'slate-800': '#1E293B', 'slate-900': '#0F172A', 'slate-950': '#020617',
150
-
151
- // Gray
152
- 'gray-50': '#F9FAFB', 'gray-100': '#F3F4F6', 'gray-200': '#E5E7EB', 'gray-300': '#D1D5DB', 'gray-400': '#9CA3AF',
153
- 'gray-500': '#6B7280', 'gray-600': '#4B5563', 'gray-700': '#374151', 'gray-800': '#1F2937', 'gray-900': '#111827', 'gray-950': '#030712',
154
-
155
- // Zinc
156
- 'zinc-50': '#FAFAFA', 'zinc-100': '#F4F4F5', 'zinc-200': '#E4E4E7', 'zinc-300': '#D4D4D8', 'zinc-400': '#A1A1AA',
157
- 'zinc-500': '#71717A', 'zinc-600': '#52525B', 'zinc-700': '#3F3F46', 'zinc-800': '#27272A', 'zinc-900': '#18181B', 'zinc-950': '#09090B',
158
-
159
- // Neutral
160
- 'neutral-50': '#FAFAFA', 'neutral-100': '#F5F5F5', 'neutral-200': '#E5E5E5', 'neutral-300': '#D4D4D4', 'neutral-400': '#A3A3A3',
161
- 'neutral-500': '#737373', 'neutral-600': '#525252', 'neutral-700': '#404040', 'neutral-800': '#262626', 'neutral-900': '#171717', 'neutral-950': '#0A0A0A',
162
-
163
- // Stone
164
- 'stone-50': '#FAFAF9', 'stone-100': '#F5F5F4', 'stone-200': '#E7E5E4', 'stone-300': '#D6D3D1', 'stone-400': '#A8A29E',
165
- 'stone-500': '#78716C', 'stone-600': '#57534E', 'stone-700': '#44403C', 'stone-800': '#292524', 'stone-900': '#1C1917', 'stone-950': '#0C0A09'
166
- },
167
- zIndex: {
168
- 'base': '0',
169
- 'low': '10',
170
- 'mid': '50',
171
- 'high': '100',
172
- 'top': '9999'
173
- }
174
- },
175
- // Dark mode configuration
176
- // 'media' - Uses @media (prefers-color-scheme: dark)
177
- // 'selector' - Uses .dark class on html/body
178
- darkMode: 'media',
179
- // Preflight: Include opinionated base reset styles
180
- // true - Include all preflight styles (default)
181
- // false - Disable preflight completely
182
- preflight: true
183
- };
184
-
185
- // ============================================
186
- // CONFIG LOADER
187
- // ============================================
188
-
189
- function loadInlineConfig() {
190
- const configEl = document.querySelector('script[type="senangstart/config"]');
191
- if (!configEl) return {};
192
-
193
- try {
194
- return JSON.parse(configEl.textContent);
195
- } catch (e) {
196
- console.error('[SenangStart] Invalid config JSON:', e);
197
- return {};
198
- }
199
- }
200
-
201
- function mergeConfig(user) {
202
- const merged = JSON.parse(JSON.stringify(defaultConfig));
203
-
204
- if (user.theme) {
205
- for (const key of Object.keys(merged.theme)) {
206
- if (user.theme[key]) {
207
- merged.theme[key] = { ...merged.theme[key], ...user.theme[key] };
208
- }
209
- }
210
- }
211
-
212
- // Handle darkMode option
213
- if (user.darkMode !== undefined) {
214
- merged.darkMode = user.darkMode;
215
- }
216
-
217
- // Handle preflight option
218
- if (user.preflight !== undefined) {
219
- merged.preflight = user.preflight;
220
- }
221
-
222
- return merged;
223
- }
224
-
225
- // ============================================
226
- // CSS VARIABLE GENERATOR
227
- // ============================================
228
-
229
- function generateCSSVariables(config) {
230
- const { theme } = config;
231
- let css = ':root {\n';
232
-
233
- // Spacing
234
- for (const [key, value] of Object.entries(theme.spacing)) {
235
- css += ` --s-${key}: ${value};\n`;
236
- }
237
-
238
- // Radius
239
- for (const [key, value] of Object.entries(theme.radius)) {
240
- css += ` --r-${key}: ${value};\n`;
241
- }
242
-
243
- // Shadow
244
- for (const [key, value] of Object.entries(theme.shadow)) {
245
- css += ` --shadow-${key}: ${value};\n`;
246
- }
247
-
248
- // Font size
249
- for (const [key, value] of Object.entries(theme.fontSize)) {
250
- css += ` --font-${key}: ${value};\n`;
251
- }
252
-
253
- // Font weight
254
- for (const [key, value] of Object.entries(theme.fontWeight)) {
255
- css += ` --fw-${key}: ${value};\n`;
256
- }
257
-
258
- // Colors
259
- for (const [key, value] of Object.entries(theme.colors)) {
260
- css += ` --c-${key}: ${value};\n`;
261
- }
262
-
263
- // Z-index
264
- for (const [key, value] of Object.entries(theme.zIndex)) {
265
- css += ` --z-${key}: ${value};\n`;
266
- }
267
-
268
- css += '}\n\n';
269
-
270
- return css;
271
- }
272
-
273
- // ============================================
274
- // PREFLIGHT GENERATOR
275
- // ============================================
276
-
277
- function generatePreflight() {
278
- return `/* SenangStart Preflight - Opinionated Base Styles */
279
- *,
280
- ::before,
281
- ::after {
282
- box-sizing: border-box;
283
- border-width: 0;
284
- border-style: solid;
285
- border-color: currentColor;
286
- }
287
-
288
- html, :host {
289
- line-height: 1.5;
290
- -webkit-text-size-adjust: 100%;
291
- -moz-tab-size: 4;
292
- tab-size: 4;
293
- font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
294
- font-feature-settings: normal;
295
- font-variation-settings: normal;
296
- -webkit-tap-highlight-color: transparent;
297
- }
298
-
299
- body {
300
- margin: 0;
301
- line-height: inherit;
302
- }
303
-
304
- hr {
305
- height: 0;
306
- color: inherit;
307
- border-top-width: 1px;
308
- }
309
-
310
- h1, h2, h3, h4, h5, h6 {
311
- font-size: inherit;
312
- font-weight: inherit;
313
- }
314
-
315
- a {
316
- color: inherit;
317
- text-decoration: inherit;
318
- }
319
-
320
- b, strong {
321
- font-weight: bolder;
322
- }
323
-
324
- code, kbd, samp, pre {
325
- font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
326
- font-size: 1em;
327
- }
328
-
329
- small {
330
- font-size: 80%;
331
- }
332
-
333
- sub, sup {
334
- font-size: 75%;
335
- line-height: 0;
336
- position: relative;
337
- vertical-align: baseline;
338
- }
339
-
340
- sub { bottom: -0.25em; }
341
- sup { top: -0.5em; }
342
-
343
- table {
344
- text-indent: 0;
345
- border-color: inherit;
346
- border-collapse: collapse;
347
- }
348
-
349
- button, input, optgroup, select, textarea {
350
- font-family: inherit;
351
- font-size: 100%;
352
- font-weight: inherit;
353
- line-height: inherit;
354
- color: inherit;
355
- margin: 0;
356
- padding: 0;
357
- }
358
-
359
- button, select {
360
- text-transform: none;
361
- }
362
-
363
- button,
364
- input:where([type='button']),
365
- input:where([type='reset']),
366
- input:where([type='submit']) {
367
- -webkit-appearance: button;
368
- background-color: transparent;
369
- background-image: none;
370
- }
371
-
372
- progress {
373
- vertical-align: baseline;
374
- }
375
-
376
- [type='search'] {
377
- -webkit-appearance: textfield;
378
- outline-offset: -2px;
379
- }
380
-
381
- summary {
382
- display: list-item;
383
- }
384
-
385
- blockquote, dl, dd, h1, h2, h3, h4, h5, h6, hr, figure, p, pre {
386
- margin: 0;
387
- }
388
-
389
- fieldset { margin: 0; padding: 0; }
390
- legend { padding: 0; }
391
-
392
- ol, ul, menu {
393
- list-style: none;
394
- margin: 0;
395
- padding: 0;
396
- }
397
-
398
- dialog { padding: 0; }
399
-
400
- textarea { resize: vertical; }
401
-
402
- input::placeholder, textarea::placeholder {
403
- opacity: 1;
404
- color: #9ca3af;
405
- }
406
-
407
- button, [role="button"] {
408
- cursor: pointer;
409
- }
410
-
411
- :disabled {
412
- cursor: default;
413
- }
414
-
415
- img, svg, video, canvas, audio, iframe, embed, object {
416
- display: block;
417
- vertical-align: middle;
418
- }
419
-
420
- img, video {
421
- max-width: 100%;
422
- height: auto;
423
- }
424
-
425
- [hidden] {
426
- display: none;
427
- }
428
-
429
- /* Keyframe Animations */
430
- @keyframes spin {
431
- to { transform: rotate(360deg); }
432
- }
433
-
434
- @keyframes ping {
435
- 75%, 100% {
436
- transform: scale(2);
437
- opacity: 0;
438
- }
439
- }
440
-
441
- @keyframes pulse {
442
- 50% { opacity: .5; }
443
- }
444
-
445
- @keyframes bounce {
446
- 0%, 100% {
447
- transform: translateY(-25%);
448
- animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
449
- }
450
- 50% {
451
- transform: none;
452
- animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
453
- }
454
- }
455
-
456
- `;
457
- }
458
-
459
- // ============================================
460
- // LAYOUT KEYWORDS
461
- // ============================================
462
-
463
- const layoutKeywords = {
464
- // Display
465
- 'flex': 'display: flex;',
466
- 'grid': 'display: grid;',
467
- 'inline-flex': 'display: inline-flex;',
468
- 'inline-grid': 'display: inline-grid;',
469
- 'block': 'display: block;',
470
- 'inline': 'display: inline-block;',
471
- 'hidden': 'display: none;',
472
-
473
- // Flex Direction
474
- 'row': 'flex-direction: row;',
475
- 'col': 'flex-direction: column;',
476
- 'row-reverse': 'flex-direction: row-reverse;',
477
- 'col-reverse': 'flex-direction: column-reverse;',
478
-
479
- // Flex Wrap
480
- 'wrap': 'flex-wrap: wrap;',
481
- 'nowrap': 'flex-wrap: nowrap;',
482
- 'wrap-reverse': 'flex-wrap: wrap-reverse;',
483
-
484
- // Flex Item
485
- 'grow': 'flex-grow: 1;',
486
- 'grow-0': 'flex-grow: 0;',
487
- 'shrink': 'flex-shrink: 1;',
488
- 'shrink-0': 'flex-shrink: 0;',
489
-
490
- // Grid Auto Flow
491
- 'grid-flow-row': 'grid-auto-flow: row;',
492
- 'grid-flow-col': 'grid-auto-flow: column;',
493
- 'grid-flow-dense': 'grid-auto-flow: dense;',
494
- 'grid-flow-row-dense': 'grid-auto-flow: row dense;',
495
- 'grid-flow-col-dense': 'grid-auto-flow: column dense;',
496
-
497
- // Shorthand Alignment (backwards compat - simple keywords)
498
- 'center': 'justify-content: center; align-items: center;',
499
- 'start': 'justify-content: flex-start; align-items: flex-start;',
500
- 'end': 'justify-content: flex-end; align-items: flex-end;',
501
- 'between': 'justify-content: space-between;',
502
- 'around': 'justify-content: space-around;',
503
- 'evenly': 'justify-content: space-evenly;',
504
-
505
- // Position
506
- 'absolute': 'position: absolute;',
507
- 'relative': 'position: relative;',
508
- 'fixed': 'position: fixed;',
509
- 'sticky': 'position: sticky;',
510
- 'static': 'position: static;',
511
-
512
- // Visibility
513
- 'visible': 'visibility: visible;',
514
- 'invisible': 'visibility: hidden;',
515
-
516
- // Isolation
517
- 'isolate': 'isolation: isolate;',
518
- 'isolate-auto': 'isolation: auto;',
519
-
520
- // Box Sizing
521
- 'box-border': 'box-sizing: border-box;',
522
- 'box-content': 'box-sizing: content-box;',
523
-
524
- // Float
525
- 'float-left': 'float: left;',
526
- 'float-right': 'float: right;',
527
- 'float-none': 'float: none;',
528
-
529
- // Clear
530
- 'clear-left': 'clear: left;',
531
- 'clear-right': 'clear: right;',
532
- 'clear-both': 'clear: both;',
533
- 'clear-none': 'clear: none;',
534
-
535
- // Container
536
- 'container': 'width: 100%; margin-left: auto; margin-right: auto;',
537
-
538
- // Table Border Collapse
539
- 'border-collapse': 'border-collapse: collapse;',
540
- 'border-separate': 'border-collapse: separate;'
541
- };
542
-
543
- // ============================================
544
- // RULE GENERATORS
545
- // ============================================
546
-
547
- const breakpoints = ['mob', 'tab', 'lap', 'desk'];
548
- const states = ['hover', 'focus', 'active', 'disabled', 'dark'];
549
-
550
- function parseToken(raw) {
551
- const token = {
552
- raw,
553
- breakpoint: null,
554
- state: null,
555
- property: null,
556
- value: null,
557
- isArbitrary: false
558
- };
559
-
560
- const parts = raw.split(':');
561
- let idx = 0;
562
-
563
- // Check for breakpoint
564
- if (breakpoints.includes(parts[0])) {
565
- token.breakpoint = parts[0];
566
- idx++;
567
- }
568
-
569
- // Check for state
570
- if (states.includes(parts[idx])) {
571
- token.state = parts[idx];
572
- idx++;
573
- }
574
-
575
- // Property
576
- if (idx < parts.length) {
577
- token.property = parts[idx];
578
- idx++;
579
- }
580
-
581
- // Value
582
- if (idx < parts.length) {
583
- let value = parts.slice(idx).join(':');
584
- const arbitraryMatch = value.match(/^\[(.+)\]$/);
585
- if (arbitraryMatch) {
586
- token.value = arbitraryMatch[1].replace(/_/g, ' ');
587
- token.isArbitrary = true;
588
- } else {
589
- token.value = value;
590
- }
591
- }
592
-
593
- return token;
594
- }
595
-
596
- function generateLayoutRule(token) {
597
- const { property, value, isArbitrary } = token;
598
-
599
- // Justify Content (justify:[value])
600
- if (property === 'justify') {
601
- const justifyMap = {
602
- 'start': 'flex-start',
603
- 'end': 'flex-end',
604
- 'center': 'center',
605
- 'between': 'space-between',
606
- 'around': 'space-around',
607
- 'evenly': 'space-evenly',
608
- 'stretch': 'stretch'
609
- };
610
- return `justify-content: ${justifyMap[value] || value};`;
611
- }
612
-
613
- // Justify Items (justify-items:[value])
614
- if (property === 'justify-items') {
615
- return `justify-items: ${value};`;
616
- }
617
-
618
- // Justify Self (justify-self:[value])
619
- if (property === 'justify-self') {
620
- return `justify-self: ${value};`;
621
- }
622
-
623
- // Align Content (content:[value])
624
- if (property === 'content') {
625
- const contentMap = {
626
- 'start': 'flex-start',
627
- 'end': 'flex-end',
628
- 'center': 'center',
629
- 'between': 'space-between',
630
- 'around': 'space-around',
631
- 'evenly': 'space-evenly',
632
- 'stretch': 'stretch'
633
- };
634
- return `align-content: ${contentMap[value] || value};`;
635
- }
636
-
637
- // Align Items (items:[value])
638
- if (property === 'items') {
639
- const itemsMap = {
640
- 'start': 'flex-start',
641
- 'end': 'flex-end',
642
- 'center': 'center',
643
- 'baseline': 'baseline',
644
- 'stretch': 'stretch'
645
- };
646
- return `align-items: ${itemsMap[value] || value};`;
647
- }
648
-
649
- // Align Self (self:[value])
650
- if (property === 'self') {
651
- const selfMap = {
652
- 'auto': 'auto',
653
- 'start': 'flex-start',
654
- 'end': 'flex-end',
655
- 'center': 'center',
656
- 'baseline': 'baseline',
657
- 'stretch': 'stretch'
658
- };
659
- return `align-self: ${selfMap[value] || value};`;
660
- }
661
-
662
- // Place Content (place-content:[value])
663
- if (property === 'place-content') {
664
- const placeContentMap = {
665
- 'start': 'start',
666
- 'end': 'end',
667
- 'center': 'center',
668
- 'between': 'space-between',
669
- 'around': 'space-around',
670
- 'evenly': 'space-evenly',
671
- 'stretch': 'stretch'
672
- };
673
- return `place-content: ${placeContentMap[value] || value};`;
674
- }
675
-
676
- // Place Items (place-items:[value])
677
- if (property === 'place-items') {
678
- return `place-items: ${value};`;
679
- }
680
-
681
- // Place Self (place-self:[value])
682
- if (property === 'place-self') {
683
- return `place-self: ${value};`;
684
- }
685
-
686
- // Z-index
687
- if (property === 'z') {
688
- return `z-index: var(--z-${value});`;
689
- }
690
-
691
- // Overflow
692
- if (property === 'overflow') {
693
- return `overflow: ${value};`;
694
- }
695
-
696
- // Overflow X/Y
697
- if (property === 'overflow-x') {
698
- return `overflow-x: ${value};`;
699
- }
700
- if (property === 'overflow-y') {
701
- return `overflow-y: ${value};`;
702
- }
703
-
704
- // Aspect Ratio
705
- if (property === 'aspect') {
706
- const aspectMap = {
707
- 'square': '1 / 1',
708
- 'video': '16 / 9',
709
- 'auto': 'auto'
710
- };
711
- const cssValue = isArbitrary ? value.replace(/_/g, ' ') : (aspectMap[value] || value);
712
- return `aspect-ratio: ${cssValue};`;
713
- }
714
-
715
- // Object Fit
716
- if (property === 'object') {
717
- return `object-fit: ${value};`;
718
- }
719
-
720
- // Object Position
721
- if (property === 'object-pos') {
722
- const cssValue = isArbitrary ? value.replace(/_/g, ' ') : value;
723
- return `object-position: ${cssValue};`;
724
- }
725
-
726
- // Inset (all sides)
727
- if (property === 'inset') {
728
- const cssValue = isArbitrary ? value : (value === '0' ? '0' : `var(--s-${value})`);
729
- return `inset: ${cssValue};`;
730
- }
731
-
732
- // Individual positioning: top, right, bottom, left
733
- if (['top', 'right', 'bottom', 'left'].includes(property)) {
734
- const cssValue = isArbitrary ? value : (value === '0' ? '0' : `var(--s-${value})`);
735
- return `${property}: ${cssValue};`;
736
- }
737
-
738
- // Inset X (left + right)
739
- if (property === 'inset-x') {
740
- const cssValue = isArbitrary ? value : (value === '0' ? '0' : `var(--s-${value})`);
741
- return `left: ${cssValue}; right: ${cssValue};`;
742
- }
743
-
744
- // Inset Y (top + bottom)
745
- if (property === 'inset-y') {
746
- const cssValue = isArbitrary ? value : (value === '0' ? '0' : `var(--s-${value})`);
747
- return `top: ${cssValue}; bottom: ${cssValue};`;
748
- }
749
-
750
- // Columns
751
- if (property === 'cols') {
752
- return `columns: ${value};`;
753
- }
754
-
755
- // Overscroll Behavior
756
- if (property === 'overscroll') {
757
- return `overscroll-behavior: ${value};`;
758
- }
759
- if (property === 'overscroll-x') {
760
- return `overscroll-behavior-x: ${value};`;
761
- }
762
- if (property === 'overscroll-y') {
763
- return `overscroll-behavior-y: ${value};`;
764
- }
765
-
766
- // Flex Basis
767
- if (property === 'basis') {
768
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
769
- return `flex-basis: ${cssValue};`;
770
- }
771
-
772
- // Flex (shorthand)
773
- if (property === 'flex') {
774
- const flexPresets = {
775
- '1': '1 1 0%',
776
- 'auto': '1 1 auto',
777
- 'initial': '0 1 auto',
778
- 'none': 'none'
779
- };
780
- const cssValue = isArbitrary ? value.replace(/_/g, ' ') : (flexPresets[value] || value);
781
- return `flex: ${cssValue};`;
782
- }
783
-
784
- // Order
785
- if (property === 'order') {
786
- const orderPresets = {
787
- 'first': '-9999',
788
- 'last': '9999',
789
- 'none': '0'
790
- };
791
- const cssValue = orderPresets[value] || value;
792
- return `order: ${cssValue};`;
793
- }
794
-
795
- // Grid Template Columns
796
- if (property === 'grid-cols') {
797
- if (value === 'none') {
798
- return 'grid-template-columns: none;';
799
- }
800
- if (value === 'subgrid') {
801
- return 'grid-template-columns: subgrid;';
802
- }
803
- if (isArbitrary) {
804
- return `grid-template-columns: ${value.replace(/_/g, ' ')};`;
805
- }
806
- // Numeric value: repeat(n, minmax(0, 1fr))
807
- return `grid-template-columns: repeat(${value}, minmax(0, 1fr));`;
808
- }
809
-
810
- // Grid Template Rows
811
- if (property === 'grid-rows') {
812
- if (value === 'none') {
813
- return 'grid-template-rows: none;';
814
- }
815
- if (value === 'subgrid') {
816
- return 'grid-template-rows: subgrid;';
817
- }
818
- if (isArbitrary) {
819
- return `grid-template-rows: ${value.replace(/_/g, ' ')};`;
820
- }
821
- return `grid-template-rows: repeat(${value}, minmax(0, 1fr));`;
822
- }
823
-
824
- // Grid Column Span
825
- if (property === 'col-span') {
826
- if (value === 'full') {
827
- return 'grid-column: 1 / -1;';
828
- }
829
- return `grid-column: span ${value} / span ${value};`;
830
- }
831
-
832
- // Grid Column Start/End
833
- if (property === 'col-start') {
834
- return `grid-column-start: ${value};`;
835
- }
836
- if (property === 'col-end') {
837
- return `grid-column-end: ${value};`;
838
- }
839
-
840
- // Grid Row Span
841
- if (property === 'row-span') {
842
- if (value === 'full') {
843
- return 'grid-row: 1 / -1;';
844
- }
845
- return `grid-row: span ${value} / span ${value};`;
846
- }
847
-
848
- // Grid Row Start/End
849
- if (property === 'row-start') {
850
- return `grid-row-start: ${value};`;
851
- }
852
- if (property === 'row-end') {
853
- return `grid-row-end: ${value};`;
854
- }
855
-
856
- // Grid Auto Columns
857
- if (property === 'auto-cols') {
858
- const autoPresets = {
859
- 'auto': 'auto',
860
- 'min': 'min-content',
861
- 'max': 'max-content',
862
- 'fr': 'minmax(0, 1fr)'
863
- };
864
- const cssValue = isArbitrary ? value : (autoPresets[value] || value);
865
- return `grid-auto-columns: ${cssValue};`;
866
- }
867
-
868
- // Grid Auto Rows
869
- if (property === 'auto-rows') {
870
- const autoPresets = {
871
- 'auto': 'auto',
872
- 'min': 'min-content',
873
- 'max': 'max-content',
874
- 'fr': 'minmax(0, 1fr)'
875
- };
876
- const cssValue = isArbitrary ? value : (autoPresets[value] || value);
877
- return `grid-auto-rows: ${cssValue};`;
878
- }
879
-
880
- // Table Layout
881
- if (property === 'table') {
882
- const tableMap = { 'auto': 'auto', 'fixed': 'fixed' };
883
- return `table-layout: ${tableMap[value] || value};`;
884
- }
885
-
886
- // Caption Side
887
- if (property === 'caption') {
888
- return `caption-side: ${value};`;
889
- }
890
-
891
- // Border Spacing
892
- if (property === 'border-spacing') {
893
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
894
- return `border-spacing: ${cssValue};`;
895
- }
896
- if (property === 'border-spacing-x') {
897
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
898
- return `border-spacing: ${cssValue} 0;`;
899
- }
900
- if (property === 'border-spacing-y') {
901
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
902
- return `border-spacing: 0 ${cssValue};`;
903
- }
904
-
905
- return layoutKeywords[property] || '';
906
- }
907
-
908
- function generateSpaceRule(token) {
909
- const { property, value, isArbitrary } = token;
910
-
911
- if (value === 'auto') {
912
- const autoMap = {
913
- 'm': 'margin: auto;',
914
- 'm-x': 'margin-left: auto; margin-right: auto;',
915
- 'm-y': 'margin-top: auto; margin-bottom: auto;',
916
- 'm-t': 'margin-top: auto;',
917
- 'm-r': 'margin-right: auto;',
918
- 'm-b': 'margin-bottom: auto;',
919
- 'm-l': 'margin-left: auto;'
920
- };
921
- return autoMap[property] || '';
922
- }
923
-
924
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
925
-
926
- const map = {
927
- 'p': `padding: ${cssValue};`,
928
- 'p-t': `padding-top: ${cssValue};`,
929
- 'p-r': `padding-right: ${cssValue};`,
930
- 'p-b': `padding-bottom: ${cssValue};`,
931
- 'p-l': `padding-left: ${cssValue};`,
932
- 'p-x': `padding-left: ${cssValue}; padding-right: ${cssValue};`,
933
- 'p-y': `padding-top: ${cssValue}; padding-bottom: ${cssValue};`,
934
- 'm': `margin: ${cssValue};`,
935
- 'm-t': `margin-top: ${cssValue};`,
936
- 'm-r': `margin-right: ${cssValue};`,
937
- 'm-b': `margin-bottom: ${cssValue};`,
938
- 'm-l': `margin-left: ${cssValue};`,
939
- 'm-x': `margin-left: ${cssValue}; margin-right: ${cssValue};`,
940
- 'm-y': `margin-top: ${cssValue}; margin-bottom: ${cssValue};`,
941
- 'g': `gap: ${cssValue};`,
942
- 'g-x': `column-gap: ${cssValue};`,
943
- 'g-y': `row-gap: ${cssValue};`,
944
- 'w': `width: ${cssValue};`,
945
- 'h': `height: ${cssValue};`,
946
- 'min-w': `min-width: ${cssValue};`,
947
- 'max-w': `max-width: ${cssValue};`,
948
- 'min-h': `min-height: ${cssValue};`,
949
- 'max-h': `max-height: ${cssValue};`
950
- };
951
-
952
- return map[property] || '';
953
- }
954
-
955
- function generateVisualRule(token) {
956
- const { property, value, isArbitrary } = token;
957
-
958
- // Static typography keywords
959
- const typographyKeywords = {
960
- // Font Style
961
- 'italic': 'font-style: italic;',
962
- 'not-italic': 'font-style: normal;',
963
-
964
- // Font Stretch
965
- 'font-stretch-condensed': 'font-stretch: condensed;',
966
- 'font-stretch-expanded': 'font-stretch: expanded;',
967
- 'font-stretch-normal': 'font-stretch: normal;',
968
-
969
- // Font Smoothing
970
- 'antialiased': '-webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;',
971
- 'subpixel-antialiased': '-webkit-font-smoothing: auto; -moz-osx-font-smoothing: auto;',
972
-
973
- // Font Variant Numeric
974
- 'normal-nums': 'font-variant-numeric: normal;',
975
- 'ordinal': 'font-variant-numeric: ordinal;',
976
- 'slashed-zero': 'font-variant-numeric: slashed-zero;',
977
- 'lining-nums': 'font-variant-numeric: lining-nums;',
978
- 'oldstyle-nums': 'font-variant-numeric: oldstyle-nums;',
979
- 'proportional-nums': 'font-variant-numeric: proportional-nums;',
980
- 'tabular-nums': 'font-variant-numeric: tabular-nums;',
981
-
982
- // Text Transform
983
- 'uppercase': 'text-transform: uppercase;',
984
- 'lowercase': 'text-transform: lowercase;',
985
- 'capitalize': 'text-transform: capitalize;',
986
- 'normal-case': 'text-transform: none;',
987
-
988
- // Text Decoration Line
989
- 'underline': 'text-decoration-line: underline;',
990
- 'overline': 'text-decoration-line: overline;',
991
- 'line-through': 'text-decoration-line: line-through;',
992
- 'no-underline': 'text-decoration-line: none;',
993
-
994
- // Text Decoration Style
995
- 'decoration-solid': 'text-decoration-style: solid;',
996
- 'decoration-double': 'text-decoration-style: double;',
997
- 'decoration-dotted': 'text-decoration-style: dotted;',
998
- 'decoration-dashed': 'text-decoration-style: dashed;',
999
- 'decoration-wavy': 'text-decoration-style: wavy;',
1000
-
1001
- // Text Overflow
1002
- 'truncate': 'overflow: hidden; text-overflow: ellipsis; white-space: nowrap;',
1003
- 'text-ellipsis': 'text-overflow: ellipsis;',
1004
- 'text-clip': 'text-overflow: clip;',
1005
-
1006
- // Text Wrap
1007
- 'text-wrap': 'text-wrap: wrap;',
1008
- 'text-nowrap': 'text-wrap: nowrap;',
1009
- 'text-balance': 'text-wrap: balance;',
1010
- 'text-pretty': 'text-wrap: pretty;',
1011
-
1012
- // Whitespace
1013
- 'whitespace-normal': 'white-space: normal;',
1014
- 'whitespace-nowrap': 'white-space: nowrap;',
1015
- 'whitespace-pre': 'white-space: pre;',
1016
- 'whitespace-pre-line': 'white-space: pre-line;',
1017
- 'whitespace-pre-wrap': 'white-space: pre-wrap;',
1018
- 'whitespace-break-spaces': 'white-space: break-spaces;',
1019
-
1020
- // Word Break
1021
- 'break-normal': 'overflow-wrap: normal; word-break: normal;',
1022
- 'break-words': 'overflow-wrap: break-word;',
1023
- 'break-all': 'word-break: break-all;',
1024
- 'break-keep': 'word-break: keep-all;',
1025
-
1026
- // Hyphens
1027
- 'hyphens-none': 'hyphens: none;',
1028
- 'hyphens-manual': 'hyphens: manual;',
1029
- 'hyphens-auto': 'hyphens: auto;',
1030
-
1031
- // Vertical Align
1032
- 'align-baseline': 'vertical-align: baseline;',
1033
- 'align-top': 'vertical-align: top;',
1034
- 'align-middle': 'vertical-align: middle;',
1035
- 'align-bottom': 'vertical-align: bottom;',
1036
- 'align-text-top': 'vertical-align: text-top;',
1037
- 'align-text-bottom': 'vertical-align: text-bottom;',
1038
- 'align-sub': 'vertical-align: sub;',
1039
- 'align-super': 'vertical-align: super;',
1040
-
1041
- // List Style Type
1042
- 'list-none': 'list-style-type: none;',
1043
- 'list-disc': 'list-style-type: disc;',
1044
- 'list-decimal': 'list-style-type: decimal;',
1045
- 'list-square': 'list-style-type: square;',
1046
-
1047
- // List Style Position
1048
- 'list-inside': 'list-style-position: inside;',
1049
- 'list-outside': 'list-style-position: outside;'
1050
- };
1051
-
1052
- // Check static keywords first
1053
- if (typographyKeywords[property]) {
1054
- return typographyKeywords[property];
1055
- }
1056
-
1057
- const rules = {
1058
- 'bg': () => {
1059
- const cssValue = isArbitrary ? value : `var(--c-${value})`;
1060
- return `background-color: ${cssValue};`;
1061
- },
1062
- 'text': () => {
1063
- if (['left', 'center', 'right', 'justify'].includes(value)) {
1064
- return `text-align: ${value};`;
1065
- }
1066
- const cssValue = isArbitrary ? value : `var(--c-${value})`;
1067
- return `color: ${cssValue};`;
1068
- },
1069
- 'text-size': () => {
1070
- const cssValue = isArbitrary ? value : `var(--font-${value})`;
1071
- return `font-size: ${cssValue};`;
1072
- },
1073
- 'font': () => {
1074
- // Check for font-family presets
1075
- const fontFamilies = {
1076
- 'sans': 'ui-sans-serif, system-ui, sans-serif',
1077
- 'serif': 'ui-serif, Georgia, serif',
1078
- 'mono': 'ui-monospace, monospace'
1079
- };
1080
- if (fontFamilies[value]) {
1081
- return `font-family: ${fontFamilies[value]};`;
1082
- }
1083
- // Font weight
1084
- return `font-weight: var(--fw-${value});`;
1085
- },
1086
- 'tracking': () => {
1087
- // Letter spacing
1088
- const trackingScale = {
1089
- 'tighter': '-0.05em',
1090
- 'tight': '-0.025em',
1091
- 'normal': '0',
1092
- 'wide': '0.025em',
1093
- 'wider': '0.05em',
1094
- 'widest': '0.1em'
1095
- };
1096
- const cssValue = isArbitrary ? value : (trackingScale[value] || value);
1097
- return `letter-spacing: ${cssValue};`;
1098
- },
1099
- 'leading': () => {
1100
- // Line height
1101
- const leadingScale = {
1102
- 'none': '1',
1103
- 'tight': '1.25',
1104
- 'snug': '1.375',
1105
- 'normal': '1.5',
1106
- 'relaxed': '1.625',
1107
- 'loose': '2'
1108
- };
1109
- const cssValue = isArbitrary ? value : (leadingScale[value] || value);
1110
- return `line-height: ${cssValue};`;
1111
- },
1112
- 'line-clamp': () => {
1113
- return `overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: ${value};`;
1114
- },
1115
- 'decoration': () => {
1116
- // Text decoration color
1117
- const cssValue = isArbitrary ? value : `var(--c-${value})`;
1118
- return `text-decoration-color: ${cssValue};`;
1119
- },
1120
- 'decoration-thickness': () => {
1121
- const cssValue = isArbitrary ? value : `${value}px`;
1122
- return `text-decoration-thickness: ${cssValue};`;
1123
- },
1124
- 'underline-offset': () => {
1125
- const cssValue = isArbitrary ? value : `${value}px`;
1126
- return `text-underline-offset: ${cssValue};`;
1127
- },
1128
- 'indent': () => {
1129
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
1130
- return `text-indent: ${cssValue};`;
1131
- },
1132
- 'border': () => {
1133
- const cssValue = isArbitrary ? value : `var(--c-${value})`;
1134
- return `border-color: ${cssValue}; border-style: solid;`;
1135
- },
1136
- // Border color - directional
1137
- 'border-t': () => {
1138
- const cssValue = isArbitrary ? value : `var(--c-${value})`;
1139
- return `border-top-color: ${cssValue}; border-top-style: solid;`;
1140
- },
1141
- 'border-b': () => {
1142
- const cssValue = isArbitrary ? value : `var(--c-${value})`;
1143
- return `border-bottom-color: ${cssValue}; border-bottom-style: solid;`;
1144
- },
1145
- 'border-l': () => {
1146
- const cssValue = isArbitrary ? value : `var(--c-${value})`;
1147
- return `border-left-color: ${cssValue}; border-left-style: solid;`;
1148
- },
1149
- 'border-r': () => {
1150
- const cssValue = isArbitrary ? value : `var(--c-${value})`;
1151
- return `border-right-color: ${cssValue}; border-right-style: solid;`;
1152
- },
1153
- 'border-x': () => {
1154
- const cssValue = isArbitrary ? value : `var(--c-${value})`;
1155
- return `border-left-color: ${cssValue}; border-right-color: ${cssValue}; border-left-style: solid; border-right-style: solid;`;
1156
- },
1157
- 'border-y': () => {
1158
- const cssValue = isArbitrary ? value : `var(--c-${value})`;
1159
- return `border-top-color: ${cssValue}; border-bottom-color: ${cssValue}; border-top-style: solid; border-bottom-style: solid;`;
1160
- },
1161
- 'border-w': () => {
1162
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
1163
- return `border-width: ${cssValue}; border-style: solid;`;
1164
- },
1165
- // Border width - directional
1166
- 'border-t-w': () => {
1167
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
1168
- return `border-top-width: ${cssValue}; border-top-style: solid;`;
1169
- },
1170
- 'border-b-w': () => {
1171
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
1172
- return `border-bottom-width: ${cssValue}; border-bottom-style: solid;`;
1173
- },
1174
- 'border-l-w': () => {
1175
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
1176
- return `border-left-width: ${cssValue}; border-left-style: solid;`;
1177
- },
1178
- 'border-r-w': () => {
1179
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
1180
- return `border-right-width: ${cssValue}; border-right-style: solid;`;
1181
- },
1182
- 'border-x-w': () => {
1183
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
1184
- return `border-left-width: ${cssValue}; border-right-width: ${cssValue}; border-left-style: solid; border-right-style: solid;`;
1185
- },
1186
- 'border-y-w': () => {
1187
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
1188
- return `border-top-width: ${cssValue}; border-bottom-width: ${cssValue}; border-top-style: solid; border-bottom-style: solid;`;
1189
- },
1190
- 'rounded': () => `border-radius: var(--r-${value});`,
1191
- 'shadow': () => `box-shadow: var(--shadow-${value});`,
1192
- 'opacity': () => {
1193
- const opacityValue = isArbitrary ? value : (parseFloat(value) / 100);
1194
- return `opacity: ${opacityValue};`;
1195
- },
1196
- 'content': () => `content: "${value}";`,
1197
-
1198
- // ============================================
1199
- // TRANSFORM UTILITIES
1200
- // ============================================
1201
- 'scale': () => {
1202
- const scaleValue = isArbitrary ? value : (parseFloat(value) / 100);
1203
- return `transform: scale(${scaleValue});`;
1204
- },
1205
- 'scale-x': () => {
1206
- const scaleValue = isArbitrary ? value : (parseFloat(value) / 100);
1207
- return `transform: scaleX(${scaleValue});`;
1208
- },
1209
- 'scale-y': () => {
1210
- const scaleValue = isArbitrary ? value : (parseFloat(value) / 100);
1211
- return `transform: scaleY(${scaleValue});`;
1212
- },
1213
- 'rotate': () => {
1214
- const rotateValue = isArbitrary ? value : `${value}deg`;
1215
- return `transform: rotate(${rotateValue});`;
1216
- },
1217
- 'translate-x': () => {
1218
- const translatePresets = { '0': '0', 'full': '100%', '1/2': '50%', '-full': '-100%', '-1/2': '-50%' };
1219
- const cssValue = isArbitrary ? value : (translatePresets[value] || `var(--s-${value})`);
1220
- return `transform: translateX(${cssValue});`;
1221
- },
1222
- 'translate-y': () => {
1223
- const translatePresets = { '0': '0', 'full': '100%', '1/2': '50%', '-full': '-100%', '-1/2': '-50%' };
1224
- const cssValue = isArbitrary ? value : (translatePresets[value] || `var(--s-${value})`);
1225
- return `transform: translateY(${cssValue});`;
1226
- },
1227
- 'skew-x': () => {
1228
- const skewValue = isArbitrary ? value : `${value}deg`;
1229
- return `transform: skewX(${skewValue});`;
1230
- },
1231
- 'skew-y': () => {
1232
- const skewValue = isArbitrary ? value : `${value}deg`;
1233
- return `transform: skewY(${skewValue});`;
1234
- },
1235
- 'origin': () => {
1236
- const originMap = {
1237
- 'center': 'center',
1238
- 'top': 'top',
1239
- 'top-right': 'top right',
1240
- 'right': 'right',
1241
- 'bottom-right': 'bottom right',
1242
- 'bottom': 'bottom',
1243
- 'bottom-left': 'bottom left',
1244
- 'left': 'left',
1245
- 'top-left': 'top left'
1246
- };
1247
- const cssValue = isArbitrary ? value.replace(/_/g, ' ') : (originMap[value] || value);
1248
- return `transform-origin: ${cssValue};`;
1249
- },
1250
-
1251
- // ============================================
1252
- // TRANSITION UTILITIES
1253
- // ============================================
1254
- 'transition': () => {
1255
- const transitionMap = {
1256
- 'none': 'transition-property: none;',
1257
- 'all': 'transition-property: all; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms;',
1258
- 'colors': 'transition-property: color, background-color, border-color; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms;',
1259
- 'opacity': 'transition-property: opacity; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms;',
1260
- 'shadow': 'transition-property: box-shadow; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms;',
1261
- 'transform': 'transition-property: transform; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms;'
1262
- };
1263
- return transitionMap[value] || `transition-property: ${value};`;
1264
- },
1265
- 'duration': () => {
1266
- const durationMap = {
1267
- 'instant': '75ms',
1268
- 'quick': '100ms',
1269
- 'fast': '150ms',
1270
- 'normal': '200ms',
1271
- 'slow': '300ms',
1272
- 'slower': '500ms',
1273
- 'lazy': '700ms'
1274
- };
1275
- const cssValue = isArbitrary ? value : (durationMap[value] || `${value}ms`);
1276
- return `transition-duration: ${cssValue};`;
1277
- },
1278
- 'ease': () => {
1279
- const easeMap = {
1280
- 'linear': 'linear',
1281
- 'in': 'cubic-bezier(0.4, 0, 1, 1)',
1282
- 'out': 'cubic-bezier(0, 0, 0.2, 1)',
1283
- 'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)'
1284
- };
1285
- const cssValue = easeMap[value] || value;
1286
- return `transition-timing-function: ${cssValue};`;
1287
- },
1288
- 'delay': () => {
1289
- const delayMap = {
1290
- 'instant': '75ms',
1291
- 'quick': '100ms',
1292
- 'fast': '150ms',
1293
- 'normal': '200ms',
1294
- 'slow': '300ms'
1295
- };
1296
- const cssValue = isArbitrary ? value : (delayMap[value] || `${value}ms`);
1297
- return `transition-delay: ${cssValue};`;
1298
- },
1299
- 'animate': () => {
1300
- const animateMap = {
1301
- 'none': 'animation: none;',
1302
- 'spin': 'animation: spin 1s linear infinite;',
1303
- 'ping': 'animation: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;',
1304
- 'pulse': 'animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;',
1305
- 'bounce': 'animation: bounce 1s infinite;'
1306
- };
1307
- return animateMap[value] || `animation: ${value};`;
1308
- },
1309
-
1310
- // ============================================
1311
- // FILTER UTILITIES
1312
- // ============================================
1313
- 'blur': () => {
1314
- const blurScale = {
1315
- 'none': '0',
1316
- 'sm': '4px',
1317
- 'md': '8px',
1318
- 'lg': '12px',
1319
- 'xl': '16px',
1320
- '2xl': '24px',
1321
- '3xl': '40px'
1322
- };
1323
- const cssValue = isArbitrary ? value : (blurScale[value] || `${value}px`);
1324
- return `filter: blur(${cssValue});`;
1325
- },
1326
- 'brightness': () => {
1327
- const brightnessScale = {
1328
- '0': '0',
1329
- '50': '0.5',
1330
- '75': '0.75',
1331
- '90': '0.9',
1332
- '95': '0.95',
1333
- '100': '1',
1334
- '105': '1.05',
1335
- '110': '1.1',
1336
- '125': '1.25',
1337
- '150': '1.5',
1338
- '200': '2'
1339
- };
1340
- const cssValue = isArbitrary ? value : (brightnessScale[value] || (parseFloat(value) / 100));
1341
- return `filter: brightness(${cssValue});`;
1342
- },
1343
- 'contrast': () => {
1344
- const contrastScale = {
1345
- '0': '0',
1346
- '50': '0.5',
1347
- '75': '0.75',
1348
- '100': '1',
1349
- '125': '1.25',
1350
- '150': '1.5',
1351
- '200': '2'
1352
- };
1353
- const cssValue = isArbitrary ? value : (contrastScale[value] || (parseFloat(value) / 100));
1354
- return `filter: contrast(${cssValue});`;
1355
- },
1356
- 'grayscale': () => {
1357
- const grayscaleScale = { '0': '0', '100': '1', 'full': '1' };
1358
- const cssValue = isArbitrary ? value : (grayscaleScale[value] || (parseFloat(value) / 100));
1359
- return `filter: grayscale(${cssValue});`;
1360
- },
1361
- 'hue-rotate': () => {
1362
- const cssValue = isArbitrary ? value : `${value}deg`;
1363
- return `filter: hue-rotate(${cssValue});`;
1364
- },
1365
- 'invert': () => {
1366
- const invertScale = { '0': '0', '100': '1', 'full': '1' };
1367
- const cssValue = isArbitrary ? value : (invertScale[value] || (parseFloat(value) / 100));
1368
- return `filter: invert(${cssValue});`;
1369
- },
1370
- 'saturate': () => {
1371
- const saturateScale = {
1372
- '0': '0',
1373
- '50': '0.5',
1374
- '100': '1',
1375
- '150': '1.5',
1376
- '200': '2'
1377
- };
1378
- const cssValue = isArbitrary ? value : (saturateScale[value] || (parseFloat(value) / 100));
1379
- return `filter: saturate(${cssValue});`;
1380
- },
1381
- 'sepia': () => {
1382
- const sepiaScale = { '0': '0', '100': '1', 'full': '1' };
1383
- const cssValue = isArbitrary ? value : (sepiaScale[value] || (parseFloat(value) / 100));
1384
- return `filter: sepia(${cssValue});`;
1385
- },
1386
- 'drop-shadow': () => {
1387
- const shadowMap = {
1388
- 'sm': 'drop-shadow(0 1px 1px rgb(0 0 0 / 0.05))',
1389
- 'md': 'drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06))',
1390
- 'lg': 'drop-shadow(0 10px 8px rgb(0 0 0 / 0.04)) drop-shadow(0 4px 3px rgb(0 0 0 / 0.1))',
1391
- 'xl': 'drop-shadow(0 20px 13px rgb(0 0 0 / 0.03)) drop-shadow(0 8px 5px rgb(0 0 0 / 0.08))',
1392
- '2xl': 'drop-shadow(0 25px 25px rgb(0 0 0 / 0.15))',
1393
- 'none': 'drop-shadow(0 0 #0000)'
1394
- };
1395
- const cssValue = isArbitrary ? `drop-shadow(${value.replace(/_/g, ' ')})` : (shadowMap[value] || shadowMap['md']);
1396
- return `filter: ${cssValue};`;
1397
- },
1398
-
1399
- // ============================================
1400
- // BACKGROUND UTILITIES
1401
- // ============================================
1402
- 'bg-size': () => {
1403
- const sizeMap = { 'auto': 'auto', 'cover': 'cover', 'contain': 'contain' };
1404
- const cssValue = isArbitrary ? value.replace(/_/g, ' ') : (sizeMap[value] || value);
1405
- return `background-size: ${cssValue};`;
1406
- },
1407
- 'bg-pos': () => {
1408
- const posMap = {
1409
- 'center': 'center',
1410
- 'top': 'top',
1411
- 'top-right': 'top right',
1412
- 'right': 'right',
1413
- 'bottom-right': 'bottom right',
1414
- 'bottom': 'bottom',
1415
- 'bottom-left': 'bottom left',
1416
- 'left': 'left',
1417
- 'top-left': 'top left'
1418
- };
1419
- const cssValue = isArbitrary ? value.replace(/_/g, ' ') : (posMap[value] || value);
1420
- return `background-position: ${cssValue};`;
1421
- },
1422
- 'bg-repeat': () => {
1423
- const repeatMap = {
1424
- 'repeat': 'repeat',
1425
- 'no-repeat': 'no-repeat',
1426
- 'repeat-x': 'repeat-x',
1427
- 'repeat-y': 'repeat-y',
1428
- 'round': 'round',
1429
- 'space': 'space'
1430
- };
1431
- return `background-repeat: ${repeatMap[value] || value};`;
1432
- },
1433
- 'bg-attachment': () => {
1434
- return `background-attachment: ${value};`;
1435
- },
1436
- 'bg-clip': () => {
1437
- const clipMap = {
1438
- 'border': 'border-box',
1439
- 'padding': 'padding-box',
1440
- 'content': 'content-box',
1441
- 'text': 'text'
1442
- };
1443
- return `background-clip: ${clipMap[value] || value};`;
1444
- },
1445
- 'bg-origin': () => {
1446
- const originMap = {
1447
- 'border': 'border-box',
1448
- 'padding': 'padding-box',
1449
- 'content': 'content-box'
1450
- };
1451
- return `background-origin: ${originMap[value] || value};`;
1452
- },
1453
- 'bg-blend': () => {
1454
- return `background-blend-mode: ${value};`;
1455
- },
1456
- 'bg-image': () => {
1457
- const gradientMap = {
1458
- 'none': 'none',
1459
- 'gradient-to-t': 'linear-gradient(to top, var(--tw-gradient-stops))',
1460
- 'gradient-to-tr': 'linear-gradient(to top right, var(--tw-gradient-stops))',
1461
- 'gradient-to-r': 'linear-gradient(to right, var(--tw-gradient-stops))',
1462
- 'gradient-to-br': 'linear-gradient(to bottom right, var(--tw-gradient-stops))',
1463
- 'gradient-to-b': 'linear-gradient(to bottom, var(--tw-gradient-stops))',
1464
- 'gradient-to-bl': 'linear-gradient(to bottom left, var(--tw-gradient-stops))',
1465
- 'gradient-to-l': 'linear-gradient(to left, var(--tw-gradient-stops))',
1466
- 'gradient-to-tl': 'linear-gradient(to top left, var(--tw-gradient-stops))'
1467
- };
1468
- const cssValue = isArbitrary ? value.replace(/_/g, ' ') : (gradientMap[value] || value);
1469
- return `background-image: ${cssValue};`;
1470
- },
1471
-
1472
- // ============================================
1473
- // BACKDROP FILTER UTILITIES
1474
- // ============================================
1475
- 'backdrop-blur': () => {
1476
- const blurScale = {
1477
- 'none': '0',
1478
- 'sm': '4px',
1479
- 'md': '8px',
1480
- 'lg': '12px',
1481
- 'xl': '16px',
1482
- '2xl': '24px',
1483
- '3xl': '40px'
1484
- };
1485
- const cssValue = isArbitrary ? value : (blurScale[value] || `${value}px`);
1486
- return `backdrop-filter: blur(${cssValue});`;
1487
- },
1488
- 'backdrop-brightness': () => {
1489
- const cssValue = isArbitrary ? value : (parseFloat(value) / 100);
1490
- return `backdrop-filter: brightness(${cssValue});`;
1491
- },
1492
- 'backdrop-contrast': () => {
1493
- const cssValue = isArbitrary ? value : (parseFloat(value) / 100);
1494
- return `backdrop-filter: contrast(${cssValue});`;
1495
- },
1496
- 'backdrop-grayscale': () => {
1497
- const grayscaleScale = { '0': '0', '100': '1', 'full': '1' };
1498
- const cssValue = isArbitrary ? value : (grayscaleScale[value] || (parseFloat(value) / 100));
1499
- return `backdrop-filter: grayscale(${cssValue});`;
1500
- },
1501
- 'backdrop-hue-rotate': () => {
1502
- const cssValue = isArbitrary ? value : `${value}deg`;
1503
- return `backdrop-filter: hue-rotate(${cssValue});`;
1504
- },
1505
- 'backdrop-invert': () => {
1506
- const invertScale = { '0': '0', '100': '1', 'full': '1' };
1507
- const cssValue = isArbitrary ? value : (invertScale[value] || (parseFloat(value) / 100));
1508
- return `backdrop-filter: invert(${cssValue});`;
1509
- },
1510
- 'backdrop-opacity': () => {
1511
- const cssValue = isArbitrary ? value : (parseFloat(value) / 100);
1512
- return `backdrop-filter: opacity(${cssValue});`;
1513
- },
1514
- 'backdrop-saturate': () => {
1515
- const cssValue = isArbitrary ? value : (parseFloat(value) / 100);
1516
- return `backdrop-filter: saturate(${cssValue});`;
1517
- },
1518
- 'backdrop-sepia': () => {
1519
- const sepiaScale = { '0': '0', '100': '1', 'full': '1' };
1520
- const cssValue = isArbitrary ? value : (sepiaScale[value] || (parseFloat(value) / 100));
1521
- return `backdrop-filter: sepia(${cssValue});`;
1522
- },
1523
-
1524
- // ============================================
1525
- // ANIMATION EXTENDED PROPERTIES
1526
- // ============================================
1527
- 'animation-duration': () => {
1528
- const durationMap = {
1529
- 'instant': '75ms',
1530
- 'quick': '100ms',
1531
- 'fast': '150ms',
1532
- 'normal': '200ms',
1533
- 'slow': '300ms',
1534
- 'slower': '500ms',
1535
- 'lazy': '700ms'
1536
- };
1537
- const cssValue = isArbitrary ? value : (durationMap[value] || `${value}ms`);
1538
- return `animation-duration: ${cssValue};`;
1539
- },
1540
- 'animation-delay': () => {
1541
- const delayMap = {
1542
- 'instant': '75ms',
1543
- 'quick': '100ms',
1544
- 'fast': '150ms',
1545
- 'normal': '200ms',
1546
- 'slow': '300ms'
1547
- };
1548
- const cssValue = isArbitrary ? value : (delayMap[value] || `${value}ms`);
1549
- return `animation-delay: ${cssValue};`;
1550
- },
1551
- 'animation-iteration': () => {
1552
- const iterationMap = { 'infinite': 'infinite', 'once': '1', 'twice': '2' };
1553
- const cssValue = iterationMap[value] || value;
1554
- return `animation-iteration-count: ${cssValue};`;
1555
- },
1556
- 'animation-direction': () => {
1557
- return `animation-direction: ${value};`;
1558
- },
1559
- 'animation-fill': () => {
1560
- return `animation-fill-mode: ${value};`;
1561
- },
1562
- 'animation-play': () => {
1563
- return `animation-play-state: ${value};`;
1564
- },
1565
- 'animation-timing': () => {
1566
- const easeMap = {
1567
- 'linear': 'linear',
1568
- 'in': 'cubic-bezier(0.4, 0, 1, 1)',
1569
- 'out': 'cubic-bezier(0, 0, 0.2, 1)',
1570
- 'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)'
1571
- };
1572
- const cssValue = easeMap[value] || value;
1573
- return `animation-timing-function: ${cssValue};`;
1574
- },
1575
-
1576
- // ============================================
1577
- // SCROLL & INTERACTIVITY UTILITIES
1578
- // ============================================
1579
- 'scroll-behavior': () => {
1580
- return `scroll-behavior: ${value};`;
1581
- },
1582
- 'scroll-m': () => {
1583
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
1584
- return `scroll-margin: ${cssValue};`;
1585
- },
1586
- 'scroll-m-x': () => {
1587
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
1588
- return `scroll-margin-left: ${cssValue}; scroll-margin-right: ${cssValue};`;
1589
- },
1590
- 'scroll-m-y': () => {
1591
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
1592
- return `scroll-margin-top: ${cssValue}; scroll-margin-bottom: ${cssValue};`;
1593
- },
1594
- 'scroll-p': () => {
1595
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
1596
- return `scroll-padding: ${cssValue};`;
1597
- },
1598
- 'scroll-p-x': () => {
1599
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
1600
- return `scroll-padding-left: ${cssValue}; scroll-padding-right: ${cssValue};`;
1601
- },
1602
- 'scroll-p-y': () => {
1603
- const cssValue = isArbitrary ? value : `var(--s-${value})`;
1604
- return `scroll-padding-top: ${cssValue}; scroll-padding-bottom: ${cssValue};`;
1605
- },
1606
- 'snap-align': () => {
1607
- return `scroll-snap-align: ${value};`;
1608
- },
1609
- 'snap-stop': () => {
1610
- return `scroll-snap-stop: ${value};`;
1611
- },
1612
- 'snap-type': () => {
1613
- const typeMap = {
1614
- 'none': 'none',
1615
- 'x': 'x mandatory',
1616
- 'y': 'y mandatory',
1617
- 'both': 'both mandatory',
1618
- 'x-proximity': 'x proximity',
1619
- 'y-proximity': 'y proximity'
1620
- };
1621
- return `scroll-snap-type: ${typeMap[value] || value};`;
1622
- },
1623
- 'touch': () => {
1624
- const touchMap = {
1625
- 'auto': 'auto',
1626
- 'none': 'none',
1627
- 'pan-x': 'pan-x',
1628
- 'pan-y': 'pan-y',
1629
- 'pan-left': 'pan-left',
1630
- 'pan-right': 'pan-right',
1631
- 'pan-up': 'pan-up',
1632
- 'pan-down': 'pan-down',
1633
- 'pinch-zoom': 'pinch-zoom',
1634
- 'manipulation': 'manipulation'
1635
- };
1636
- return `touch-action: ${touchMap[value] || value};`;
1637
- },
1638
- 'resize': () => {
1639
- const resizeMap = {
1640
- 'none': 'none',
1641
- 'both': 'both',
1642
- 'x': 'horizontal',
1643
- 'y': 'vertical'
1644
- };
1645
- return `resize: ${resizeMap[value] || value};`;
1646
- },
1647
- 'will-change': () => {
1648
- const willChangeMap = {
1649
- 'auto': 'auto',
1650
- 'scroll': 'scroll-position',
1651
- 'contents': 'contents',
1652
- 'transform': 'transform',
1653
- 'opacity': 'opacity'
1654
- };
1655
- return `will-change: ${willChangeMap[value] || value};`;
1656
- },
1657
- 'color-scheme': () => {
1658
- return `color-scheme: ${value};`;
1659
- },
1660
- 'field-sizing': () => {
1661
- return `field-sizing: ${value};`;
1662
- },
1663
- 'forced-color': () => {
1664
- return `forced-color-adjust: ${value};`;
1665
- },
1666
-
1667
- // ============================================
1668
- // BORDER & OUTLINE UTILITIES
1669
- // ============================================
1670
- 'border-style': () => {
1671
- return `border-style: ${value};`;
1672
- },
1673
- 'outline': () => {
1674
- const cssValue = isArbitrary ? value : `var(--c-${value})`;
1675
- return `outline-color: ${cssValue};`;
1676
- },
1677
- 'outline-style': () => {
1678
- return `outline-style: ${value};`;
1679
- },
1680
- 'outline-w': () => {
1681
- const cssValue = isArbitrary ? value : `${value}px`;
1682
- return `outline-width: ${cssValue};`;
1683
- },
1684
- 'outline-offset': () => {
1685
- const cssValue = isArbitrary ? value : `${value}px`;
1686
- return `outline-offset: ${cssValue};`;
1687
- },
1688
-
1689
- // ============================================
1690
- // SVG UTILITIES
1691
- // ============================================
1692
- 'stroke': () => {
1693
- const cssValue = isArbitrary ? value : `var(--c-${value})`;
1694
- return `stroke: ${cssValue};`;
1695
- },
1696
- 'stroke-w': () => {
1697
- const cssValue = isArbitrary ? value : value;
1698
- return `stroke-width: ${cssValue};`;
1699
- },
1700
- 'fill': () => {
1701
- if (value === 'none') return 'fill: none;';
1702
- const cssValue = isArbitrary ? value : `var(--c-${value})`;
1703
- return `fill: ${cssValue};`;
1704
- },
1705
-
1706
- // ============================================
1707
- // MIX BLEND MODE
1708
- // ============================================
1709
- 'mix-blend': () => {
1710
- return `mix-blend-mode: ${value};`;
1711
- },
1712
-
1713
- // ============================================
1714
- // 3D TRANSFORM UTILITIES
1715
- // ============================================
1716
- 'perspective': () => {
1717
- const perspectiveMap = {
1718
- 'none': 'none',
1719
- 'sm': '500px',
1720
- 'md': '1000px',
1721
- 'lg': '1500px',
1722
- 'xl': '2000px'
1723
- };
1724
- const cssValue = isArbitrary ? value : (perspectiveMap[value] || value);
1725
- return `perspective: ${cssValue};`;
1726
- },
1727
- 'perspective-origin': () => {
1728
- const originMap = {
1729
- 'center': 'center',
1730
- 'top': 'top',
1731
- 'top-right': 'top right',
1732
- 'right': 'right',
1733
- 'bottom-right': 'bottom right',
1734
- 'bottom': 'bottom',
1735
- 'bottom-left': 'bottom left',
1736
- 'left': 'left',
1737
- 'top-left': 'top left'
1738
- };
1739
- const cssValue = isArbitrary ? value.replace(/_/g, ' ') : (originMap[value] || value);
1740
- return `perspective-origin: ${cssValue};`;
1741
- },
1742
- 'rotate-x': () => {
1743
- const rotateValue = isArbitrary ? value : `${value}deg`;
1744
- return `transform: rotateX(${rotateValue});`;
1745
- },
1746
- 'rotate-y': () => {
1747
- const rotateValue = isArbitrary ? value : `${value}deg`;
1748
- return `transform: rotateY(${rotateValue});`;
1749
- },
1750
- 'rotate-z': () => {
1751
- const rotateValue = isArbitrary ? value : `${value}deg`;
1752
- return `transform: rotateZ(${rotateValue});`;
1753
- },
1754
- 'transform-style': () => {
1755
- return `transform-style: ${value};`;
1756
- },
1757
- 'backface': () => {
1758
- const backfaceMap = { 'visible': 'visible', 'hidden': 'hidden' };
1759
- return `backface-visibility: ${backfaceMap[value] || value};`;
1760
- }
1761
- };
1762
-
1763
- const gen = rules[property];
1764
- return gen ? gen() : '';
1765
- }
1766
-
1767
- function generateRule(raw, attrType) {
1768
- // Handle simple layout keywords
1769
- if (attrType === 'layout' && layoutKeywords[raw]) {
1770
- return `[layout~="${raw}"] { ${layoutKeywords[raw]} }\n`;
1771
- }
1772
-
1773
- const token = parseToken(raw);
1774
- let cssDeclaration = '';
1775
-
1776
- switch (attrType) {
1777
- case 'layout':
1778
- cssDeclaration = generateLayoutRule(token);
1779
- break;
1780
- case 'space':
1781
- cssDeclaration = generateSpaceRule(token);
1782
- break;
1783
- case 'visual':
1784
- cssDeclaration = generateVisualRule(token);
1785
- break;
1786
- }
1787
-
1788
- if (!cssDeclaration) return '';
1789
-
1790
- let selector = `[${attrType}~="${raw}"]`;
1791
- // Add pseudo-class for states (but not for 'dark' - handled separately)
1792
- if (token.state && token.state !== 'dark') {
1793
- selector += `:${token.state}`;
1794
- }
1795
-
1796
- return `${selector} { ${cssDeclaration} }\n`;
1797
- }
1798
-
1799
- // ============================================
1800
- // DOM SCANNER
1801
- // ============================================
1802
-
1803
- function scanDOM() {
1804
- const tokens = {
1805
- layout: new Set(),
1806
- space: new Set(),
1807
- visual: new Set()
1808
- };
1809
-
1810
- const elements = document.querySelectorAll('[layout], [space], [visual]');
1811
-
1812
- elements.forEach(el => {
1813
- ['layout', 'space', 'visual'].forEach(attr => {
1814
- const value = el.getAttribute(attr);
1815
- if (value) {
1816
- value.split(/\s+/).forEach(token => {
1817
- if (token) tokens[attr].add(token);
1818
- });
1819
- }
1820
- });
1821
- });
1822
-
1823
- return tokens;
1824
- }
1825
-
1826
- // ============================================
1827
- // CSS COMPILER
1828
- // ============================================
1829
-
1830
- function compileCSS(tokens, config) {
1831
- let css = generateCSSVariables(config);
1832
-
1833
- // Add Preflight if enabled (default: true)
1834
- if (config.preflight !== false) {
1835
- css += generatePreflight();
1836
- }
1837
-
1838
- const baseRules = [];
1839
- const darkRules = [];
1840
- const mediaRules = {
1841
- mob: [],
1842
- tab: [],
1843
- lap: [],
1844
- desk: []
1845
- };
1846
-
1847
- for (const [attrType, values] of Object.entries(tokens)) {
1848
- for (const raw of values) {
1849
- const rule = generateRule(raw, attrType);
1850
- if (rule) {
1851
- // Check for dark: prefix
1852
- if (raw.match(/^(mob:|tab:|lap:|desk:)?dark:/)) {
1853
- darkRules.push(rule);
1854
- }
1855
- // Check for breakpoint prefix
1856
- else {
1857
- const bpMatch = raw.match(/^(mob|tab|lap|desk):/);
1858
- if (bpMatch) {
1859
- mediaRules[bpMatch[1]].push(rule);
1860
- } else {
1861
- baseRules.push(rule);
1862
- }
1863
- }
1864
- }
1865
- }
1866
- }
1867
-
1868
- // Add base rules
1869
- css += baseRules.join('');
1870
-
1871
- // Add media queries
1872
- const { screens } = config.theme;
1873
- for (const [bp, rules] of Object.entries(mediaRules)) {
1874
- if (rules.length > 0) {
1875
- css += `\n@media (min-width: ${screens[bp]}) {\n`;
1876
- css += rules.map(r => ' ' + r).join('');
1877
- css += '}\n';
1878
- }
1879
- }
1880
-
1881
- // Add dark mode rules
1882
- if (darkRules.length > 0) {
1883
- const darkMode = config.darkMode || 'media';
1884
-
1885
- if (darkMode === 'media') {
1886
- css += `\n@media (prefers-color-scheme: dark) {\n`;
1887
- css += darkRules.map(r => ' ' + r).join('');
1888
- css += '}\n';
1889
- } else {
1890
- // Selector strategy
1891
- const darkSelector = Array.isArray(darkMode) ? darkMode[1] : '.dark';
1892
- css += `\n/* Dark Mode */\n`;
1893
- for (const rule of darkRules) {
1894
- css += rule.replace(/^(\[[^\]]+\])/, `${darkSelector} $1`);
1895
- }
1896
- }
1897
- }
1898
-
1899
- return css;
1900
- }
1901
-
1902
- // ============================================
1903
- // STYLE INJECTION
1904
- // ============================================
1905
-
1906
- function injectStyles(css) {
1907
- let styleEl = document.getElementById('senangstart-jit');
1908
- if (!styleEl) {
1909
- styleEl = document.createElement('style');
1910
- styleEl.id = 'senangstart-jit';
1911
- document.head.appendChild(styleEl);
1912
- }
1913
- styleEl.textContent = css;
1914
- }
1915
-
1916
- // ============================================
1917
- // INITIALIZATION
1918
- // ============================================
1919
-
1920
- function init() {
1921
- const userConfig = loadInlineConfig();
1922
- const config = mergeConfig(userConfig);
1923
-
1924
- const tokens = scanDOM();
1925
- const css = compileCSS(tokens, config);
1926
- injectStyles(css);
1927
-
1928
- // Watch for DOM changes
1929
- const observer = new MutationObserver(() => {
1930
- const newTokens = scanDOM();
1931
- const newCSS = compileCSS(newTokens, config);
1932
- injectStyles(newCSS);
1933
- });
1934
-
1935
- observer.observe(document.body, {
1936
- childList: true,
1937
- subtree: true,
1938
- attributes: true,
1939
- attributeFilter: ['layout', 'space', 'visual']
1940
- });
1941
-
1942
- console.log('%c[SenangStart CSS]%c JIT runtime initialized ✓',
1943
- 'color: #2563EB; font-weight: bold;',
1944
- 'color: #10B981;'
1945
- );
1946
- }
1947
-
1948
- // Run on DOMContentLoaded or immediately if already loaded
1949
- if (document.readyState === 'loading') {
1950
- document.addEventListener('DOMContentLoaded', init);
1951
- } else {
1952
- init();
1953
- }
1954
-
1955
- })();
1
+ /* SenangStart CSS - JIT Runtime v0.2.0 | MIT License */
2
+ (() => {
3
+ // src/core/constants.js
4
+ var BREAKPOINTS = ["mob", "tab", "lap", "desk", "tw-sm", "tw-md", "tw-lg", "tw-xl", "tw-2xl"];
5
+ var STATES = ["hover", "focus", "active", "disabled", "dark"];
6
+ var LAYOUT_KEYWORDS = [
7
+ "flex",
8
+ "grid",
9
+ "block",
10
+ "inline",
11
+ "hidden",
12
+ "row",
13
+ "col",
14
+ "row-reverse",
15
+ "col-reverse",
16
+ "center",
17
+ "start",
18
+ "end",
19
+ "between",
20
+ "around",
21
+ "evenly",
22
+ "wrap",
23
+ "nowrap",
24
+ "absolute",
25
+ "relative",
26
+ "fixed",
27
+ "sticky"
28
+ ];
29
+
30
+ // src/core/tokenizer-core.js
31
+ function sanitizeValue(value) {
32
+ if (typeof value !== "string") {
33
+ return "";
34
+ }
35
+ return value.replace(/;/g, "_");
36
+ }
37
+ function isValidToken(token) {
38
+ if (!token.property || typeof token.property !== "string") {
39
+ return false;
40
+ }
41
+ if (token.property.length > 100) {
42
+ return false;
43
+ }
44
+ if (token.value !== null && typeof token.value !== "string") {
45
+ return false;
46
+ }
47
+ if (token.value && token.value.length > 500) {
48
+ return false;
49
+ }
50
+ if (token.breakpoint && !BREAKPOINTS.includes(token.breakpoint)) {
51
+ return false;
52
+ }
53
+ if (token.state && !STATES.includes(token.state)) {
54
+ return false;
55
+ }
56
+ return true;
57
+ }
58
+ function parseToken(raw) {
59
+ const token = {
60
+ raw,
61
+ breakpoint: null,
62
+ state: null,
63
+ property: null,
64
+ value: null,
65
+ isArbitrary: false
66
+ };
67
+ const parts = raw.split(":");
68
+ let idx = 0;
69
+ if (BREAKPOINTS.includes(parts[0])) {
70
+ token.breakpoint = parts[0];
71
+ idx++;
72
+ }
73
+ if (STATES.includes(parts[idx])) {
74
+ token.state = parts[idx];
75
+ idx++;
76
+ }
77
+ if (idx < parts.length) {
78
+ token.property = parts[idx];
79
+ idx++;
80
+ }
81
+ if (idx < parts.length) {
82
+ let value = parts.slice(idx).join(":");
83
+ const arbitraryMatch = value.match(/^\[(.+)\]$/);
84
+ if (arbitraryMatch) {
85
+ token.value = arbitraryMatch[1].replace(/_/g, " ");
86
+ token.isArbitrary = true;
87
+ } else {
88
+ token.value = value;
89
+ }
90
+ }
91
+ return token;
92
+ }
93
+ function tokenize(raw, attrType) {
94
+ if (typeof raw !== "string" || raw.length === 0 || raw.length > 200) {
95
+ return {
96
+ raw,
97
+ breakpoint: null,
98
+ state: null,
99
+ property: null,
100
+ value: null,
101
+ isArbitrary: false,
102
+ attrType,
103
+ error: "Invalid token format"
104
+ };
105
+ }
106
+ const token = {
107
+ raw,
108
+ breakpoint: null,
109
+ state: null,
110
+ property: null,
111
+ value: null,
112
+ isArbitrary: false,
113
+ attrType
114
+ };
115
+ if (attrType === "layout") {
116
+ if (raw.startsWith("z:")) {
117
+ token.property = "z";
118
+ token.value = raw.substring(2);
119
+ return token;
120
+ }
121
+ if (raw.startsWith("overflow:")) {
122
+ token.property = "overflow";
123
+ token.value = raw.substring(9);
124
+ return token;
125
+ }
126
+ if (LAYOUT_KEYWORDS.includes(raw)) {
127
+ token.property = raw;
128
+ token.value = raw;
129
+ return token;
130
+ }
131
+ const parts2 = raw.split(":");
132
+ if (parts2.length === 2 && BREAKPOINTS.includes(parts2[0])) {
133
+ token.breakpoint = parts2[0];
134
+ token.property = parts2[1];
135
+ token.value = parts2[1];
136
+ return token;
137
+ }
138
+ }
139
+ const parts = raw.split(":");
140
+ if (parts.length === 1) {
141
+ token.property = raw;
142
+ token.value = raw;
143
+ return token;
144
+ }
145
+ let idx = 0;
146
+ if (BREAKPOINTS.includes(parts[0])) {
147
+ token.breakpoint = parts[0];
148
+ idx++;
149
+ }
150
+ if (STATES.includes(parts[idx])) {
151
+ token.state = parts[idx];
152
+ idx++;
153
+ }
154
+ if (idx < parts.length) {
155
+ token.property = parts[idx];
156
+ idx++;
157
+ }
158
+ if (idx < parts.length) {
159
+ let value = parts.slice(idx).join(":");
160
+ const arbitraryMatch = value.match(/^\[(.+)\]$/);
161
+ if (arbitraryMatch) {
162
+ token.value = sanitizeValue(arbitraryMatch[1].replace(/_/g, " "));
163
+ token.isArbitrary = true;
164
+ } else {
165
+ token.value = sanitizeValue(value);
166
+ }
167
+ }
168
+ if (!isValidToken(token)) {
169
+ token.error = "Invalid token structure";
170
+ }
171
+ return token;
172
+ }
173
+
174
+ // src/cdn/jit.js
175
+ (function() {
176
+ "use strict";
177
+ const defaultConfig = {
178
+ theme: {
179
+ spacing: {
180
+ "none": "0px",
181
+ "tiny": "4px",
182
+ "small": "8px",
183
+ "medium": "16px",
184
+ "big": "32px",
185
+ "giant": "64px",
186
+ "vast": "128px"
187
+ },
188
+ radius: {
189
+ "none": "0px",
190
+ "small": "4px",
191
+ "medium": "8px",
192
+ "big": "16px",
193
+ "round": "9999px"
194
+ },
195
+ shadow: {
196
+ "none": "none",
197
+ "small": "0 1px 2px rgba(0,0,0,0.05)",
198
+ "medium": "0 4px 6px rgba(0,0,0,0.1)",
199
+ "big": "0 10px 15px rgba(0,0,0,0.15)",
200
+ "giant": "0 25px 50px rgba(0,0,0,0.25)"
201
+ },
202
+ fontSize: {
203
+ "tiny": "12px",
204
+ "small": "14px",
205
+ "medium": "16px",
206
+ "big": "20px",
207
+ "giant": "32px",
208
+ "vast": "48px"
209
+ },
210
+ fontWeight: {
211
+ "normal": "400",
212
+ "medium": "500",
213
+ "bold": "700"
214
+ },
215
+ screens: {
216
+ "mob": "480px",
217
+ "tab": "768px",
218
+ "lap": "1024px",
219
+ "desk": "1280px",
220
+ // Tailwind compatibility
221
+ "tw-sm": "640px",
222
+ "tw-md": "768px",
223
+ "tw-lg": "1024px",
224
+ "tw-xl": "1280px",
225
+ "tw-2xl": "1536px"
226
+ },
227
+ colors: {
228
+ // Base colors
229
+ "white": "#FFFFFF",
230
+ "black": "#000000",
231
+ // Brand/Semantic colors
232
+ "grey": "#6B7280",
233
+ "dark": "#3E4A5D",
234
+ "light": "#DBEAFE",
235
+ "primary": "#2563EB",
236
+ "secondary": "#DBEAFE",
237
+ "success": "#10B981",
238
+ "warning": "#F59E0B",
239
+ "danger": "#EF4444",
240
+ // Red
241
+ "red-50": "#FEF2F2",
242
+ "red-100": "#FEE2E2",
243
+ "red-200": "#FECACA",
244
+ "red-300": "#FCA5A5",
245
+ "red-400": "#F87171",
246
+ "red-500": "#EF4444",
247
+ "red-600": "#DC2626",
248
+ "red-700": "#B91C1C",
249
+ "red-800": "#991B1B",
250
+ "red-900": "#7F1D1D",
251
+ "red-950": "#450A0A",
252
+ // Orange
253
+ "orange-50": "#FFF7ED",
254
+ "orange-100": "#FFEDD5",
255
+ "orange-200": "#FED7AA",
256
+ "orange-300": "#FDBA74",
257
+ "orange-400": "#FB923C",
258
+ "orange-500": "#F97316",
259
+ "orange-600": "#EA580C",
260
+ "orange-700": "#C2410C",
261
+ "orange-800": "#9A3412",
262
+ "orange-900": "#7C2D12",
263
+ "orange-950": "#431407",
264
+ // Amber
265
+ "amber-50": "#FFFBEB",
266
+ "amber-100": "#FEF3C7",
267
+ "amber-200": "#FDE68A",
268
+ "amber-300": "#FCD34D",
269
+ "amber-400": "#FBBF24",
270
+ "amber-500": "#F59E0B",
271
+ "amber-600": "#D97706",
272
+ "amber-700": "#B45309",
273
+ "amber-800": "#92400E",
274
+ "amber-900": "#78350F",
275
+ "amber-950": "#451A03",
276
+ // Yellow
277
+ "yellow-50": "#FEFCE8",
278
+ "yellow-100": "#FEF9C3",
279
+ "yellow-200": "#FEF08A",
280
+ "yellow-300": "#FDE047",
281
+ "yellow-400": "#FACC15",
282
+ "yellow-500": "#EAB308",
283
+ "yellow-600": "#CA8A04",
284
+ "yellow-700": "#A16207",
285
+ "yellow-800": "#854D0E",
286
+ "yellow-900": "#713F12",
287
+ "yellow-950": "#422006",
288
+ // Lime
289
+ "lime-50": "#F7FEE7",
290
+ "lime-100": "#ECFCCB",
291
+ "lime-200": "#D9F99D",
292
+ "lime-300": "#BEF264",
293
+ "lime-400": "#A3E635",
294
+ "lime-500": "#84CC16",
295
+ "lime-600": "#65A30D",
296
+ "lime-700": "#4D7C0F",
297
+ "lime-800": "#3F6212",
298
+ "lime-900": "#365314",
299
+ "lime-950": "#1A2E05",
300
+ // Green
301
+ "green-50": "#F0FDF4",
302
+ "green-100": "#DCFCE7",
303
+ "green-200": "#BBF7D0",
304
+ "green-300": "#86EFAC",
305
+ "green-400": "#4ADE80",
306
+ "green-500": "#22C55E",
307
+ "green-600": "#16A34A",
308
+ "green-700": "#15803D",
309
+ "green-800": "#166534",
310
+ "green-900": "#14532D",
311
+ "green-950": "#052E16",
312
+ // Emerald
313
+ "emerald-50": "#ECFDF5",
314
+ "emerald-100": "#D1FAE5",
315
+ "emerald-200": "#A7F3D0",
316
+ "emerald-300": "#6EE7B7",
317
+ "emerald-400": "#34D399",
318
+ "emerald-500": "#10B981",
319
+ "emerald-600": "#059669",
320
+ "emerald-700": "#047857",
321
+ "emerald-800": "#065F46",
322
+ "emerald-900": "#064E3B",
323
+ "emerald-950": "#022C22",
324
+ // Teal
325
+ "teal-50": "#F0FDFA",
326
+ "teal-100": "#CCFBF1",
327
+ "teal-200": "#99F6E4",
328
+ "teal-300": "#5EEAD4",
329
+ "teal-400": "#2DD4BF",
330
+ "teal-500": "#14B8A6",
331
+ "teal-600": "#0D9488",
332
+ "teal-700": "#0F766E",
333
+ "teal-800": "#115E59",
334
+ "teal-900": "#134E4A",
335
+ "teal-950": "#042F2E",
336
+ // Cyan
337
+ "cyan-50": "#ECFEFF",
338
+ "cyan-100": "#CFFAFE",
339
+ "cyan-200": "#A5F3FC",
340
+ "cyan-300": "#67E8F9",
341
+ "cyan-400": "#22D3EE",
342
+ "cyan-500": "#06B6D4",
343
+ "cyan-600": "#0891B2",
344
+ "cyan-700": "#0E7490",
345
+ "cyan-800": "#155E75",
346
+ "cyan-900": "#164E63",
347
+ "cyan-950": "#083344",
348
+ // Sky
349
+ "sky-50": "#F0F9FF",
350
+ "sky-100": "#E0F2FE",
351
+ "sky-200": "#BAE6FD",
352
+ "sky-300": "#7DD3FC",
353
+ "sky-400": "#38BDF8",
354
+ "sky-500": "#0EA5E9",
355
+ "sky-600": "#0284C7",
356
+ "sky-700": "#0369A1",
357
+ "sky-800": "#075985",
358
+ "sky-900": "#0C4A6E",
359
+ "sky-950": "#082F49",
360
+ // Blue
361
+ "blue-50": "#EFF6FF",
362
+ "blue-100": "#DBEAFE",
363
+ "blue-200": "#BFDBFE",
364
+ "blue-300": "#93C5FD",
365
+ "blue-400": "#60A5FA",
366
+ "blue-500": "#3B82F6",
367
+ "blue-600": "#2563EB",
368
+ "blue-700": "#1D4ED8",
369
+ "blue-800": "#1E40AF",
370
+ "blue-900": "#1E3A8A",
371
+ "blue-950": "#172554",
372
+ // Indigo
373
+ "indigo-50": "#EEF2FF",
374
+ "indigo-100": "#E0E7FF",
375
+ "indigo-200": "#C7D2FE",
376
+ "indigo-300": "#A5B4FC",
377
+ "indigo-400": "#818CF8",
378
+ "indigo-500": "#6366F1",
379
+ "indigo-600": "#4F46E5",
380
+ "indigo-700": "#4338CA",
381
+ "indigo-800": "#3730A3",
382
+ "indigo-900": "#312E81",
383
+ "indigo-950": "#1E1B4B",
384
+ // Violet
385
+ "violet-50": "#F5F3FF",
386
+ "violet-100": "#EDE9FE",
387
+ "violet-200": "#DDD6FE",
388
+ "violet-300": "#C4B5FD",
389
+ "violet-400": "#A78BFA",
390
+ "violet-500": "#8B5CF6",
391
+ "violet-600": "#7C3AED",
392
+ "violet-700": "#6D28D9",
393
+ "violet-800": "#5B21B6",
394
+ "violet-900": "#4C1D95",
395
+ "violet-950": "#2E1065",
396
+ // Purple
397
+ "purple-50": "#FAF5FF",
398
+ "purple-100": "#F3E8FF",
399
+ "purple-200": "#E9D5FF",
400
+ "purple-300": "#D8B4FE",
401
+ "purple-400": "#C084FC",
402
+ "purple-500": "#A855F7",
403
+ "purple-600": "#9333EA",
404
+ "purple-700": "#7E22CE",
405
+ "purple-800": "#6B21A8",
406
+ "purple-900": "#581C87",
407
+ "purple-950": "#3B0764",
408
+ // Fuchsia
409
+ "fuchsia-50": "#FDF4FF",
410
+ "fuchsia-100": "#FAE8FF",
411
+ "fuchsia-200": "#F5D0FE",
412
+ "fuchsia-300": "#F0ABFC",
413
+ "fuchsia-400": "#E879F9",
414
+ "fuchsia-500": "#D946EF",
415
+ "fuchsia-600": "#C026D3",
416
+ "fuchsia-700": "#A21CAF",
417
+ "fuchsia-800": "#86198F",
418
+ "fuchsia-900": "#701A75",
419
+ "fuchsia-950": "#4A044E",
420
+ // Pink
421
+ "pink-50": "#FDF2F8",
422
+ "pink-100": "#FCE7F3",
423
+ "pink-200": "#FBCFE8",
424
+ "pink-300": "#F9A8D4",
425
+ "pink-400": "#F472B6",
426
+ "pink-500": "#EC4899",
427
+ "pink-600": "#DB2777",
428
+ "pink-700": "#BE185D",
429
+ "pink-800": "#9D174D",
430
+ "pink-900": "#831843",
431
+ "pink-950": "#500724",
432
+ // Rose
433
+ "rose-50": "#FFF1F2",
434
+ "rose-100": "#FFE4E6",
435
+ "rose-200": "#FECDD3",
436
+ "rose-300": "#FDA4AF",
437
+ "rose-400": "#FB7185",
438
+ "rose-500": "#F43F5E",
439
+ "rose-600": "#E11D48",
440
+ "rose-700": "#BE123C",
441
+ "rose-800": "#9F1239",
442
+ "rose-900": "#881337",
443
+ "rose-950": "#4C0519",
444
+ // Slate
445
+ "slate-50": "#F8FAFC",
446
+ "slate-100": "#F1F5F9",
447
+ "slate-200": "#E2E8F0",
448
+ "slate-300": "#CBD5E1",
449
+ "slate-400": "#94A3B8",
450
+ "slate-500": "#64748B",
451
+ "slate-600": "#475569",
452
+ "slate-700": "#334155",
453
+ "slate-800": "#1E293B",
454
+ "slate-900": "#0F172A",
455
+ "slate-950": "#020617",
456
+ // Gray
457
+ "gray-50": "#F9FAFB",
458
+ "gray-100": "#F3F4F6",
459
+ "gray-200": "#E5E7EB",
460
+ "gray-300": "#D1D5DB",
461
+ "gray-400": "#9CA3AF",
462
+ "gray-500": "#6B7280",
463
+ "gray-600": "#4B5563",
464
+ "gray-700": "#374151",
465
+ "gray-800": "#1F2937",
466
+ "gray-900": "#111827",
467
+ "gray-950": "#030712",
468
+ // Zinc
469
+ "zinc-50": "#FAFAFA",
470
+ "zinc-100": "#F4F4F5",
471
+ "zinc-200": "#E4E4E7",
472
+ "zinc-300": "#D4D4D8",
473
+ "zinc-400": "#A1A1AA",
474
+ "zinc-500": "#71717A",
475
+ "zinc-600": "#52525B",
476
+ "zinc-700": "#3F3F46",
477
+ "zinc-800": "#27272A",
478
+ "zinc-900": "#18181B",
479
+ "zinc-950": "#09090B",
480
+ // Neutral
481
+ "neutral-50": "#FAFAFA",
482
+ "neutral-100": "#F5F5F5",
483
+ "neutral-200": "#E5E5E5",
484
+ "neutral-300": "#D4D4D4",
485
+ "neutral-400": "#A3A3A3",
486
+ "neutral-500": "#737373",
487
+ "neutral-600": "#525252",
488
+ "neutral-700": "#404040",
489
+ "neutral-800": "#262626",
490
+ "neutral-900": "#171717",
491
+ "neutral-950": "#0A0A0A",
492
+ // Stone
493
+ "stone-50": "#FAFAF9",
494
+ "stone-100": "#F5F5F4",
495
+ "stone-200": "#E7E5E4",
496
+ "stone-300": "#D6D3D1",
497
+ "stone-400": "#A8A29E",
498
+ "stone-500": "#78716C",
499
+ "stone-600": "#57534E",
500
+ "stone-700": "#44403C",
501
+ "stone-800": "#292524",
502
+ "stone-900": "#1C1917",
503
+ "stone-950": "#0C0A09"
504
+ },
505
+ zIndex: {
506
+ "base": "0",
507
+ "low": "10",
508
+ "mid": "50",
509
+ "high": "100",
510
+ "top": "9999"
511
+ }
512
+ },
513
+ // Dark mode configuration
514
+ // 'media' - Uses @media (prefers-color-scheme: dark)
515
+ // 'selector' - Uses .dark class on html/body
516
+ darkMode: "media",
517
+ // Preflight: Include opinionated base reset styles
518
+ // true - Include all preflight styles (default)
519
+ // false - Disable preflight completely
520
+ preflight: true
521
+ };
522
+ const configSchema = {
523
+ theme: {
524
+ type: "object",
525
+ properties: {
526
+ spacing: { type: "object" },
527
+ radius: { type: "object" },
528
+ shadow: { type: "object" },
529
+ fontSize: { type: "object" },
530
+ fontWeight: { type: "object" },
531
+ screens: { type: "object" },
532
+ colors: { type: "object" },
533
+ zIndex: { type: "object" }
534
+ }
535
+ },
536
+ darkMode: { type: "string", enum: ["media", "selector"] },
537
+ preflight: { type: "boolean" }
538
+ };
539
+ function validateConfig(config) {
540
+ if (!config || typeof config !== "object" || Array.isArray(config)) {
541
+ return false;
542
+ }
543
+ if (config.theme && (typeof config.theme !== "object" || Array.isArray(config.theme))) {
544
+ return false;
545
+ }
546
+ if (config.darkMode !== void 0 && config.darkMode !== "media" && config.darkMode !== "selector" && !Array.isArray(config.darkMode)) {
547
+ return false;
548
+ }
549
+ if (config.preflight !== void 0 && typeof config.preflight !== "boolean") {
550
+ return false;
551
+ }
552
+ return true;
553
+ }
554
+ function loadInlineConfig() {
555
+ const configEl = document.querySelector('script[type="senangstart/config"]');
556
+ if (!configEl) return {};
557
+ try {
558
+ const parsed = JSON.parse(configEl.textContent);
559
+ if (!validateConfig(parsed)) {
560
+ console.error("[SenangStart] Invalid config structure");
561
+ return {};
562
+ }
563
+ return parsed;
564
+ } catch (e) {
565
+ console.error("[SenangStart] Invalid config JSON:", e);
566
+ return {};
567
+ }
568
+ }
569
+ function mergeConfig(user) {
570
+ if (!validateConfig(user)) {
571
+ console.error("[SenangStart] Invalid user config, using defaults");
572
+ return JSON.parse(JSON.stringify(defaultConfig));
573
+ }
574
+ const merged = JSON.parse(JSON.stringify(defaultConfig));
575
+ if (user.theme) {
576
+ for (const key of Object.keys(merged.theme)) {
577
+ if (user.theme[key]) {
578
+ merged.theme[key] = { ...merged.theme[key], ...user.theme[key] };
579
+ }
580
+ }
581
+ }
582
+ if (user.darkMode !== void 0) {
583
+ merged.darkMode = user.darkMode;
584
+ }
585
+ if (user.preflight !== void 0) {
586
+ merged.preflight = user.preflight;
587
+ }
588
+ return merged;
589
+ }
590
+ function generateCSSVariables(config) {
591
+ const { theme } = config;
592
+ let css = ":root {\n";
593
+ for (const [key, value] of Object.entries(theme.spacing)) {
594
+ css += ` --s-${key}: ${value};
595
+ `;
596
+ }
597
+ for (const [key, value] of Object.entries(theme.radius)) {
598
+ css += ` --r-${key}: ${value};
599
+ `;
600
+ }
601
+ for (const [key, value] of Object.entries(theme.shadow)) {
602
+ css += ` --shadow-${key}: ${value};
603
+ `;
604
+ }
605
+ for (const [key, value] of Object.entries(theme.fontSize)) {
606
+ css += ` --font-${key}: ${value};
607
+ `;
608
+ }
609
+ for (const [key, value] of Object.entries(theme.fontWeight)) {
610
+ css += ` --fw-${key}: ${value};
611
+ `;
612
+ }
613
+ for (const [key, value] of Object.entries(theme.colors)) {
614
+ css += ` --c-${key}: ${value};
615
+ `;
616
+ }
617
+ for (const [key, value] of Object.entries(theme.zIndex)) {
618
+ css += ` --z-${key}: ${value};
619
+ `;
620
+ }
621
+ const twSpacing = {
622
+ "0": "0px",
623
+ "px": "1px",
624
+ "0.5": "0.125rem",
625
+ "1": "0.25rem",
626
+ "1.5": "0.375rem",
627
+ "2": "0.5rem",
628
+ "2.5": "0.625rem",
629
+ "3": "0.75rem",
630
+ "3.5": "0.875rem",
631
+ "4": "1rem",
632
+ "5": "1.25rem",
633
+ "6": "1.5rem",
634
+ "7": "1.75rem",
635
+ "8": "2rem",
636
+ "9": "2.25rem",
637
+ "10": "2.5rem",
638
+ "11": "2.75rem",
639
+ "12": "3rem",
640
+ "14": "3.5rem",
641
+ "16": "4rem",
642
+ "20": "5rem",
643
+ "24": "6rem",
644
+ "28": "7rem",
645
+ "32": "8rem",
646
+ "36": "9rem",
647
+ "40": "10rem",
648
+ "44": "11rem",
649
+ "48": "12rem",
650
+ "52": "13rem",
651
+ "56": "14rem",
652
+ "60": "15rem",
653
+ "64": "16rem",
654
+ "72": "18rem",
655
+ "80": "20rem",
656
+ "96": "24rem"
657
+ };
658
+ for (const [key, value] of Object.entries(twSpacing)) {
659
+ css += ` --tw-${key}: ${value};
660
+ `;
661
+ }
662
+ const twRadius = {
663
+ "none": "0px",
664
+ "sm": "0.125rem",
665
+ "DEFAULT": "0.25rem",
666
+ "md": "0.375rem",
667
+ "lg": "0.5rem",
668
+ "xl": "0.75rem",
669
+ "2xl": "1rem",
670
+ "3xl": "1.5rem",
671
+ "full": "9999px"
672
+ };
673
+ for (const [key, value] of Object.entries(twRadius)) {
674
+ css += ` --tw-rounded-${key}: ${value};
675
+ `;
676
+ }
677
+ const twShadow = {
678
+ "sm": "0 1px 2px 0 rgb(0 0 0 / 0.05)",
679
+ "DEFAULT": "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
680
+ "md": "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
681
+ "lg": "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
682
+ "xl": "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)",
683
+ "2xl": "0 25px 50px -12px rgb(0 0 0 / 0.25)",
684
+ "inner": "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)",
685
+ "none": "0 0 #0000"
686
+ };
687
+ for (const [key, value] of Object.entries(twShadow)) {
688
+ css += ` --tw-shadow-${key}: ${value};
689
+ `;
690
+ }
691
+ const twFontSize = {
692
+ "xs": "0.75rem",
693
+ "sm": "0.875rem",
694
+ "base": "1rem",
695
+ "lg": "1.125rem",
696
+ "xl": "1.25rem",
697
+ "2xl": "1.5rem",
698
+ "3xl": "1.875rem",
699
+ "4xl": "2.25rem",
700
+ "5xl": "3rem",
701
+ "6xl": "3.75rem",
702
+ "7xl": "4.5rem",
703
+ "8xl": "6rem",
704
+ "9xl": "8rem"
705
+ };
706
+ for (const [key, value] of Object.entries(twFontSize)) {
707
+ css += ` --tw-text-${key}: ${value};
708
+ `;
709
+ }
710
+ const twFontWeight = {
711
+ "thin": "100",
712
+ "extralight": "200",
713
+ "light": "300",
714
+ "normal": "400",
715
+ "medium": "500",
716
+ "semibold": "600",
717
+ "bold": "700",
718
+ "extrabold": "800",
719
+ "black": "900"
720
+ };
721
+ for (const [key, value] of Object.entries(twFontWeight)) {
722
+ css += ` --tw-font-${key}: ${value};
723
+ `;
724
+ }
725
+ css += "}\n\n";
726
+ return css;
727
+ }
728
+ function generatePreflight() {
729
+ return `/* SenangStart Preflight - Opinionated Base Styles */
730
+ *,
731
+ ::before,
732
+ ::after {
733
+ box-sizing: border-box;
734
+ border-width: 0;
735
+ border-style: solid;
736
+ border-color: currentColor;
737
+ }
738
+
739
+ html, :host {
740
+ line-height: 1.5;
741
+ -webkit-text-size-adjust: 100%;
742
+ -moz-tab-size: 4;
743
+ tab-size: 4;
744
+ font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
745
+ font-feature-settings: normal;
746
+ font-variation-settings: normal;
747
+ -webkit-tap-highlight-color: transparent;
748
+ }
749
+
750
+ body {
751
+ margin: 0;
752
+ line-height: inherit;
753
+ }
754
+
755
+ hr {
756
+ height: 0;
757
+ color: inherit;
758
+ border-top-width: 1px;
759
+ }
760
+
761
+ h1, h2, h3, h4, h5, h6 {
762
+ font-size: inherit;
763
+ font-weight: inherit;
764
+ }
765
+
766
+ a {
767
+ color: inherit;
768
+ text-decoration: inherit;
769
+ }
770
+
771
+ b, strong {
772
+ font-weight: bolder;
773
+ }
774
+
775
+ code, kbd, samp, pre {
776
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
777
+ font-size: 1em;
778
+ }
779
+
780
+ small {
781
+ font-size: 80%;
782
+ }
783
+
784
+ sub, sup {
785
+ font-size: 75%;
786
+ line-height: 0;
787
+ position: relative;
788
+ vertical-align: baseline;
789
+ }
790
+
791
+ sub { bottom: -0.25em; }
792
+ sup { top: -0.5em; }
793
+
794
+ table {
795
+ text-indent: 0;
796
+ border-color: inherit;
797
+ border-collapse: collapse;
798
+ }
799
+
800
+ button, input, optgroup, select, textarea {
801
+ font-family: inherit;
802
+ font-size: 100%;
803
+ font-weight: inherit;
804
+ line-height: inherit;
805
+ color: inherit;
806
+ margin: 0;
807
+ padding: 0;
808
+ }
809
+
810
+ button, select {
811
+ text-transform: none;
812
+ }
813
+
814
+ button,
815
+ input:where([type='button']),
816
+ input:where([type='reset']),
817
+ input:where([type='submit']) {
818
+ -webkit-appearance: button;
819
+ background-color: transparent;
820
+ background-image: none;
821
+ }
822
+
823
+ progress {
824
+ vertical-align: baseline;
825
+ }
826
+
827
+ [type='search'] {
828
+ -webkit-appearance: textfield;
829
+ outline-offset: -2px;
830
+ }
831
+
832
+ summary {
833
+ display: list-item;
834
+ }
835
+
836
+ blockquote, dl, dd, h1, h2, h3, h4, h5, h6, hr, figure, p, pre {
837
+ margin: 0;
838
+ }
839
+
840
+ fieldset { margin: 0; padding: 0; }
841
+ legend { padding: 0; }
842
+
843
+ ol, ul, menu {
844
+ list-style: none;
845
+ margin: 0;
846
+ padding: 0;
847
+ }
848
+
849
+ dialog { padding: 0; }
850
+
851
+ textarea { resize: vertical; }
852
+
853
+ input::placeholder, textarea::placeholder {
854
+ opacity: 1;
855
+ color: #9ca3af;
856
+ }
857
+
858
+ button, [role="button"] {
859
+ cursor: pointer;
860
+ }
861
+
862
+ :disabled {
863
+ cursor: default;
864
+ }
865
+
866
+ img, svg, video, canvas, audio, iframe, embed, object {
867
+ display: block;
868
+ vertical-align: middle;
869
+ }
870
+
871
+ img, video {
872
+ max-width: 100%;
873
+ height: auto;
874
+ }
875
+
876
+ [hidden] {
877
+ display: none;
878
+ }
879
+
880
+ /* Keyframe Animations */
881
+ @keyframes spin {
882
+ to { transform: rotate(360deg); }
883
+ }
884
+
885
+ @keyframes ping {
886
+ 75%, 100% {
887
+ transform: scale(2);
888
+ opacity: 0;
889
+ }
890
+ }
891
+
892
+ @keyframes pulse {
893
+ 50% { opacity: .5; }
894
+ }
895
+
896
+ @keyframes bounce {
897
+ 0%, 100% {
898
+ transform: translateY(-25%);
899
+ animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
900
+ }
901
+ 50% {
902
+ transform: none;
903
+ animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
904
+ }
905
+ }
906
+
907
+ `;
908
+ }
909
+ const layoutKeywords = {
910
+ // Display
911
+ "flex": "display: flex;",
912
+ "grid": "display: grid;",
913
+ "inline-flex": "display: inline-flex;",
914
+ "inline-grid": "display: inline-grid;",
915
+ "block": "display: block;",
916
+ "inline": "display: inline-block;",
917
+ "hidden": "display: none;",
918
+ // Flex Direction
919
+ "row": "flex-direction: row;",
920
+ "col": "flex-direction: column;",
921
+ "row-reverse": "flex-direction: row-reverse;",
922
+ "col-reverse": "flex-direction: column-reverse;",
923
+ // Flex Wrap
924
+ "wrap": "flex-wrap: wrap;",
925
+ "nowrap": "flex-wrap: nowrap;",
926
+ "wrap-reverse": "flex-wrap: wrap-reverse;",
927
+ // Flex Item
928
+ "grow": "flex-grow: 1;",
929
+ "grow-0": "flex-grow: 0;",
930
+ "shrink": "flex-shrink: 1;",
931
+ "shrink-0": "flex-shrink: 0;",
932
+ // Grid Auto Flow
933
+ "grid-flow-row": "grid-auto-flow: row;",
934
+ "grid-flow-col": "grid-auto-flow: column;",
935
+ "grid-flow-dense": "grid-auto-flow: dense;",
936
+ "grid-flow-row-dense": "grid-auto-flow: row dense;",
937
+ "grid-flow-col-dense": "grid-auto-flow: column dense;",
938
+ // Shorthand Alignment (backwards compat - simple keywords)
939
+ "center": "justify-content: center; align-items: center;",
940
+ "start": "justify-content: flex-start; align-items: flex-start;",
941
+ "end": "justify-content: flex-end; align-items: flex-end;",
942
+ "between": "justify-content: space-between;",
943
+ "around": "justify-content: space-around;",
944
+ "evenly": "justify-content: space-evenly;",
945
+ // Position
946
+ "absolute": "position: absolute;",
947
+ "relative": "position: relative;",
948
+ "fixed": "position: fixed;",
949
+ "sticky": "position: sticky;",
950
+ "static": "position: static;",
951
+ // Visibility
952
+ "visible": "visibility: visible;",
953
+ "invisible": "visibility: hidden;",
954
+ // Isolation
955
+ "isolate": "isolation: isolate;",
956
+ "isolate-auto": "isolation: auto;",
957
+ // Box Sizing
958
+ "box-border": "box-sizing: border-box;",
959
+ "box-content": "box-sizing: content-box;",
960
+ // Float
961
+ "float-left": "float: left;",
962
+ "float-right": "float: right;",
963
+ "float-none": "float: none;",
964
+ // Clear
965
+ "clear-left": "clear: left;",
966
+ "clear-right": "clear: right;",
967
+ "clear-both": "clear: both;",
968
+ "clear-none": "clear: none;",
969
+ // Container
970
+ "container": "width: 100%; margin-left: auto; margin-right: auto;",
971
+ // Table Border Collapse
972
+ "border-collapse": "border-collapse: collapse;",
973
+ "border-separate": "border-collapse: separate;"
974
+ };
975
+ const breakpoints = BREAKPOINTS;
976
+ const states = STATES;
977
+ function generateLayoutRule(token) {
978
+ const { property, value, isArbitrary } = token;
979
+ if (property === "container") {
980
+ return "width: 100%; margin-left: auto; margin-right: auto;";
981
+ }
982
+ if (property === "justify") {
983
+ const justifyMap = {
984
+ "start": "flex-start",
985
+ "end": "flex-end",
986
+ "center": "center",
987
+ "between": "space-between",
988
+ "around": "space-around",
989
+ "evenly": "space-evenly",
990
+ "stretch": "stretch"
991
+ };
992
+ return `justify-content: ${justifyMap[value] || value};`;
993
+ }
994
+ if (property === "justify-items") {
995
+ return `justify-items: ${value};`;
996
+ }
997
+ if (property === "justify-self") {
998
+ return `justify-self: ${value};`;
999
+ }
1000
+ if (property === "content") {
1001
+ const contentMap = {
1002
+ "start": "flex-start",
1003
+ "end": "flex-end",
1004
+ "center": "center",
1005
+ "between": "space-between",
1006
+ "around": "space-around",
1007
+ "evenly": "space-evenly",
1008
+ "stretch": "stretch"
1009
+ };
1010
+ return `align-content: ${contentMap[value] || value};`;
1011
+ }
1012
+ if (property === "items") {
1013
+ const itemsMap = {
1014
+ "start": "flex-start",
1015
+ "end": "flex-end",
1016
+ "center": "center",
1017
+ "baseline": "baseline",
1018
+ "stretch": "stretch"
1019
+ };
1020
+ return `align-items: ${itemsMap[value] || value};`;
1021
+ }
1022
+ if (property === "self") {
1023
+ const selfMap = {
1024
+ "auto": "auto",
1025
+ "start": "flex-start",
1026
+ "end": "flex-end",
1027
+ "center": "center",
1028
+ "baseline": "baseline",
1029
+ "stretch": "stretch"
1030
+ };
1031
+ return `align-self: ${selfMap[value] || value};`;
1032
+ }
1033
+ if (property === "place-content") {
1034
+ const placeContentMap = {
1035
+ "start": "start",
1036
+ "end": "end",
1037
+ "center": "center",
1038
+ "between": "space-between",
1039
+ "around": "space-around",
1040
+ "evenly": "space-evenly",
1041
+ "stretch": "stretch"
1042
+ };
1043
+ return `place-content: ${placeContentMap[value] || value};`;
1044
+ }
1045
+ if (property === "place-items") {
1046
+ return `place-items: ${value};`;
1047
+ }
1048
+ if (property === "place-self") {
1049
+ return `place-self: ${value};`;
1050
+ }
1051
+ if (property === "z") {
1052
+ return `z-index: var(--z-${value});`;
1053
+ }
1054
+ if (property === "overflow") {
1055
+ return `overflow: ${value};`;
1056
+ }
1057
+ if (property === "overflow-x") {
1058
+ return `overflow-x: ${value};`;
1059
+ }
1060
+ if (property === "overflow-y") {
1061
+ return `overflow-y: ${value};`;
1062
+ }
1063
+ if (property === "aspect") {
1064
+ const aspectMap = {
1065
+ "square": "1 / 1",
1066
+ "video": "16 / 9",
1067
+ "auto": "auto"
1068
+ };
1069
+ const cssValue = isArbitrary ? value.replace(/_/g, " ") : aspectMap[value] || value;
1070
+ return `aspect-ratio: ${cssValue};`;
1071
+ }
1072
+ if (property === "object") {
1073
+ return `object-fit: ${value};`;
1074
+ }
1075
+ if (property === "object-pos") {
1076
+ const cssValue = isArbitrary ? value.replace(/_/g, " ") : value;
1077
+ return `object-position: ${cssValue};`;
1078
+ }
1079
+ if (property === "inset") {
1080
+ const cssValue = isArbitrary ? value : value === "0" ? "0" : `var(--s-${value})`;
1081
+ return `inset: ${cssValue};`;
1082
+ }
1083
+ if (["top", "right", "bottom", "left"].includes(property)) {
1084
+ const cssValue = isArbitrary ? value : value === "0" ? "0" : `var(--s-${value})`;
1085
+ return `${property}: ${cssValue};`;
1086
+ }
1087
+ if (property === "inset-x") {
1088
+ const cssValue = isArbitrary ? value : value === "0" ? "0" : `var(--s-${value})`;
1089
+ return `left: ${cssValue}; right: ${cssValue};`;
1090
+ }
1091
+ if (property === "inset-y") {
1092
+ const cssValue = isArbitrary ? value : value === "0" ? "0" : `var(--s-${value})`;
1093
+ return `top: ${cssValue}; bottom: ${cssValue};`;
1094
+ }
1095
+ if (property === "cols") {
1096
+ return `columns: ${value};`;
1097
+ }
1098
+ if (property === "overscroll") {
1099
+ return `overscroll-behavior: ${value};`;
1100
+ }
1101
+ if (property === "overscroll-x") {
1102
+ return `overscroll-behavior-x: ${value};`;
1103
+ }
1104
+ if (property === "overscroll-y") {
1105
+ return `overscroll-behavior-y: ${value};`;
1106
+ }
1107
+ if (property === "basis") {
1108
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1109
+ return `flex-basis: ${cssValue};`;
1110
+ }
1111
+ if (property === "flex") {
1112
+ const flexPresets = {
1113
+ "1": "1 1 0%",
1114
+ "auto": "1 1 auto",
1115
+ "initial": "0 1 auto",
1116
+ "none": "none"
1117
+ };
1118
+ const cssValue = isArbitrary ? value.replace(/_/g, " ") : flexPresets[value] || value;
1119
+ return `flex: ${cssValue};`;
1120
+ }
1121
+ if (property === "order") {
1122
+ const orderPresets = {
1123
+ "first": "-9999",
1124
+ "last": "9999",
1125
+ "none": "0"
1126
+ };
1127
+ const cssValue = orderPresets[value] || value;
1128
+ return `order: ${cssValue};`;
1129
+ }
1130
+ if (property === "grid-cols") {
1131
+ if (value === "none") {
1132
+ return "grid-template-columns: none;";
1133
+ }
1134
+ if (value === "subgrid") {
1135
+ return "grid-template-columns: subgrid;";
1136
+ }
1137
+ if (isArbitrary) {
1138
+ return `grid-template-columns: ${value.replace(/_/g, " ")};`;
1139
+ }
1140
+ return `grid-template-columns: repeat(${value}, minmax(0, 1fr));`;
1141
+ }
1142
+ if (property === "grid-rows") {
1143
+ if (value === "none") {
1144
+ return "grid-template-rows: none;";
1145
+ }
1146
+ if (value === "subgrid") {
1147
+ return "grid-template-rows: subgrid;";
1148
+ }
1149
+ if (isArbitrary) {
1150
+ return `grid-template-rows: ${value.replace(/_/g, " ")};`;
1151
+ }
1152
+ return `grid-template-rows: repeat(${value}, minmax(0, 1fr));`;
1153
+ }
1154
+ if (property === "col-span") {
1155
+ if (value === "full") {
1156
+ return "grid-column: 1 / -1;";
1157
+ }
1158
+ return `grid-column: span ${value} / span ${value};`;
1159
+ }
1160
+ if (property === "col-start") {
1161
+ return `grid-column-start: ${value};`;
1162
+ }
1163
+ if (property === "col-end") {
1164
+ return `grid-column-end: ${value};`;
1165
+ }
1166
+ if (property === "row-span") {
1167
+ if (value === "full") {
1168
+ return "grid-row: 1 / -1;";
1169
+ }
1170
+ return `grid-row: span ${value} / span ${value};`;
1171
+ }
1172
+ if (property === "row-start") {
1173
+ return `grid-row-start: ${value};`;
1174
+ }
1175
+ if (property === "row-end") {
1176
+ return `grid-row-end: ${value};`;
1177
+ }
1178
+ if (property === "auto-cols") {
1179
+ const autoPresets = {
1180
+ "auto": "auto",
1181
+ "min": "min-content",
1182
+ "max": "max-content",
1183
+ "fr": "minmax(0, 1fr)"
1184
+ };
1185
+ const cssValue = isArbitrary ? value : autoPresets[value] || value;
1186
+ return `grid-auto-columns: ${cssValue};`;
1187
+ }
1188
+ if (property === "auto-rows") {
1189
+ const autoPresets = {
1190
+ "auto": "auto",
1191
+ "min": "min-content",
1192
+ "max": "max-content",
1193
+ "fr": "minmax(0, 1fr)"
1194
+ };
1195
+ const cssValue = isArbitrary ? value : autoPresets[value] || value;
1196
+ return `grid-auto-rows: ${cssValue};`;
1197
+ }
1198
+ if (property === "table") {
1199
+ const tableMap = { "auto": "auto", "fixed": "fixed" };
1200
+ return `table-layout: ${tableMap[value] || value};`;
1201
+ }
1202
+ if (property === "caption") {
1203
+ return `caption-side: ${value};`;
1204
+ }
1205
+ if (property === "border-spacing") {
1206
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1207
+ return `border-spacing: ${cssValue};`;
1208
+ }
1209
+ if (property === "border-spacing-x") {
1210
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1211
+ return `border-spacing: ${cssValue} 0;`;
1212
+ }
1213
+ if (property === "border-spacing-y") {
1214
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1215
+ return `border-spacing: 0 ${cssValue};`;
1216
+ }
1217
+ return layoutKeywords[property] || "";
1218
+ }
1219
+ function generateSpaceRule(token) {
1220
+ const { property, value, isArbitrary } = token;
1221
+ if (value === "auto") {
1222
+ const autoMap = {
1223
+ "m": "margin: auto;",
1224
+ "m-x": "margin-left: auto; margin-right: auto;",
1225
+ "m-y": "margin-top: auto; margin-bottom: auto;",
1226
+ "m-t": "margin-top: auto;",
1227
+ "m-r": "margin-right: auto;",
1228
+ "m-b": "margin-bottom: auto;",
1229
+ "m-l": "margin-left: auto;"
1230
+ };
1231
+ return autoMap[property] || "";
1232
+ }
1233
+ let cssValue;
1234
+ if (isArbitrary) {
1235
+ cssValue = value;
1236
+ } else if (value.startsWith("tw-")) {
1237
+ const twValue = value.slice(3);
1238
+ cssValue = `var(--tw-${twValue})`;
1239
+ } else {
1240
+ cssValue = `var(--s-${value})`;
1241
+ }
1242
+ const map = {
1243
+ "p": `padding: ${cssValue};`,
1244
+ "p-t": `padding-top: ${cssValue};`,
1245
+ "p-r": `padding-right: ${cssValue};`,
1246
+ "p-b": `padding-bottom: ${cssValue};`,
1247
+ "p-l": `padding-left: ${cssValue};`,
1248
+ "p-x": `padding-left: ${cssValue}; padding-right: ${cssValue};`,
1249
+ "p-y": `padding-top: ${cssValue}; padding-bottom: ${cssValue};`,
1250
+ "m": `margin: ${cssValue};`,
1251
+ "m-t": `margin-top: ${cssValue};`,
1252
+ "m-r": `margin-right: ${cssValue};`,
1253
+ "m-b": `margin-bottom: ${cssValue};`,
1254
+ "m-l": `margin-left: ${cssValue};`,
1255
+ "m-x": `margin-left: ${cssValue}; margin-right: ${cssValue};`,
1256
+ "m-y": `margin-top: ${cssValue}; margin-bottom: ${cssValue};`,
1257
+ "g": `gap: ${cssValue};`,
1258
+ "g-x": `column-gap: ${cssValue};`,
1259
+ "g-y": `row-gap: ${cssValue};`,
1260
+ "w": `width: ${cssValue};`,
1261
+ "h": `height: ${cssValue};`,
1262
+ "min-w": `min-width: ${cssValue};`,
1263
+ "max-w": `max-width: ${cssValue};`,
1264
+ "min-h": `min-height: ${cssValue};`,
1265
+ "max-h": `max-height: ${cssValue};`
1266
+ };
1267
+ return map[property] || "";
1268
+ }
1269
+ function generateVisualRule(token) {
1270
+ const { property, value, isArbitrary } = token;
1271
+ const typographyKeywords = {
1272
+ // Font Style
1273
+ "italic": "font-style: italic;",
1274
+ "not-italic": "font-style: normal;",
1275
+ // Font Stretch
1276
+ "font-stretch-condensed": "font-stretch: condensed;",
1277
+ "font-stretch-expanded": "font-stretch: expanded;",
1278
+ "font-stretch-normal": "font-stretch: normal;",
1279
+ // Font Smoothing
1280
+ "antialiased": "-webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;",
1281
+ "subpixel-antialiased": "-webkit-font-smoothing: auto; -moz-osx-font-smoothing: auto;",
1282
+ // Font Variant Numeric
1283
+ "normal-nums": "font-variant-numeric: normal;",
1284
+ "ordinal": "font-variant-numeric: ordinal;",
1285
+ "slashed-zero": "font-variant-numeric: slashed-zero;",
1286
+ "lining-nums": "font-variant-numeric: lining-nums;",
1287
+ "oldstyle-nums": "font-variant-numeric: oldstyle-nums;",
1288
+ "proportional-nums": "font-variant-numeric: proportional-nums;",
1289
+ "tabular-nums": "font-variant-numeric: tabular-nums;",
1290
+ // Text Transform
1291
+ "uppercase": "text-transform: uppercase;",
1292
+ "lowercase": "text-transform: lowercase;",
1293
+ "capitalize": "text-transform: capitalize;",
1294
+ "normal-case": "text-transform: none;",
1295
+ // Text Decoration Line
1296
+ "underline": "text-decoration-line: underline;",
1297
+ "overline": "text-decoration-line: overline;",
1298
+ "line-through": "text-decoration-line: line-through;",
1299
+ "no-underline": "text-decoration-line: none;",
1300
+ // Text Decoration Style
1301
+ "decoration-solid": "text-decoration-style: solid;",
1302
+ "decoration-double": "text-decoration-style: double;",
1303
+ "decoration-dotted": "text-decoration-style: dotted;",
1304
+ "decoration-dashed": "text-decoration-style: dashed;",
1305
+ "decoration-wavy": "text-decoration-style: wavy;",
1306
+ // Text Overflow
1307
+ "truncate": "overflow: hidden; text-overflow: ellipsis; white-space: nowrap;",
1308
+ "text-ellipsis": "text-overflow: ellipsis;",
1309
+ "text-clip": "text-overflow: clip;",
1310
+ // Text Wrap
1311
+ "text-wrap": "text-wrap: wrap;",
1312
+ "text-nowrap": "text-wrap: nowrap;",
1313
+ "text-balance": "text-wrap: balance;",
1314
+ "text-pretty": "text-wrap: pretty;",
1315
+ // Whitespace
1316
+ "whitespace-normal": "white-space: normal;",
1317
+ "whitespace-nowrap": "white-space: nowrap;",
1318
+ "whitespace-pre": "white-space: pre;",
1319
+ "whitespace-pre-line": "white-space: pre-line;",
1320
+ "whitespace-pre-wrap": "white-space: pre-wrap;",
1321
+ "whitespace-break-spaces": "white-space: break-spaces;",
1322
+ // Word Break
1323
+ "break-normal": "overflow-wrap: normal; word-break: normal;",
1324
+ "break-words": "overflow-wrap: break-word;",
1325
+ "break-all": "word-break: break-all;",
1326
+ "break-keep": "word-break: keep-all;",
1327
+ // Hyphens
1328
+ "hyphens-none": "hyphens: none;",
1329
+ "hyphens-manual": "hyphens: manual;",
1330
+ "hyphens-auto": "hyphens: auto;",
1331
+ // Vertical Align
1332
+ "align-baseline": "vertical-align: baseline;",
1333
+ "align-top": "vertical-align: top;",
1334
+ "align-middle": "vertical-align: middle;",
1335
+ "align-bottom": "vertical-align: bottom;",
1336
+ "align-text-top": "vertical-align: text-top;",
1337
+ "align-text-bottom": "vertical-align: text-bottom;",
1338
+ "align-sub": "vertical-align: sub;",
1339
+ "align-super": "vertical-align: super;",
1340
+ // List Style Type
1341
+ "list-none": "list-style-type: none;",
1342
+ "list-disc": "list-style-type: disc;",
1343
+ "list-decimal": "list-style-type: decimal;",
1344
+ "list-square": "list-style-type: square;",
1345
+ // List Style Position
1346
+ "list-inside": "list-style-position: inside;",
1347
+ "list-outside": "list-style-position: outside;"
1348
+ };
1349
+ if (typographyKeywords[property]) {
1350
+ return typographyKeywords[property];
1351
+ }
1352
+ const rules = {
1353
+ "bg": () => {
1354
+ const cssValue = isArbitrary ? value : `var(--c-${value})`;
1355
+ return `background-color: ${cssValue};`;
1356
+ },
1357
+ "text": () => {
1358
+ if (["left", "center", "right", "justify"].includes(value)) {
1359
+ return `text-align: ${value};`;
1360
+ }
1361
+ const cssValue = isArbitrary ? value : `var(--c-${value})`;
1362
+ return `color: ${cssValue};`;
1363
+ },
1364
+ "text-size": () => {
1365
+ let cssValue;
1366
+ if (isArbitrary) {
1367
+ cssValue = value;
1368
+ } else if (value.startsWith("tw-")) {
1369
+ const twValue = value.slice(3);
1370
+ cssValue = `var(--tw-text-${twValue})`;
1371
+ } else {
1372
+ cssValue = `var(--font-${value})`;
1373
+ }
1374
+ return `font-size: ${cssValue};`;
1375
+ },
1376
+ "font": () => {
1377
+ const fontFamilies = {
1378
+ "sans": "ui-sans-serif, system-ui, sans-serif",
1379
+ "serif": "ui-serif, Georgia, serif",
1380
+ "mono": "ui-monospace, monospace"
1381
+ };
1382
+ if (fontFamilies[value]) {
1383
+ return `font-family: ${fontFamilies[value]};`;
1384
+ }
1385
+ let cssValue;
1386
+ if (isArbitrary) {
1387
+ cssValue = value;
1388
+ } else if (value.startsWith("tw-")) {
1389
+ const twValue = value.slice(3);
1390
+ cssValue = `var(--tw-font-${twValue})`;
1391
+ } else {
1392
+ cssValue = `var(--fw-${value})`;
1393
+ }
1394
+ return `font-weight: ${cssValue};`;
1395
+ },
1396
+ "tracking": () => {
1397
+ const trackingScale = {
1398
+ "tighter": "-0.05em",
1399
+ "tight": "-0.025em",
1400
+ "normal": "0",
1401
+ "wide": "0.025em",
1402
+ "wider": "0.05em",
1403
+ "widest": "0.1em"
1404
+ };
1405
+ const cssValue = isArbitrary ? value : trackingScale[value] || value;
1406
+ return `letter-spacing: ${cssValue};`;
1407
+ },
1408
+ "leading": () => {
1409
+ const leadingScale = {
1410
+ "none": "1",
1411
+ "tight": "1.25",
1412
+ "snug": "1.375",
1413
+ "normal": "1.5",
1414
+ "relaxed": "1.625",
1415
+ "loose": "2"
1416
+ };
1417
+ const cssValue = isArbitrary ? value : leadingScale[value] || value;
1418
+ return `line-height: ${cssValue};`;
1419
+ },
1420
+ "line-clamp": () => {
1421
+ return `overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: ${value};`;
1422
+ },
1423
+ "decoration": () => {
1424
+ const cssValue = isArbitrary ? value : `var(--c-${value})`;
1425
+ return `text-decoration-color: ${cssValue};`;
1426
+ },
1427
+ "decoration-thickness": () => {
1428
+ const cssValue = isArbitrary ? value : `${value}px`;
1429
+ return `text-decoration-thickness: ${cssValue};`;
1430
+ },
1431
+ "underline-offset": () => {
1432
+ const cssValue = isArbitrary ? value : `${value}px`;
1433
+ return `text-underline-offset: ${cssValue};`;
1434
+ },
1435
+ "indent": () => {
1436
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1437
+ return `text-indent: ${cssValue};`;
1438
+ },
1439
+ "border": () => {
1440
+ const cssValue = isArbitrary ? value : `var(--c-${value})`;
1441
+ return `border-color: ${cssValue}; border-style: solid;`;
1442
+ },
1443
+ // Border color - directional
1444
+ "border-t": () => {
1445
+ const cssValue = isArbitrary ? value : `var(--c-${value})`;
1446
+ return `border-top-color: ${cssValue}; border-top-style: solid;`;
1447
+ },
1448
+ "border-b": () => {
1449
+ const cssValue = isArbitrary ? value : `var(--c-${value})`;
1450
+ return `border-bottom-color: ${cssValue}; border-bottom-style: solid;`;
1451
+ },
1452
+ "border-l": () => {
1453
+ const cssValue = isArbitrary ? value : `var(--c-${value})`;
1454
+ return `border-left-color: ${cssValue}; border-left-style: solid;`;
1455
+ },
1456
+ "border-r": () => {
1457
+ const cssValue = isArbitrary ? value : `var(--c-${value})`;
1458
+ return `border-right-color: ${cssValue}; border-right-style: solid;`;
1459
+ },
1460
+ "border-x": () => {
1461
+ const cssValue = isArbitrary ? value : `var(--c-${value})`;
1462
+ return `border-left-color: ${cssValue}; border-right-color: ${cssValue}; border-left-style: solid; border-right-style: solid;`;
1463
+ },
1464
+ "border-y": () => {
1465
+ const cssValue = isArbitrary ? value : `var(--c-${value})`;
1466
+ return `border-top-color: ${cssValue}; border-bottom-color: ${cssValue}; border-top-style: solid; border-bottom-style: solid;`;
1467
+ },
1468
+ "border-w": () => {
1469
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1470
+ return `border-width: ${cssValue}; border-style: solid;`;
1471
+ },
1472
+ // Border width - directional
1473
+ "border-t-w": () => {
1474
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1475
+ return `border-top-width: ${cssValue}; border-top-style: solid;`;
1476
+ },
1477
+ "border-b-w": () => {
1478
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1479
+ return `border-bottom-width: ${cssValue}; border-bottom-style: solid;`;
1480
+ },
1481
+ "border-l-w": () => {
1482
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1483
+ return `border-left-width: ${cssValue}; border-left-style: solid;`;
1484
+ },
1485
+ "border-r-w": () => {
1486
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1487
+ return `border-right-width: ${cssValue}; border-right-style: solid;`;
1488
+ },
1489
+ "border-x-w": () => {
1490
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1491
+ return `border-left-width: ${cssValue}; border-right-width: ${cssValue}; border-left-style: solid; border-right-style: solid;`;
1492
+ },
1493
+ "border-y-w": () => {
1494
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1495
+ return `border-top-width: ${cssValue}; border-bottom-width: ${cssValue}; border-top-style: solid; border-bottom-style: solid;`;
1496
+ },
1497
+ "rounded": () => {
1498
+ let cssValue;
1499
+ if (isArbitrary) {
1500
+ cssValue = value;
1501
+ } else if (value.startsWith("tw-")) {
1502
+ const twValue = value.slice(3);
1503
+ cssValue = `var(--tw-rounded-${twValue})`;
1504
+ } else {
1505
+ cssValue = `var(--r-${value})`;
1506
+ }
1507
+ return `border-radius: ${cssValue};`;
1508
+ },
1509
+ "shadow": () => {
1510
+ let cssValue;
1511
+ if (isArbitrary) {
1512
+ cssValue = value;
1513
+ } else if (value.startsWith("tw-")) {
1514
+ const twValue = value.slice(3);
1515
+ cssValue = `var(--tw-shadow-${twValue})`;
1516
+ } else {
1517
+ cssValue = `var(--shadow-${value})`;
1518
+ }
1519
+ return `box-shadow: ${cssValue};`;
1520
+ },
1521
+ "opacity": () => {
1522
+ const opacityValue = isArbitrary ? value : parseFloat(value) / 100;
1523
+ return `opacity: ${opacityValue};`;
1524
+ },
1525
+ "content": () => `content: "${value}";`,
1526
+ // ============================================
1527
+ // TRANSFORM UTILITIES
1528
+ // ============================================
1529
+ "scale": () => {
1530
+ const scaleValue = isArbitrary ? value : parseFloat(value) / 100;
1531
+ return `transform: scale(${scaleValue});`;
1532
+ },
1533
+ "scale-x": () => {
1534
+ const scaleValue = isArbitrary ? value : parseFloat(value) / 100;
1535
+ return `transform: scaleX(${scaleValue});`;
1536
+ },
1537
+ "scale-y": () => {
1538
+ const scaleValue = isArbitrary ? value : parseFloat(value) / 100;
1539
+ return `transform: scaleY(${scaleValue});`;
1540
+ },
1541
+ "rotate": () => {
1542
+ const rotateValue = isArbitrary ? value : `${value}deg`;
1543
+ return `transform: rotate(${rotateValue});`;
1544
+ },
1545
+ "translate-x": () => {
1546
+ const translatePresets = { "0": "0", "full": "100%", "1/2": "50%", "-full": "-100%", "-1/2": "-50%" };
1547
+ const cssValue = isArbitrary ? value : translatePresets[value] || `var(--s-${value})`;
1548
+ return `transform: translateX(${cssValue});`;
1549
+ },
1550
+ "translate-y": () => {
1551
+ const translatePresets = { "0": "0", "full": "100%", "1/2": "50%", "-full": "-100%", "-1/2": "-50%" };
1552
+ const cssValue = isArbitrary ? value : translatePresets[value] || `var(--s-${value})`;
1553
+ return `transform: translateY(${cssValue});`;
1554
+ },
1555
+ "skew-x": () => {
1556
+ const skewValue = isArbitrary ? value : `${value}deg`;
1557
+ return `transform: skewX(${skewValue});`;
1558
+ },
1559
+ "skew-y": () => {
1560
+ const skewValue = isArbitrary ? value : `${value}deg`;
1561
+ return `transform: skewY(${skewValue});`;
1562
+ },
1563
+ "origin": () => {
1564
+ const originMap = {
1565
+ "center": "center",
1566
+ "top": "top",
1567
+ "top-right": "top right",
1568
+ "right": "right",
1569
+ "bottom-right": "bottom right",
1570
+ "bottom": "bottom",
1571
+ "bottom-left": "bottom left",
1572
+ "left": "left",
1573
+ "top-left": "top left"
1574
+ };
1575
+ const cssValue = isArbitrary ? value.replace(/_/g, " ") : originMap[value] || value;
1576
+ return `transform-origin: ${cssValue};`;
1577
+ },
1578
+ // ============================================
1579
+ // TRANSITION UTILITIES
1580
+ // ============================================
1581
+ "transition": () => {
1582
+ const transitionMap = {
1583
+ "none": "transition-property: none;",
1584
+ "all": "transition-property: all; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms;",
1585
+ "colors": "transition-property: color, background-color, border-color; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms;",
1586
+ "opacity": "transition-property: opacity; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms;",
1587
+ "shadow": "transition-property: box-shadow; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms;",
1588
+ "transform": "transition-property: transform; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms;"
1589
+ };
1590
+ return transitionMap[value] || `transition-property: ${value};`;
1591
+ },
1592
+ "duration": () => {
1593
+ const durationMap = {
1594
+ "instant": "75ms",
1595
+ "quick": "100ms",
1596
+ "fast": "150ms",
1597
+ "normal": "200ms",
1598
+ "slow": "300ms",
1599
+ "slower": "500ms",
1600
+ "lazy": "700ms"
1601
+ };
1602
+ const cssValue = isArbitrary ? value : durationMap[value] || `${value}ms`;
1603
+ return `transition-duration: ${cssValue};`;
1604
+ },
1605
+ "ease": () => {
1606
+ const easeMap = {
1607
+ "linear": "linear",
1608
+ "in": "cubic-bezier(0.4, 0, 1, 1)",
1609
+ "out": "cubic-bezier(0, 0, 0.2, 1)",
1610
+ "in-out": "cubic-bezier(0.4, 0, 0.2, 1)"
1611
+ };
1612
+ const cssValue = easeMap[value] || value;
1613
+ return `transition-timing-function: ${cssValue};`;
1614
+ },
1615
+ "delay": () => {
1616
+ const delayMap = {
1617
+ "instant": "75ms",
1618
+ "quick": "100ms",
1619
+ "fast": "150ms",
1620
+ "normal": "200ms",
1621
+ "slow": "300ms"
1622
+ };
1623
+ const cssValue = isArbitrary ? value : delayMap[value] || `${value}ms`;
1624
+ return `transition-delay: ${cssValue};`;
1625
+ },
1626
+ "animate": () => {
1627
+ const animateMap = {
1628
+ "none": "animation: none;",
1629
+ "spin": "animation: spin 1s linear infinite;",
1630
+ "ping": "animation: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;",
1631
+ "pulse": "animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;",
1632
+ "bounce": "animation: bounce 1s infinite;"
1633
+ };
1634
+ return animateMap[value] || `animation: ${value};`;
1635
+ },
1636
+ // ============================================
1637
+ // FILTER UTILITIES
1638
+ // ============================================
1639
+ "blur": () => {
1640
+ const blurScale = {
1641
+ "none": "0",
1642
+ "sm": "4px",
1643
+ "md": "8px",
1644
+ "lg": "12px",
1645
+ "xl": "16px",
1646
+ "2xl": "24px",
1647
+ "3xl": "40px"
1648
+ };
1649
+ const cssValue = isArbitrary ? value : blurScale[value] || `${value}px`;
1650
+ return `filter: blur(${cssValue});`;
1651
+ },
1652
+ "brightness": () => {
1653
+ const brightnessScale = {
1654
+ "0": "0",
1655
+ "50": "0.5",
1656
+ "75": "0.75",
1657
+ "90": "0.9",
1658
+ "95": "0.95",
1659
+ "100": "1",
1660
+ "105": "1.05",
1661
+ "110": "1.1",
1662
+ "125": "1.25",
1663
+ "150": "1.5",
1664
+ "200": "2"
1665
+ };
1666
+ const cssValue = isArbitrary ? value : brightnessScale[value] || parseFloat(value) / 100;
1667
+ return `filter: brightness(${cssValue});`;
1668
+ },
1669
+ "contrast": () => {
1670
+ const contrastScale = {
1671
+ "0": "0",
1672
+ "50": "0.5",
1673
+ "75": "0.75",
1674
+ "100": "1",
1675
+ "125": "1.25",
1676
+ "150": "1.5",
1677
+ "200": "2"
1678
+ };
1679
+ const cssValue = isArbitrary ? value : contrastScale[value] || parseFloat(value) / 100;
1680
+ return `filter: contrast(${cssValue});`;
1681
+ },
1682
+ "grayscale": () => {
1683
+ const grayscaleScale = { "0": "0", "100": "1", "full": "1" };
1684
+ const cssValue = isArbitrary ? value : grayscaleScale[value] || parseFloat(value) / 100;
1685
+ return `filter: grayscale(${cssValue});`;
1686
+ },
1687
+ "hue-rotate": () => {
1688
+ const cssValue = isArbitrary ? value : `${value}deg`;
1689
+ return `filter: hue-rotate(${cssValue});`;
1690
+ },
1691
+ "invert": () => {
1692
+ const invertScale = { "0": "0", "100": "1", "full": "1" };
1693
+ const cssValue = isArbitrary ? value : invertScale[value] || parseFloat(value) / 100;
1694
+ return `filter: invert(${cssValue});`;
1695
+ },
1696
+ "saturate": () => {
1697
+ const saturateScale = {
1698
+ "0": "0",
1699
+ "50": "0.5",
1700
+ "100": "1",
1701
+ "150": "1.5",
1702
+ "200": "2"
1703
+ };
1704
+ const cssValue = isArbitrary ? value : saturateScale[value] || parseFloat(value) / 100;
1705
+ return `filter: saturate(${cssValue});`;
1706
+ },
1707
+ "sepia": () => {
1708
+ const sepiaScale = { "0": "0", "100": "1", "full": "1" };
1709
+ const cssValue = isArbitrary ? value : sepiaScale[value] || parseFloat(value) / 100;
1710
+ return `filter: sepia(${cssValue});`;
1711
+ },
1712
+ "drop-shadow": () => {
1713
+ const shadowMap = {
1714
+ "sm": "drop-shadow(0 1px 1px rgb(0 0 0 / 0.05))",
1715
+ "md": "drop-shadow(0 4px 3px rgb(0 0 0 / 0.07)) drop-shadow(0 2px 2px rgb(0 0 0 / 0.06))",
1716
+ "lg": "drop-shadow(0 10px 8px rgb(0 0 0 / 0.04)) drop-shadow(0 4px 3px rgb(0 0 0 / 0.1))",
1717
+ "xl": "drop-shadow(0 20px 13px rgb(0 0 0 / 0.03)) drop-shadow(0 8px 5px rgb(0 0 0 / 0.08))",
1718
+ "2xl": "drop-shadow(0 25px 25px rgb(0 0 0 / 0.15))",
1719
+ "none": "drop-shadow(0 0 #0000)"
1720
+ };
1721
+ const cssValue = isArbitrary ? `drop-shadow(${value.replace(/_/g, " ")})` : shadowMap[value] || shadowMap["md"];
1722
+ return `filter: ${cssValue};`;
1723
+ },
1724
+ // ============================================
1725
+ // BACKGROUND UTILITIES
1726
+ // ============================================
1727
+ "bg-size": () => {
1728
+ const sizeMap = { "auto": "auto", "cover": "cover", "contain": "contain" };
1729
+ const cssValue = isArbitrary ? value.replace(/_/g, " ") : sizeMap[value] || value;
1730
+ return `background-size: ${cssValue};`;
1731
+ },
1732
+ "bg-pos": () => {
1733
+ const posMap = {
1734
+ "center": "center",
1735
+ "top": "top",
1736
+ "top-right": "top right",
1737
+ "right": "right",
1738
+ "bottom-right": "bottom right",
1739
+ "bottom": "bottom",
1740
+ "bottom-left": "bottom left",
1741
+ "left": "left",
1742
+ "top-left": "top left"
1743
+ };
1744
+ const cssValue = isArbitrary ? value.replace(/_/g, " ") : posMap[value] || value;
1745
+ return `background-position: ${cssValue};`;
1746
+ },
1747
+ "bg-repeat": () => {
1748
+ const repeatMap = {
1749
+ "repeat": "repeat",
1750
+ "no-repeat": "no-repeat",
1751
+ "repeat-x": "repeat-x",
1752
+ "repeat-y": "repeat-y",
1753
+ "round": "round",
1754
+ "space": "space"
1755
+ };
1756
+ return `background-repeat: ${repeatMap[value] || value};`;
1757
+ },
1758
+ "bg-attachment": () => {
1759
+ return `background-attachment: ${value};`;
1760
+ },
1761
+ "bg-clip": () => {
1762
+ const clipMap = {
1763
+ "border": "border-box",
1764
+ "padding": "padding-box",
1765
+ "content": "content-box",
1766
+ "text": "text"
1767
+ };
1768
+ return `background-clip: ${clipMap[value] || value};`;
1769
+ },
1770
+ "bg-origin": () => {
1771
+ const originMap = {
1772
+ "border": "border-box",
1773
+ "padding": "padding-box",
1774
+ "content": "content-box"
1775
+ };
1776
+ return `background-origin: ${originMap[value] || value};`;
1777
+ },
1778
+ "bg-blend": () => {
1779
+ return `background-blend-mode: ${value};`;
1780
+ },
1781
+ "bg-image": () => {
1782
+ const gradientMap = {
1783
+ "none": "none",
1784
+ "gradient-to-t": "linear-gradient(to top, var(--tw-gradient-stops))",
1785
+ "gradient-to-tr": "linear-gradient(to top right, var(--tw-gradient-stops))",
1786
+ "gradient-to-r": "linear-gradient(to right, var(--tw-gradient-stops))",
1787
+ "gradient-to-br": "linear-gradient(to bottom right, var(--tw-gradient-stops))",
1788
+ "gradient-to-b": "linear-gradient(to bottom, var(--tw-gradient-stops))",
1789
+ "gradient-to-bl": "linear-gradient(to bottom left, var(--tw-gradient-stops))",
1790
+ "gradient-to-l": "linear-gradient(to left, var(--tw-gradient-stops))",
1791
+ "gradient-to-tl": "linear-gradient(to top left, var(--tw-gradient-stops))"
1792
+ };
1793
+ const cssValue = isArbitrary ? value.replace(/_/g, " ") : gradientMap[value] || value;
1794
+ return `background-image: ${cssValue};`;
1795
+ },
1796
+ // ============================================
1797
+ // BACKDROP FILTER UTILITIES
1798
+ // ============================================
1799
+ "backdrop-blur": () => {
1800
+ const blurScale = {
1801
+ "none": "0",
1802
+ "sm": "4px",
1803
+ "md": "8px",
1804
+ "lg": "12px",
1805
+ "xl": "16px",
1806
+ "2xl": "24px",
1807
+ "3xl": "40px"
1808
+ };
1809
+ const cssValue = isArbitrary ? value : blurScale[value] || `${value}px`;
1810
+ return `backdrop-filter: blur(${cssValue});`;
1811
+ },
1812
+ "backdrop-brightness": () => {
1813
+ const cssValue = isArbitrary ? value : parseFloat(value) / 100;
1814
+ return `backdrop-filter: brightness(${cssValue});`;
1815
+ },
1816
+ "backdrop-contrast": () => {
1817
+ const cssValue = isArbitrary ? value : parseFloat(value) / 100;
1818
+ return `backdrop-filter: contrast(${cssValue});`;
1819
+ },
1820
+ "backdrop-grayscale": () => {
1821
+ const grayscaleScale = { "0": "0", "100": "1", "full": "1" };
1822
+ const cssValue = isArbitrary ? value : grayscaleScale[value] || parseFloat(value) / 100;
1823
+ return `backdrop-filter: grayscale(${cssValue});`;
1824
+ },
1825
+ "backdrop-hue-rotate": () => {
1826
+ const cssValue = isArbitrary ? value : `${value}deg`;
1827
+ return `backdrop-filter: hue-rotate(${cssValue});`;
1828
+ },
1829
+ "backdrop-invert": () => {
1830
+ const invertScale = { "0": "0", "100": "1", "full": "1" };
1831
+ const cssValue = isArbitrary ? value : invertScale[value] || parseFloat(value) / 100;
1832
+ return `backdrop-filter: invert(${cssValue});`;
1833
+ },
1834
+ "backdrop-opacity": () => {
1835
+ const cssValue = isArbitrary ? value : parseFloat(value) / 100;
1836
+ return `backdrop-filter: opacity(${cssValue});`;
1837
+ },
1838
+ "backdrop-saturate": () => {
1839
+ const cssValue = isArbitrary ? value : parseFloat(value) / 100;
1840
+ return `backdrop-filter: saturate(${cssValue});`;
1841
+ },
1842
+ "backdrop-sepia": () => {
1843
+ const sepiaScale = { "0": "0", "100": "1", "full": "1" };
1844
+ const cssValue = isArbitrary ? value : sepiaScale[value] || parseFloat(value) / 100;
1845
+ return `backdrop-filter: sepia(${cssValue});`;
1846
+ },
1847
+ // ============================================
1848
+ // ANIMATION EXTENDED PROPERTIES
1849
+ // ============================================
1850
+ "animation-duration": () => {
1851
+ const durationMap = {
1852
+ "instant": "75ms",
1853
+ "quick": "100ms",
1854
+ "fast": "150ms",
1855
+ "normal": "200ms",
1856
+ "slow": "300ms",
1857
+ "slower": "500ms",
1858
+ "lazy": "700ms"
1859
+ };
1860
+ const cssValue = isArbitrary ? value : durationMap[value] || `${value}ms`;
1861
+ return `animation-duration: ${cssValue};`;
1862
+ },
1863
+ "animation-delay": () => {
1864
+ const delayMap = {
1865
+ "instant": "75ms",
1866
+ "quick": "100ms",
1867
+ "fast": "150ms",
1868
+ "normal": "200ms",
1869
+ "slow": "300ms"
1870
+ };
1871
+ const cssValue = isArbitrary ? value : delayMap[value] || `${value}ms`;
1872
+ return `animation-delay: ${cssValue};`;
1873
+ },
1874
+ "animation-iteration": () => {
1875
+ const iterationMap = { "infinite": "infinite", "once": "1", "twice": "2" };
1876
+ const cssValue = iterationMap[value] || value;
1877
+ return `animation-iteration-count: ${cssValue};`;
1878
+ },
1879
+ "animation-direction": () => {
1880
+ return `animation-direction: ${value};`;
1881
+ },
1882
+ "animation-fill": () => {
1883
+ return `animation-fill-mode: ${value};`;
1884
+ },
1885
+ "animation-play": () => {
1886
+ return `animation-play-state: ${value};`;
1887
+ },
1888
+ "animation-timing": () => {
1889
+ const easeMap = {
1890
+ "linear": "linear",
1891
+ "in": "cubic-bezier(0.4, 0, 1, 1)",
1892
+ "out": "cubic-bezier(0, 0, 0.2, 1)",
1893
+ "in-out": "cubic-bezier(0.4, 0, 0.2, 1)"
1894
+ };
1895
+ const cssValue = easeMap[value] || value;
1896
+ return `animation-timing-function: ${cssValue};`;
1897
+ },
1898
+ // ============================================
1899
+ // SCROLL & INTERACTIVITY UTILITIES
1900
+ // ============================================
1901
+ "scroll-behavior": () => {
1902
+ return `scroll-behavior: ${value};`;
1903
+ },
1904
+ "scroll-m": () => {
1905
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1906
+ return `scroll-margin: ${cssValue};`;
1907
+ },
1908
+ "scroll-m-x": () => {
1909
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1910
+ return `scroll-margin-left: ${cssValue}; scroll-margin-right: ${cssValue};`;
1911
+ },
1912
+ "scroll-m-y": () => {
1913
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1914
+ return `scroll-margin-top: ${cssValue}; scroll-margin-bottom: ${cssValue};`;
1915
+ },
1916
+ "scroll-p": () => {
1917
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1918
+ return `scroll-padding: ${cssValue};`;
1919
+ },
1920
+ "scroll-p-x": () => {
1921
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1922
+ return `scroll-padding-left: ${cssValue}; scroll-padding-right: ${cssValue};`;
1923
+ },
1924
+ "scroll-p-y": () => {
1925
+ const cssValue = isArbitrary ? value : `var(--s-${value})`;
1926
+ return `scroll-padding-top: ${cssValue}; scroll-padding-bottom: ${cssValue};`;
1927
+ },
1928
+ "snap-align": () => {
1929
+ return `scroll-snap-align: ${value};`;
1930
+ },
1931
+ "snap-stop": () => {
1932
+ return `scroll-snap-stop: ${value};`;
1933
+ },
1934
+ "snap-type": () => {
1935
+ const typeMap = {
1936
+ "none": "none",
1937
+ "x": "x mandatory",
1938
+ "y": "y mandatory",
1939
+ "both": "both mandatory",
1940
+ "x-proximity": "x proximity",
1941
+ "y-proximity": "y proximity"
1942
+ };
1943
+ return `scroll-snap-type: ${typeMap[value] || value};`;
1944
+ },
1945
+ "touch": () => {
1946
+ const touchMap = {
1947
+ "auto": "auto",
1948
+ "none": "none",
1949
+ "pan-x": "pan-x",
1950
+ "pan-y": "pan-y",
1951
+ "pan-left": "pan-left",
1952
+ "pan-right": "pan-right",
1953
+ "pan-up": "pan-up",
1954
+ "pan-down": "pan-down",
1955
+ "pinch-zoom": "pinch-zoom",
1956
+ "manipulation": "manipulation"
1957
+ };
1958
+ return `touch-action: ${touchMap[value] || value};`;
1959
+ },
1960
+ "resize": () => {
1961
+ const resizeMap = {
1962
+ "none": "none",
1963
+ "both": "both",
1964
+ "x": "horizontal",
1965
+ "y": "vertical"
1966
+ };
1967
+ return `resize: ${resizeMap[value] || value};`;
1968
+ },
1969
+ "will-change": () => {
1970
+ const willChangeMap = {
1971
+ "auto": "auto",
1972
+ "scroll": "scroll-position",
1973
+ "contents": "contents",
1974
+ "transform": "transform",
1975
+ "opacity": "opacity"
1976
+ };
1977
+ return `will-change: ${willChangeMap[value] || value};`;
1978
+ },
1979
+ "color-scheme": () => {
1980
+ return `color-scheme: ${value};`;
1981
+ },
1982
+ "field-sizing": () => {
1983
+ return `field-sizing: ${value};`;
1984
+ },
1985
+ "forced-color": () => {
1986
+ return `forced-color-adjust: ${value};`;
1987
+ },
1988
+ // ============================================
1989
+ // BORDER & OUTLINE UTILITIES
1990
+ // ============================================
1991
+ "border-style": () => {
1992
+ return `border-style: ${value};`;
1993
+ },
1994
+ "outline": () => {
1995
+ const cssValue = isArbitrary ? value : `var(--c-${value})`;
1996
+ return `outline-color: ${cssValue};`;
1997
+ },
1998
+ "outline-style": () => {
1999
+ return `outline-style: ${value};`;
2000
+ },
2001
+ "outline-w": () => {
2002
+ const cssValue = isArbitrary ? value : `${value}px`;
2003
+ return `outline-width: ${cssValue};`;
2004
+ },
2005
+ "outline-offset": () => {
2006
+ const cssValue = isArbitrary ? value : `${value}px`;
2007
+ return `outline-offset: ${cssValue};`;
2008
+ },
2009
+ // ============================================
2010
+ // SVG UTILITIES
2011
+ // ============================================
2012
+ "stroke": () => {
2013
+ const cssValue = isArbitrary ? value : `var(--c-${value})`;
2014
+ return `stroke: ${cssValue};`;
2015
+ },
2016
+ "stroke-w": () => {
2017
+ const cssValue = isArbitrary ? value : value;
2018
+ return `stroke-width: ${cssValue};`;
2019
+ },
2020
+ "fill": () => {
2021
+ if (value === "none") return "fill: none;";
2022
+ const cssValue = isArbitrary ? value : `var(--c-${value})`;
2023
+ return `fill: ${cssValue};`;
2024
+ },
2025
+ // ============================================
2026
+ // MIX BLEND MODE
2027
+ // ============================================
2028
+ "mix-blend": () => {
2029
+ return `mix-blend-mode: ${value};`;
2030
+ },
2031
+ // ============================================
2032
+ // 3D TRANSFORM UTILITIES
2033
+ // ============================================
2034
+ "perspective": () => {
2035
+ const perspectiveMap = {
2036
+ "none": "none",
2037
+ "sm": "500px",
2038
+ "md": "1000px",
2039
+ "lg": "1500px",
2040
+ "xl": "2000px"
2041
+ };
2042
+ const cssValue = isArbitrary ? value : perspectiveMap[value] || value;
2043
+ return `perspective: ${cssValue};`;
2044
+ },
2045
+ "perspective-origin": () => {
2046
+ const originMap = {
2047
+ "center": "center",
2048
+ "top": "top",
2049
+ "top-right": "top right",
2050
+ "right": "right",
2051
+ "bottom-right": "bottom right",
2052
+ "bottom": "bottom",
2053
+ "bottom-left": "bottom left",
2054
+ "left": "left",
2055
+ "top-left": "top left"
2056
+ };
2057
+ const cssValue = isArbitrary ? value.replace(/_/g, " ") : originMap[value] || value;
2058
+ return `perspective-origin: ${cssValue};`;
2059
+ },
2060
+ "rotate-x": () => {
2061
+ const rotateValue = isArbitrary ? value : `${value}deg`;
2062
+ return `transform: rotateX(${rotateValue});`;
2063
+ },
2064
+ "rotate-y": () => {
2065
+ const rotateValue = isArbitrary ? value : `${value}deg`;
2066
+ return `transform: rotateY(${rotateValue});`;
2067
+ },
2068
+ "rotate-z": () => {
2069
+ const rotateValue = isArbitrary ? value : `${value}deg`;
2070
+ return `transform: rotateZ(${rotateValue});`;
2071
+ },
2072
+ "transform-style": () => {
2073
+ return `transform-style: ${value};`;
2074
+ },
2075
+ "backface": () => {
2076
+ const backfaceMap = { "visible": "visible", "hidden": "hidden" };
2077
+ return `backface-visibility: ${backfaceMap[value] || value};`;
2078
+ }
2079
+ };
2080
+ const gen = rules[property];
2081
+ return gen ? gen() : "";
2082
+ }
2083
+ function generateRule(raw, attrType) {
2084
+ if (attrType === "layout" && layoutKeywords[raw]) {
2085
+ return `[layout~="${raw}"] { ${layoutKeywords[raw]} }
2086
+ `;
2087
+ }
2088
+ const token = parseToken(raw);
2089
+ let cssDeclaration = "";
2090
+ switch (attrType) {
2091
+ case "layout":
2092
+ cssDeclaration = generateLayoutRule(token);
2093
+ break;
2094
+ case "space":
2095
+ cssDeclaration = generateSpaceRule(token);
2096
+ break;
2097
+ case "visual":
2098
+ cssDeclaration = generateVisualRule(token);
2099
+ break;
2100
+ }
2101
+ if (!cssDeclaration) return "";
2102
+ let selector = `[${attrType}~="${raw}"]`;
2103
+ if (token.state && token.state !== "dark") {
2104
+ selector += `:${token.state}`;
2105
+ }
2106
+ let rule = `${selector} { ${cssDeclaration} }
2107
+ `;
2108
+ if (token.state === "dark") {
2109
+ rule = `:where(.dark) ${rule}`;
2110
+ }
2111
+ if (token.breakpoint) {
2112
+ const screenWidth = defaultConfig.theme.screens[token.breakpoint];
2113
+ if (screenWidth) {
2114
+ return `@media (min-width: ${screenWidth}) { ${rule} }
2115
+ `;
2116
+ }
2117
+ }
2118
+ return rule;
2119
+ }
2120
+ function scanDOM() {
2121
+ const tokens = {
2122
+ layout: /* @__PURE__ */ new Set(),
2123
+ space: /* @__PURE__ */ new Set(),
2124
+ visual: /* @__PURE__ */ new Set()
2125
+ };
2126
+ const elements = document.querySelectorAll("[layout], [space], [visual]");
2127
+ elements.forEach((el) => {
2128
+ ["layout", "space", "visual"].forEach((attr) => {
2129
+ const value = el.getAttribute(attr);
2130
+ if (value) {
2131
+ value.split(/\s+/).forEach((token) => {
2132
+ if (token) tokens[attr].add(token);
2133
+ });
2134
+ }
2135
+ });
2136
+ });
2137
+ return tokens;
2138
+ }
2139
+ function compileCSS(tokens, config) {
2140
+ let css = generateCSSVariables(config);
2141
+ if (config.preflight !== false) {
2142
+ css += generatePreflight();
2143
+ }
2144
+ const tokenArray = [];
2145
+ for (const [attrType, values] of Object.entries(tokens)) {
2146
+ for (const raw of values) {
2147
+ tokenArray.push({ raw, attrType });
2148
+ }
2149
+ }
2150
+ const baseTokens = [];
2151
+ const darkTokens = [];
2152
+ const breakpointTokens = {};
2153
+ const { screens } = config.theme;
2154
+ for (const bp of Object.keys(screens)) {
2155
+ breakpointTokens[bp] = [];
2156
+ }
2157
+ for (const token of tokenArray) {
2158
+ const parsed = tokenize(token.raw, token.attrType);
2159
+ if (parsed.state === "dark") {
2160
+ darkTokens.push(parsed);
2161
+ } else if (parsed.breakpoint) {
2162
+ if (!breakpointTokens[parsed.breakpoint]) {
2163
+ breakpointTokens[parsed.breakpoint] = [];
2164
+ }
2165
+ breakpointTokens[parsed.breakpoint].push(parsed);
2166
+ } else {
2167
+ baseTokens.push(parsed);
2168
+ }
2169
+ }
2170
+ const displayProps = ["flex", "grid", "inline-flex", "inline-grid", "block", "inline", "hidden", "contents"];
2171
+ const baseDisplayTokens = /* @__PURE__ */ new Map();
2172
+ for (const token of baseTokens) {
2173
+ if (token.attrType && displayProps.includes(token.property)) {
2174
+ if (!baseDisplayTokens.has(token.attrType)) {
2175
+ baseDisplayTokens.set(token.attrType, /* @__PURE__ */ new Set());
2176
+ }
2177
+ baseDisplayTokens.get(token.attrType).add(token.raw);
2178
+ }
2179
+ }
2180
+ for (const token of baseTokens) {
2181
+ css += generateRule(token.raw, token.attrType);
2182
+ }
2183
+ for (const [bp, bpTokens] of Object.entries(breakpointTokens)) {
2184
+ if (bpTokens.length > 0) {
2185
+ css += `
2186
+ @media (min-width: ${screens[bp]}) {
2187
+ `;
2188
+ const processedResetSelectors = /* @__PURE__ */ new Set();
2189
+ for (const bpToken of bpTokens) {
2190
+ if (bpToken.attrType && displayProps.includes(bpToken.property)) {
2191
+ if (baseDisplayTokens.has(bpToken.attrType)) {
2192
+ const baseDisplays = baseDisplayTokens.get(bpToken.attrType);
2193
+ if (baseDisplays.size > 0 && !baseDisplays.has(bpToken.raw) && !processedResetSelectors.has(bpToken.raw)) {
2194
+ const selector = `[${bpToken.attrType}~="${bpToken.raw}"]`;
2195
+ css += ` ${selector} { display: revert-layer; }
2196
+ `;
2197
+ processedResetSelectors.add(bpToken.raw);
2198
+ }
2199
+ }
2200
+ }
2201
+ }
2202
+ for (const token of bpTokens) {
2203
+ css += " " + generateRule(token.raw, token.attrType);
2204
+ }
2205
+ css += "}\n";
2206
+ }
2207
+ }
2208
+ if (darkTokens.length > 0) {
2209
+ const darkMode = config.darkMode || "media";
2210
+ if (darkMode === "media") {
2211
+ css += `
2212
+ @media (prefers-color-scheme: dark) {
2213
+ `;
2214
+ for (const token of darkTokens) {
2215
+ css += " " + generateRule(token.raw, token.attrType);
2216
+ }
2217
+ css += "}\n";
2218
+ } else {
2219
+ const darkSelector = Array.isArray(darkMode) ? darkMode[1] : ".dark";
2220
+ css += `
2221
+ /* Dark Mode */
2222
+ `;
2223
+ for (const token of darkTokens) {
2224
+ const rule = generateRule(token.raw, token.attrType);
2225
+ css += rule.replace(/^(\[[^\]]+\])/, `${darkSelector} $1`);
2226
+ }
2227
+ }
2228
+ }
2229
+ return css;
2230
+ }
2231
+ function injectStyles(css) {
2232
+ let styleEl = document.getElementById("senangstart-jit");
2233
+ if (!styleEl) {
2234
+ styleEl = document.createElement("style");
2235
+ styleEl.id = "senangstart-jit";
2236
+ document.head.appendChild(styleEl);
2237
+ }
2238
+ styleEl.textContent = css;
2239
+ }
2240
+ function init() {
2241
+ const userConfig = loadInlineConfig();
2242
+ const config = mergeConfig(userConfig);
2243
+ const tokens = scanDOM();
2244
+ const css = compileCSS(tokens, config);
2245
+ injectStyles(css);
2246
+ const observer = new MutationObserver(() => {
2247
+ const newTokens = scanDOM();
2248
+ const newCSS = compileCSS(newTokens, config);
2249
+ injectStyles(newCSS);
2250
+ });
2251
+ observer.observe(document.body, {
2252
+ childList: true,
2253
+ subtree: true,
2254
+ attributes: true,
2255
+ attributeFilter: ["layout", "space", "visual"]
2256
+ });
2257
+ console.log(
2258
+ "%c[SenangStart CSS]%c JIT runtime initialized \u2713",
2259
+ "color: #2563EB; font-weight: bold;",
2260
+ "color: #10B981;"
2261
+ );
2262
+ }
2263
+ if (document.readyState === "loading") {
2264
+ document.addEventListener("DOMContentLoaded", init);
2265
+ } else {
2266
+ init();
2267
+ }
2268
+ })();
2269
+ })();