@arbidocs/blocks 0.5.63 → 0.5.65

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 (177) hide show
  1. package/dist/{ConnectedDocumentViewer-7VKAM6KD.js → ConnectedDocumentViewer-HKIBNGGG.js} +10 -9
  2. package/dist/{ConnectedDocumentViewer-7VKAM6KD.js.map → ConnectedDocumentViewer-HKIBNGGG.js.map} +1 -1
  3. package/dist/{ConnectedDocumentViewer-FGQ27H4B.cjs → ConnectedDocumentViewer-YSZWOVGN.cjs} +11 -10
  4. package/dist/{ConnectedDocumentViewer-FGQ27H4B.cjs.map → ConnectedDocumentViewer-YSZWOVGN.cjs.map} +1 -1
  5. package/dist/{ConnectedNativeDocxComparison-HJ4FTVH6.cjs → ConnectedNativeDocxComparison-L3R3ROPZ.cjs} +7 -7
  6. package/dist/{ConnectedNativeDocxComparison-HJ4FTVH6.cjs.map → ConnectedNativeDocxComparison-L3R3ROPZ.cjs.map} +1 -1
  7. package/dist/{ConnectedNativeDocxComparison-FPW3BNBN.js → ConnectedNativeDocxComparison-PSAP3Q7D.js} +6 -6
  8. package/dist/{ConnectedNativeDocxComparison-FPW3BNBN.js.map → ConnectedNativeDocxComparison-PSAP3Q7D.js.map} +1 -1
  9. package/dist/{ConnectedNativeDocxEditor-S7NJMDSU.js → ConnectedNativeDocxEditor-PI6QTPXZ.js} +5 -5
  10. package/dist/{ConnectedNativeDocxEditor-S7NJMDSU.js.map → ConnectedNativeDocxEditor-PI6QTPXZ.js.map} +1 -1
  11. package/dist/{ConnectedNativeDocxEditor-PF46MU5H.cjs → ConnectedNativeDocxEditor-VDBC4XRT.cjs} +7 -7
  12. package/dist/{ConnectedNativeDocxEditor-PF46MU5H.cjs.map → ConnectedNativeDocxEditor-VDBC4XRT.cjs.map} +1 -1
  13. package/dist/{ConnectedStreamedWordArtifact-5MHLV24V.js → ConnectedStreamedWordArtifact-V4MTKVNE.js} +6 -6
  14. package/dist/ConnectedStreamedWordArtifact-V4MTKVNE.js.map +1 -0
  15. package/dist/{ConnectedStreamedWordArtifact-LNGW7YGV.cjs → ConnectedStreamedWordArtifact-YSW6D7AG.cjs} +7 -7
  16. package/dist/ConnectedStreamedWordArtifact-YSW6D7AG.cjs.map +1 -0
  17. package/dist/{DocumentReviewCard-VFNMJSK7.cjs → DocumentReviewCard-BQ6ZD5MD.cjs} +6 -6
  18. package/dist/{DocumentReviewCard-VFNMJSK7.cjs.map → DocumentReviewCard-BQ6ZD5MD.cjs.map} +1 -1
  19. package/dist/{DocumentReviewCard-5U3TGJZA.js → DocumentReviewCard-TQQADJ36.js} +6 -6
  20. package/dist/{DocumentReviewCard-5U3TGJZA.js.map → DocumentReviewCard-TQQADJ36.js.map} +1 -1
  21. package/dist/{WorkspaceTableView-DHMCJRC6.cjs → WorkspaceTableView-GKMVTECZ.cjs} +6 -6
  22. package/dist/{WorkspaceTableView-DHMCJRC6.cjs.map → WorkspaceTableView-GKMVTECZ.cjs.map} +1 -1
  23. package/dist/{WorkspaceTableView-EH5CEB44.js → WorkspaceTableView-YFLVFRJL.js} +4 -4
  24. package/dist/{WorkspaceTableView-EH5CEB44.js.map → WorkspaceTableView-YFLVFRJL.js.map} +1 -1
  25. package/dist/agents/index.cjs +345 -344
  26. package/dist/agents/index.js +6 -5
  27. package/dist/{chunk-NDVLCOWS.js → chunk-2LUA7UDE.js} +7 -7
  28. package/dist/{chunk-NDVLCOWS.js.map → chunk-2LUA7UDE.js.map} +1 -1
  29. package/dist/{chunk-77IAOKZO.js → chunk-2VH2PT3J.js} +5 -38
  30. package/dist/chunk-2VH2PT3J.js.map +1 -0
  31. package/dist/{chunk-IC6SBDYA.js → chunk-4CI42DCG.js} +3 -3
  32. package/dist/{chunk-IC6SBDYA.js.map → chunk-4CI42DCG.js.map} +1 -1
  33. package/dist/{chunk-IFLFLP4K.js → chunk-4Q7ON335.js} +6 -5
  34. package/dist/chunk-4Q7ON335.js.map +1 -0
  35. package/dist/{chunk-IUFS3AYQ.js → chunk-5EGTGHBW.js} +7 -7
  36. package/dist/{chunk-IUFS3AYQ.js.map → chunk-5EGTGHBW.js.map} +1 -1
  37. package/dist/{chunk-OLDGMBEF.cjs → chunk-67AFX23Y.cjs} +185 -91
  38. package/dist/chunk-67AFX23Y.cjs.map +1 -0
  39. package/dist/{chunk-5CWBAINB.js → chunk-6OMIIF76.js} +3 -3
  40. package/dist/{chunk-5CWBAINB.js.map → chunk-6OMIIF76.js.map} +1 -1
  41. package/dist/chunk-6QZ35CTZ.js +594 -0
  42. package/dist/chunk-6QZ35CTZ.js.map +1 -0
  43. package/dist/{chunk-4RJPTXUQ.cjs → chunk-7MOQO6NO.cjs} +5 -5
  44. package/dist/{chunk-4RJPTXUQ.cjs.map → chunk-7MOQO6NO.cjs.map} +1 -1
  45. package/dist/chunk-AESJLGMC.cjs +1228 -0
  46. package/dist/chunk-AESJLGMC.cjs.map +1 -0
  47. package/dist/{chunk-EOIJ5JYP.cjs → chunk-B3CRSCLK.cjs} +4 -4
  48. package/dist/{chunk-EOIJ5JYP.cjs.map → chunk-B3CRSCLK.cjs.map} +1 -1
  49. package/dist/{chunk-GRDLCRNL.js → chunk-BELZ2WD2.js} +5 -5
  50. package/dist/{chunk-GRDLCRNL.js.map → chunk-BELZ2WD2.js.map} +1 -1
  51. package/dist/chunk-C2S246BV.js +1225 -0
  52. package/dist/chunk-C2S246BV.js.map +1 -0
  53. package/dist/{chunk-TAI23FCY.js → chunk-CEKOZAGO.js} +3 -3
  54. package/dist/{chunk-TAI23FCY.js.map → chunk-CEKOZAGO.js.map} +1 -1
  55. package/dist/{chunk-HVOPUYAG.cjs → chunk-CJF7B5A7.cjs} +29 -28
  56. package/dist/chunk-CJF7B5A7.cjs.map +1 -0
  57. package/dist/{chunk-LBKTTQUR.cjs → chunk-CMYJEIZB.cjs} +12 -12
  58. package/dist/{chunk-LBKTTQUR.cjs.map → chunk-CMYJEIZB.cjs.map} +1 -1
  59. package/dist/{chunk-2SLDVFOZ.js → chunk-CRHY7DBO.js} +3 -3
  60. package/dist/{chunk-2SLDVFOZ.js.map → chunk-CRHY7DBO.js.map} +1 -1
  61. package/dist/{chunk-23ACBETH.cjs → chunk-D27BBGUF.cjs} +4 -4
  62. package/dist/{chunk-23ACBETH.cjs.map → chunk-D27BBGUF.cjs.map} +1 -1
  63. package/dist/{chunk-3X37I6QE.cjs → chunk-DJE2E7YH.cjs} +29 -29
  64. package/dist/{chunk-3X37I6QE.cjs.map → chunk-DJE2E7YH.cjs.map} +1 -1
  65. package/dist/{chunk-CCSF7RI4.cjs → chunk-EG3BB32W.cjs} +3 -3
  66. package/dist/{chunk-CCSF7RI4.cjs.map → chunk-EG3BB32W.cjs.map} +1 -1
  67. package/dist/{chunk-MAKTAR7H.cjs → chunk-F777MGVA.cjs} +18 -18
  68. package/dist/{chunk-MAKTAR7H.cjs.map → chunk-F777MGVA.cjs.map} +1 -1
  69. package/dist/{chunk-TFWCREOL.js → chunk-GPYLXEZO.js} +9 -506
  70. package/dist/chunk-GPYLXEZO.js.map +1 -0
  71. package/dist/{chunk-OY3I32ZS.js → chunk-GX37C5QT.js} +4 -4
  72. package/dist/{chunk-OY3I32ZS.js.map → chunk-GX37C5QT.js.map} +1 -1
  73. package/dist/chunk-I4IS6ST6.cjs +48 -0
  74. package/dist/chunk-I4IS6ST6.cjs.map +1 -0
  75. package/dist/{chunk-OZL5ABLF.js → chunk-IRXPUQFP.js} +3 -3
  76. package/dist/{chunk-OZL5ABLF.js.map → chunk-IRXPUQFP.js.map} +1 -1
  77. package/dist/chunk-J77BACGX.js +575 -0
  78. package/dist/chunk-J77BACGX.js.map +1 -0
  79. package/dist/{chunk-X3JJTHQ4.cjs → chunk-JSHBC47B.cjs} +55 -55
  80. package/dist/{chunk-X3JJTHQ4.cjs.map → chunk-JSHBC47B.cjs.map} +1 -1
  81. package/dist/{chunk-Y6ZNWC7E.cjs → chunk-K26RLK2Y.cjs} +3 -3
  82. package/dist/{chunk-Y6ZNWC7E.cjs.map → chunk-K26RLK2Y.cjs.map} +1 -1
  83. package/dist/{chunk-PKDPQS6Z.js → chunk-KNOSLLTC.js} +3 -3
  84. package/dist/{chunk-PKDPQS6Z.js.map → chunk-KNOSLLTC.js.map} +1 -1
  85. package/dist/chunk-LFS6UWSJ.cjs +602 -0
  86. package/dist/chunk-LFS6UWSJ.cjs.map +1 -0
  87. package/dist/{chunk-YQFEN7UJ.js → chunk-LNH6NYG4.js} +6 -90
  88. package/dist/chunk-LNH6NYG4.js.map +1 -0
  89. package/dist/chunk-LRPGXNMA.js +44 -0
  90. package/dist/chunk-LRPGXNMA.js.map +1 -0
  91. package/dist/chunk-NEGFHF3V.cjs +617 -0
  92. package/dist/chunk-NEGFHF3V.cjs.map +1 -0
  93. package/dist/{chunk-NHPBONMR.js → chunk-O4FBMC6S.js} +186 -71
  94. package/dist/chunk-O4FBMC6S.js.map +1 -0
  95. package/dist/{chunk-7P24MJQN.js → chunk-PBIFISDD.js} +3 -3
  96. package/dist/{chunk-7P24MJQN.js.map → chunk-PBIFISDD.js.map} +1 -1
  97. package/dist/{chunk-OWUNCJFO.cjs → chunk-PZOX4JF6.cjs} +30 -30
  98. package/dist/{chunk-OWUNCJFO.cjs.map → chunk-PZOX4JF6.cjs.map} +1 -1
  99. package/dist/{chunk-CKNUL4LM.cjs → chunk-QK546T4C.cjs} +3 -3
  100. package/dist/{chunk-CKNUL4LM.cjs.map → chunk-QK546T4C.cjs.map} +1 -1
  101. package/dist/{chunk-QAXIVZEJ.cjs → chunk-ROWJU4SK.cjs} +13 -513
  102. package/dist/chunk-ROWJU4SK.cjs.map +1 -0
  103. package/dist/{chunk-JWRTUYLC.js → chunk-SBAM3UZX.js} +3 -3
  104. package/dist/{chunk-JWRTUYLC.js.map → chunk-SBAM3UZX.js.map} +1 -1
  105. package/dist/{chunk-COZDIUG7.cjs → chunk-TJ7QEGVP.cjs} +18 -18
  106. package/dist/{chunk-COZDIUG7.cjs.map → chunk-TJ7QEGVP.cjs.map} +1 -1
  107. package/dist/{chunk-PVPGD6QR.js → chunk-VWM3J6ES.js} +3 -3
  108. package/dist/{chunk-PVPGD6QR.js.map → chunk-VWM3J6ES.js.map} +1 -1
  109. package/dist/{chunk-UDMII47W.cjs → chunk-WBLCPCWR.cjs} +7 -7
  110. package/dist/{chunk-UDMII47W.cjs.map → chunk-WBLCPCWR.cjs.map} +1 -1
  111. package/dist/{chunk-3T3IKNGF.cjs → chunk-ZXW6WFZG.cjs} +5 -41
  112. package/dist/chunk-ZXW6WFZG.cjs.map +1 -0
  113. package/dist/{chunk-ODQK3LX5.cjs → chunk-ZZHMJXM5.cjs} +4 -93
  114. package/dist/chunk-ZZHMJXM5.cjs.map +1 -0
  115. package/dist/connect/docx.cjs +11 -11
  116. package/dist/connect/docx.js +7 -7
  117. package/dist/connect/index.cjs +496 -493
  118. package/dist/connect/index.cjs.map +1 -1
  119. package/dist/connect/index.js +36 -33
  120. package/dist/connect/index.js.map +1 -1
  121. package/dist/connect/viewer.cjs +9 -8
  122. package/dist/connect/viewer.js +8 -7
  123. package/dist/dashboards/index.cjs +1 -1
  124. package/dist/dashboards/index.js +1 -1
  125. package/dist/document-tools/index.cjs +17 -17
  126. package/dist/document-tools/index.js +2 -2
  127. package/dist/embed/index.cjs +11 -10
  128. package/dist/embed/index.js +8 -7
  129. package/dist/facts/index.cjs +1 -1
  130. package/dist/facts/index.js +1 -1
  131. package/dist/files/index.cjs +1 -1
  132. package/dist/files/index.js +1 -1
  133. package/dist/index.cjs +653 -618
  134. package/dist/index.cjs.map +1 -1
  135. package/dist/index.d.ts +4 -0
  136. package/dist/index.js +19 -16
  137. package/dist/index.js.map +1 -1
  138. package/dist/shell/index.cjs +78 -77
  139. package/dist/shell/index.js +3 -2
  140. package/dist/site/index.cjs +105 -81
  141. package/dist/site/index.d.ts +3 -1
  142. package/dist/site/index.js +4 -4
  143. package/dist/studio/index.cjs +60 -55
  144. package/dist/studio/index.cjs.map +1 -1
  145. package/dist/studio/index.js +12 -7
  146. package/dist/studio/index.js.map +1 -1
  147. package/dist/theme/ThemeControls.d.ts +71 -0
  148. package/dist/theme/ThemeEditor.d.ts +5 -2
  149. package/dist/theme/ThemePreview.d.ts +20 -0
  150. package/dist/theme/color.d.ts +17 -1
  151. package/dist/theme/derive.d.ts +75 -0
  152. package/dist/theme/editorModel.d.ts +36 -0
  153. package/dist/theme/previewLabels.d.ts +38 -0
  154. package/dist/theme/store.d.ts +51 -13
  155. package/dist/theme/tokens.d.ts +2 -0
  156. package/dist/workflow-canvas/index.cjs +37 -36
  157. package/dist/workflow-canvas/index.cjs.map +1 -1
  158. package/dist/workflow-canvas/index.js +13 -12
  159. package/dist/workflow-canvas/index.js.map +1 -1
  160. package/node_modules/@arbidocs/coedit/package.json +1 -1
  161. package/package.json +5 -5
  162. package/dist/ConnectedStreamedWordArtifact-5MHLV24V.js.map +0 -1
  163. package/dist/ConnectedStreamedWordArtifact-LNGW7YGV.cjs.map +0 -1
  164. package/dist/chunk-3T3IKNGF.cjs.map +0 -1
  165. package/dist/chunk-77IAOKZO.js.map +0 -1
  166. package/dist/chunk-HVOPUYAG.cjs.map +0 -1
  167. package/dist/chunk-IFLFLP4K.js.map +0 -1
  168. package/dist/chunk-N5WJBQYF.cjs +0 -476
  169. package/dist/chunk-N5WJBQYF.cjs.map +0 -1
  170. package/dist/chunk-NHPBONMR.js.map +0 -1
  171. package/dist/chunk-ODQK3LX5.cjs.map +0 -1
  172. package/dist/chunk-OLDGMBEF.cjs.map +0 -1
  173. package/dist/chunk-QAXIVZEJ.cjs.map +0 -1
  174. package/dist/chunk-QCLYRNOC.js +0 -466
  175. package/dist/chunk-QCLYRNOC.js.map +0 -1
  176. package/dist/chunk-TFWCREOL.js.map +0 -1
  177. package/dist/chunk-YQFEN7UJ.js.map +0 -1
@@ -1,476 +0,0 @@
1
- "use client";
2
- 'use strict';
3
-
4
- var chunkNWNVWO6L_cjs = require('./chunk-NWNVWO6L.cjs');
5
- var react = require('react');
6
- var lucideReact = require('lucide-react');
7
- var ui = require('@arbidocs/react/ui');
8
- var jsxRuntime = require('react/jsx-runtime');
9
-
10
- // src/theme/color.ts
11
- var NUM = String.raw`-?\d*\.?\d+(?:e-?\d+)?`;
12
- var TRIPLET_RE = new RegExp(String.raw`^(${NUM})(?:deg)?\s+(${NUM})%\s+(${NUM})%$`);
13
- var HSL_FN_RE = new RegExp(
14
- String.raw`^hsla?\(\s*(${NUM})(?:deg)?[\s,]+(${NUM})%[\s,]+(${NUM})%\s*(?:[,/]\s*${NUM}%?\s*)?\)$`,
15
- "i"
16
- );
17
- var RGB_FN_RE = new RegExp(
18
- String.raw`^rgba?\(\s*(${NUM})[\s,]+(${NUM})[\s,]+(${NUM})\s*(?:[,/]\s*${NUM}%?\s*)?\)$`,
19
- "i"
20
- );
21
- var clamp = (n, lo, hi) => Math.min(hi, Math.max(lo, n));
22
- var fmt = (n) => String(Math.round(n * 10) / 10);
23
- function rgbToHsl({ r, g, b }) {
24
- const rn = r / 255;
25
- const gn = g / 255;
26
- const bn = b / 255;
27
- const max = Math.max(rn, gn, bn);
28
- const min = Math.min(rn, gn, bn);
29
- const l = (max + min) / 2;
30
- const d = max - min;
31
- let h = 0;
32
- let s = 0;
33
- if (d !== 0) {
34
- s = d / (1 - Math.abs(2 * l - 1));
35
- if (max === rn) h = 60 * ((gn - bn) / d % 6);
36
- else if (max === gn) h = 60 * ((bn - rn) / d + 2);
37
- else h = 60 * ((rn - gn) / d + 4);
38
- }
39
- if (h < 0) h += 360;
40
- return { h, s: s * 100, l: l * 100 };
41
- }
42
- function hslToRgb({ h, s, l }) {
43
- const sn = clamp(s, 0, 100) / 100;
44
- const ln = clamp(l, 0, 100) / 100;
45
- const hn = (h % 360 + 360) % 360;
46
- const c = (1 - Math.abs(2 * ln - 1)) * sn;
47
- const x = c * (1 - Math.abs(hn / 60 % 2 - 1));
48
- const m = ln - c / 2;
49
- const [r1, g1, b1] = hn < 60 ? [c, x, 0] : hn < 120 ? [x, c, 0] : hn < 180 ? [0, c, x] : hn < 240 ? [0, x, c] : hn < 300 ? [x, 0, c] : [c, 0, x];
50
- return { r: (r1 + m) * 255, g: (g1 + m) * 255, b: (b1 + m) * 255 };
51
- }
52
- function parseHex(value) {
53
- let hex = value.slice(1);
54
- if (hex.length === 3 || hex.length === 4) {
55
- hex = hex.slice(0, 3).split("").map((ch) => ch + ch).join("");
56
- } else if (hex.length === 8) {
57
- hex = hex.slice(0, 6);
58
- }
59
- if (!/^[0-9a-fA-F]{6}$/.test(hex)) return null;
60
- return {
61
- r: parseInt(hex.slice(0, 2), 16),
62
- g: parseInt(hex.slice(2, 4), 16),
63
- b: parseInt(hex.slice(4, 6), 16)
64
- };
65
- }
66
- function parseColor(value) {
67
- const c = value.trim();
68
- if (c.startsWith("#")) return parseHex(c);
69
- const rgb = RGB_FN_RE.exec(c);
70
- if (rgb) return { r: Number(rgb[1]), g: Number(rgb[2]), b: Number(rgb[3]) };
71
- const hsl = HSL_FN_RE.exec(c) ?? TRIPLET_RE.exec(c);
72
- if (hsl) return hslToRgb({ h: Number(hsl[1]), s: Number(hsl[2]), l: Number(hsl[3]) });
73
- return null;
74
- }
75
- function parseHsl(value) {
76
- const c = value.trim();
77
- const m = TRIPLET_RE.exec(c) ?? HSL_FN_RE.exec(c);
78
- if (m) return { h: Number(m[1]), s: Number(m[2]), l: Number(m[3]) };
79
- const rgb = parseColor(c);
80
- return rgb ? rgbToHsl(rgb) : null;
81
- }
82
- function formatHslTriplet({ h, s, l }) {
83
- return `${fmt((h % 360 + 360) % 360)} ${fmt(s)}% ${fmt(l)}%`;
84
- }
85
- function toHslTriplet(color) {
86
- const c = color.trim();
87
- if (TRIPLET_RE.test(c)) return c;
88
- const hsl = parseHsl(c);
89
- return hsl ? formatHslTriplet(hsl) : c;
90
- }
91
- function toCssColor(value) {
92
- const c = value.trim();
93
- return TRIPLET_RE.test(c) ? `hsl(${c})` : c;
94
- }
95
-
96
- // src/theme/tokens.ts
97
- var THEME_STYLE_ID = "arbi-theme-vars";
98
- function themeCssVars(colors) {
99
- const vars = {};
100
- for (const [key, value] of Object.entries(colors)) {
101
- vars[`--${key}`] = toHslTriplet(value);
102
- vars[`--color-${key}`] = toCssColor(value);
103
- }
104
- return vars;
105
- }
106
- function themeMetaVars(theme) {
107
- return {
108
- "--font-display": theme.fonts.display,
109
- "--font-sans": theme.fonts.sans,
110
- "--radius": `${theme.radius}rem`
111
- };
112
- }
113
- function renderBlock(selector, vars) {
114
- const body = Object.entries(vars).map(([name, value]) => ` ${name}: ${value};`).join("\n");
115
- return `${selector} {
116
- ${body}
117
- }`;
118
- }
119
- function emitCssVars(theme, dark) {
120
- if (typeof document === "undefined") return;
121
- let css = renderBlock(":root", { ...themeCssVars(theme.colors), ...themeMetaVars(theme) });
122
- if (dark) css += `
123
- ${renderBlock(":root.dark", themeCssVars(dark))}`;
124
- let style = document.getElementById(THEME_STYLE_ID);
125
- if (!style) {
126
- style = document.createElement("style");
127
- style.id = THEME_STYLE_ID;
128
- document.head.appendChild(style);
129
- }
130
- style.textContent = css;
131
- }
132
- function removeCssVars() {
133
- if (typeof document === "undefined") return;
134
- document.getElementById(THEME_STYLE_ID)?.remove();
135
- }
136
- function normalizeOptions(optionsOrRoot) {
137
- if (typeof HTMLElement !== "undefined" && optionsOrRoot instanceof HTMLElement) {
138
- return { root: optionsOrRoot };
139
- }
140
- return optionsOrRoot;
141
- }
142
- function applyThemeVars(theme, optionsOrRoot = {}) {
143
- const { mode = "flat", dark, root = document.documentElement } = normalizeOptions(optionsOrRoot);
144
- if (mode === "cssVars") {
145
- emitCssVars(theme, dark);
146
- return;
147
- }
148
- for (const [name, value] of Object.entries({
149
- ...themeCssVars(theme.colors),
150
- ...themeMetaVars(theme)
151
- })) {
152
- root.style.setProperty(name, value);
153
- }
154
- }
155
- function applyFontVars(fonts, root = document.documentElement) {
156
- root.style.setProperty("--font-display", fonts.display);
157
- root.style.setProperty("--font-sans", fonts.sans);
158
- }
159
- function clearFontVars(root = document.documentElement) {
160
- root.style.removeProperty("--font-display");
161
- root.style.removeProperty("--font-sans");
162
- }
163
- function clearThemeVars(theme, optionsOrRoot = {}) {
164
- const { mode = "flat", root = document.documentElement } = normalizeOptions(optionsOrRoot);
165
- if (mode === "cssVars") {
166
- removeCssVars();
167
- return;
168
- }
169
- for (const key of Object.keys(theme.colors)) {
170
- root.style.removeProperty(`--${key}`);
171
- root.style.removeProperty(`--color-${key}`);
172
- }
173
- root.style.removeProperty("--font-display");
174
- root.style.removeProperty("--font-sans");
175
- root.style.removeProperty("--radius");
176
- }
177
- function ThemeEditor({
178
- bundle,
179
- variant = "panel",
180
- preview,
181
- onSave,
182
- testIdPrefix = "theme",
183
- defaultOpen = false
184
- }) {
185
- const { useStore, tokens, presets, groupLabels, mode, darkColors } = bundle;
186
- const colors = useStore((s) => s.colors);
187
- const fonts = useStore((s) => s.fonts);
188
- const radius = useStore((s) => s.radius);
189
- const activePresetId = useStore((s) => s.activePresetId);
190
- const setColor = useStore((s) => s.setColor);
191
- const setFont = useStore((s) => s.setFont);
192
- const setFontPairing = useStore((s) => s.setFontPairing);
193
- const setRadius = useStore((s) => s.setRadius);
194
- const applyPreset = useStore((s) => s.applyPreset);
195
- const reset = useStore((s) => s.reset);
196
- const [open, setOpen] = react.useState(defaultOpen);
197
- const [saving, setSaving] = react.useState(false);
198
- const [savedVia, setSavedVia] = react.useState(null);
199
- react.useEffect(() => {
200
- applyThemeVars({ colors, fonts, radius }, { mode, dark: darkColors });
201
- }, [colors, fonts, radius, mode, darkColors]);
202
- const tid = (suffix) => `${testIdPrefix}-${suffix}`;
203
- const groups = [...new Set(tokens.map((t) => t.group))];
204
- const save = async () => {
205
- if (!onSave) return;
206
- setSaving(true);
207
- try {
208
- const via = await onSave();
209
- setSavedVia(typeof via === "string" ? via : "saved");
210
- } catch {
211
- setSavedVia(null);
212
- } finally {
213
- setSaving(false);
214
- }
215
- };
216
- const Presets = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
217
- presets.map((p) => /* @__PURE__ */ jsxRuntime.jsx(
218
- "button",
219
- {
220
- type: "button",
221
- onClick: () => applyPreset(p.id),
222
- className: `rounded-full border px-3 py-1 text-xs font-medium transition-colors ${activePresetId === p.id ? "border-primary bg-primary text-primary-foreground" : "border-border text-foreground hover:border-primary"}`,
223
- "data-testid": tid(`preset-${p.id}`),
224
- children: p.label
225
- },
226
- p.id
227
- )),
228
- /* @__PURE__ */ jsxRuntime.jsxs(
229
- "button",
230
- {
231
- type: "button",
232
- onClick: reset,
233
- className: "ml-auto inline-flex items-center gap-1.5 text-xs font-medium text-muted-foreground hover:text-foreground",
234
- "data-testid": tid("reset"),
235
- children: [
236
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { className: "size-3" }),
237
- " Reset"
238
- ]
239
- }
240
- )
241
- ] });
242
- const colorRow = (k, label) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
243
- /* @__PURE__ */ jsxRuntime.jsx(
244
- "input",
245
- {
246
- type: "color",
247
- value: colors[k] ?? "#000000",
248
- onChange: (e) => setColor(k, e.target.value),
249
- className: "size-9 shrink-0 cursor-pointer rounded-md border border-border bg-transparent",
250
- "aria-label": label,
251
- "data-testid": tid(`color-${k}`)
252
- }
253
- ),
254
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
255
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs text-muted-foreground", children: label }),
256
- /* @__PURE__ */ jsxRuntime.jsx(
257
- ui.Input,
258
- {
259
- value: colors[k] ?? "",
260
- onChange: (e) => setColor(k, e.target.value),
261
- "aria-label": `${label} hex value`,
262
- className: "bg-card placeholder:text-muted-foreground focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring h-7 font-mono text-xs",
263
- "data-testid": tid(`hex-${k}`)
264
- }
265
- )
266
- ] })
267
- ] }, k);
268
- const activePairing = chunkNWNVWO6L_cjs.matchFontPairing(fonts);
269
- const Typography = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
270
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
271
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs text-muted-foreground", children: "Typeface" }),
272
- /* @__PURE__ */ jsxRuntime.jsxs(
273
- "select",
274
- {
275
- value: activePairing?.id ?? "",
276
- onChange: (e) => setFontPairing(e.target.value),
277
- "aria-label": "Typeface",
278
- className: "mt-1 h-8 w-full rounded-md border border-border bg-card px-2 text-xs text-foreground focus-visible:border-ring/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
279
- "data-testid": tid("font-pairing"),
280
- children: [
281
- !activePairing && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Custom" }),
282
- chunkNWNVWO6L_cjs.FONT_PAIRINGS.map((pairing) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: pairing.id, children: pairing.label }, pairing.id))
283
- ]
284
- }
285
- ),
286
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: activePairing?.description ?? "Hand-edited font stacks." })
287
- ] }),
288
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
289
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs text-muted-foreground", children: "Display font stack" }),
290
- /* @__PURE__ */ jsxRuntime.jsx(
291
- ui.Input,
292
- {
293
- value: fonts.display,
294
- onChange: (e) => setFont("display", e.target.value),
295
- "aria-label": "Display font stack",
296
- className: "bg-card placeholder:text-muted-foreground focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring mt-1 font-mono text-xs",
297
- "data-testid": tid("font-display")
298
- }
299
- )
300
- ] }),
301
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
302
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs text-muted-foreground", children: "Body font stack" }),
303
- /* @__PURE__ */ jsxRuntime.jsx(
304
- ui.Input,
305
- {
306
- value: fonts.sans,
307
- onChange: (e) => setFont("sans", e.target.value),
308
- "aria-label": "Body font stack",
309
- className: "bg-card placeholder:text-muted-foreground focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring mt-1 font-mono text-xs",
310
- "data-testid": tid("font-sans")
311
- }
312
- )
313
- ] }),
314
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
315
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "block text-xs text-muted-foreground", children: [
316
- "Base radius \u2014 ",
317
- radius,
318
- "rem"
319
- ] }),
320
- /* @__PURE__ */ jsxRuntime.jsx(
321
- "input",
322
- {
323
- type: "range",
324
- min: 0,
325
- max: 1.5,
326
- step: 0.125,
327
- value: radius,
328
- onChange: (e) => setRadius(Number(e.target.value)),
329
- "aria-label": "Base radius",
330
- className: "mt-2 w-full accent-[color:var(--color-primary)]",
331
- "data-testid": tid("radius")
332
- }
333
- )
334
- ] })
335
- ] });
336
- const Preview = /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { variant: "elevated", className: "rounded-lg", "data-testid": tid("preview"), children: [
337
- /* @__PURE__ */ jsxRuntime.jsx(ui.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.CardTitle, { className: "text-base", children: "Live preview" }) }),
338
- /* @__PURE__ */ jsxRuntime.jsxs(ui.CardContent, { className: "space-y-3", children: [
339
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-[var(--radius)] bg-primary p-4 text-primary-foreground", children: [
340
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-display text-lg font-semibold", children: preview?.title ?? "Preview" }),
341
- preview?.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs opacity-80", children: preview.subtitle })
342
- ] }),
343
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-6 gap-1.5", children: tokens.map((t) => /* @__PURE__ */ jsxRuntime.jsx(
344
- "div",
345
- {
346
- title: t.label,
347
- className: "aspect-square rounded-md border border-border",
348
- style: { background: `var(--color-${t.key})` }
349
- },
350
- t.key
351
- )) }),
352
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-[var(--radius)] border border-border bg-[color:var(--color-ai-accent-soft,var(--color-accent))] p-3", children: [
353
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium text-[color:var(--color-ai-accent,var(--color-primary))]", children: "AI action surface" }),
354
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Themed by the AI-kit accent tokens." })
355
- ] })
356
- ] })
357
- ] });
358
- const SaveBar = onSave && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6 flex items-center gap-3", children: [
359
- /* @__PURE__ */ jsxRuntime.jsxs(
360
- "button",
361
- {
362
- type: "button",
363
- onClick: () => void save(),
364
- disabled: saving,
365
- className: "inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground hover:opacity-90 disabled:opacity-60",
366
- "data-testid": tid("save"),
367
- children: [
368
- savedVia ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Save, { className: "size-4" }),
369
- saving ? "Saving\u2026" : savedVia ? "Saved" : "Save theme"
370
- ]
371
- }
372
- ),
373
- savedVia && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground", "data-testid": tid("via"), children: [
374
- "stored via ",
375
- savedVia
376
- ] })
377
- ] });
378
- if (variant === "collapsed") {
379
- const controlsId = `${testIdPrefix}-controls`;
380
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", "data-testid": testIdPrefix, children: [
381
- Presets,
382
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-8 gap-1.5 @xl:grid-cols-12", "aria-hidden": "true", children: tokens.slice(0, 12).map((t) => /* @__PURE__ */ jsxRuntime.jsx(
383
- "div",
384
- {
385
- title: t.label,
386
- className: "aspect-square rounded-md border border-border",
387
- style: { background: `var(--color-${t.key})` }
388
- },
389
- t.key
390
- )) }),
391
- /* @__PURE__ */ jsxRuntime.jsxs(
392
- "button",
393
- {
394
- type: "button",
395
- onClick: () => setOpen((o) => !o),
396
- "aria-expanded": open,
397
- "aria-controls": controlsId,
398
- className: "inline-flex items-center gap-1.5 text-sm font-medium text-foreground hover:text-primary",
399
- "data-testid": tid("customize"),
400
- children: [
401
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: `size-4 transition-transform ${open ? "rotate-180" : ""}` }),
402
- "Customize colours and type"
403
- ]
404
- }
405
- ),
406
- open && /* @__PURE__ */ jsxRuntime.jsxs(
407
- "div",
408
- {
409
- id: controlsId,
410
- className: "max-h-[28rem] overflow-y-auto rounded-md border border-border bg-card p-4",
411
- "data-testid": tid("controls"),
412
- children: [
413
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "Colours" }),
414
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-3 @xl:grid-cols-2", children: tokens.map((t) => colorRow(t.key, t.label)) }),
415
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-6 mb-2 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "Typography & shape" }),
416
- Typography
417
- ]
418
- }
419
- ),
420
- SaveBar
421
- ] });
422
- }
423
- if (variant === "drawer") {
424
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col overflow-y-auto bg-card p-5", "data-testid": testIdPrefix, children: [
425
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4 flex items-center justify-between", children: /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "font-display text-lg font-semibold text-foreground", children: "Theme" }) }),
426
- Presets,
427
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-5 mb-2 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "Colours" }),
428
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: tokens.map((t) => colorRow(t.key, t.label)) }),
429
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-6 mb-2 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground", children: "Typography & shape" }),
430
- Typography,
431
- SaveBar
432
- ] });
433
- }
434
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-6 lg:grid-cols-[1fr_320px]", "data-testid": testIdPrefix, children: [
435
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6", children: [
436
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { variant: "elevated", className: "rounded-lg", children: [
437
- /* @__PURE__ */ jsxRuntime.jsx(ui.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.CardTitle, { className: "flex items-center gap-2 text-base", children: [
438
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Palette, { className: "size-4 text-[color:var(--color-primary)]" }),
439
- " Presets"
440
- ] }) }),
441
- /* @__PURE__ */ jsxRuntime.jsx(ui.CardContent, { children: Presets })
442
- ] }),
443
- groups.map((group) => /* @__PURE__ */ jsxRuntime.jsxs(
444
- ui.Card,
445
- {
446
- variant: "elevated",
447
- className: "rounded-lg",
448
- "data-testid": tid(`group-${group}`),
449
- children: [
450
- /* @__PURE__ */ jsxRuntime.jsx(ui.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.CardTitle, { className: "text-base", children: groupLabels[group] ?? group }) }),
451
- /* @__PURE__ */ jsxRuntime.jsx(ui.CardContent, { className: "grid gap-3 @xl:grid-cols-2", children: tokens.filter((t) => t.group === group).map((t) => colorRow(t.key, t.label)) })
452
- ]
453
- },
454
- group
455
- )),
456
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Card, { variant: "elevated", className: "rounded-lg", children: [
457
- /* @__PURE__ */ jsxRuntime.jsx(ui.CardHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.CardTitle, { className: "text-base", children: "Typography & shape" }) }),
458
- /* @__PURE__ */ jsxRuntime.jsx(ui.CardContent, { children: Typography })
459
- ] }),
460
- SaveBar
461
- ] }),
462
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "lg:sticky lg:top-4 lg:self-start", children: Preview })
463
- ] });
464
- }
465
-
466
- exports.THEME_STYLE_ID = THEME_STYLE_ID;
467
- exports.ThemeEditor = ThemeEditor;
468
- exports.applyFontVars = applyFontVars;
469
- exports.applyThemeVars = applyThemeVars;
470
- exports.clearFontVars = clearFontVars;
471
- exports.clearThemeVars = clearThemeVars;
472
- exports.themeCssVars = themeCssVars;
473
- exports.themeMetaVars = themeMetaVars;
474
- exports.toHslTriplet = toHslTriplet;
475
- //# sourceMappingURL=chunk-N5WJBQYF.cjs.map
476
- //# sourceMappingURL=chunk-N5WJBQYF.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/theme/color.ts","../src/theme/tokens.ts","../src/theme/ThemeEditor.tsx"],"names":["useState","useEffect","jsxs","jsx","RotateCcw","Input","matchFontPairing","FONT_PAIRINGS","Card","CardHeader","CardTitle","CardContent","Check","Save","ChevronDown","Palette"],"mappings":"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","file":"chunk-N5WJBQYF.cjs","sourcesContent":["/**\n * Colour math for the theme store: parse the formats a theme value comes in (hex, `rgb()`,\n * `hsl()`, a raw `H S% L%` triplet) and convert between them.\n *\n * Pure functions, no DOM. A theme value is kept in whatever format the host wrote it (Clarum's\n * `@theme` is hex, the ARBI app's stylesheet is triplets); these helpers turn it into the two\n * formats the document needs: the raw triplet the blocks contract reads (`hsl(var(--primary))`)\n * and a full colour for Tailwind's `--color-*` map.\n */\n\nexport interface Rgb {\n /** 0..255 */\n r: number\n g: number\n b: number\n}\n\nexport interface Hsl {\n /** Hue in degrees, 0..360. */\n h: number\n /** Saturation, 0..100. */\n s: number\n /** Lightness, 0..100. */\n l: number\n}\n\nconst NUM = String.raw`-?\\d*\\.?\\d+(?:e-?\\d+)?`\nconst TRIPLET_RE = new RegExp(String.raw`^(${NUM})(?:deg)?\\s+(${NUM})%\\s+(${NUM})%$`)\nconst HSL_FN_RE = new RegExp(\n String.raw`^hsla?\\(\\s*(${NUM})(?:deg)?[\\s,]+(${NUM})%[\\s,]+(${NUM})%\\s*(?:[,/]\\s*${NUM}%?\\s*)?\\)$`,\n 'i'\n)\nconst RGB_FN_RE = new RegExp(\n String.raw`^rgba?\\(\\s*(${NUM})[\\s,]+(${NUM})[\\s,]+(${NUM})\\s*(?:[,/]\\s*${NUM}%?\\s*)?\\)$`,\n 'i'\n)\n\n/** True for a raw `H S% L%` triplet (the blocks contract's format, no `hsl()`). */\nexport function isHslTriplet(value: string): boolean {\n return TRIPLET_RE.test(value.trim())\n}\n\nconst clamp = (n: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, n))\n\n/** Round to one decimal and drop a trailing `.0`, so `50.0` prints as `50`. */\nconst fmt = (n: number) => String(Math.round(n * 10) / 10)\n\nexport function rgbToHsl({ r, g, b }: Rgb): Hsl {\n const rn = r / 255\n const gn = g / 255\n const bn = b / 255\n const max = Math.max(rn, gn, bn)\n const min = Math.min(rn, gn, bn)\n const l = (max + min) / 2\n const d = max - min\n let h = 0\n let s = 0\n if (d !== 0) {\n s = d / (1 - Math.abs(2 * l - 1))\n if (max === rn) h = 60 * (((gn - bn) / d) % 6)\n else if (max === gn) h = 60 * ((bn - rn) / d + 2)\n else h = 60 * ((rn - gn) / d + 4)\n }\n if (h < 0) h += 360\n return { h, s: s * 100, l: l * 100 }\n}\n\nexport function hslToRgb({ h, s, l }: Hsl): Rgb {\n const sn = clamp(s, 0, 100) / 100\n const ln = clamp(l, 0, 100) / 100\n const hn = ((h % 360) + 360) % 360\n const c = (1 - Math.abs(2 * ln - 1)) * sn\n const x = c * (1 - Math.abs(((hn / 60) % 2) - 1))\n const m = ln - c / 2\n const [r1, g1, b1] =\n hn < 60\n ? [c, x, 0]\n : hn < 120\n ? [x, c, 0]\n : hn < 180\n ? [0, c, x]\n : hn < 240\n ? [0, x, c]\n : hn < 300\n ? [x, 0, c]\n : [c, 0, x]\n return { r: (r1 + m) * 255, g: (g1 + m) * 255, b: (b1 + m) * 255 }\n}\n\nfunction parseHex(value: string): Rgb | null {\n let hex = value.slice(1)\n if (hex.length === 3 || hex.length === 4) {\n hex = hex\n .slice(0, 3)\n .split('')\n .map((ch) => ch + ch)\n .join('')\n } else if (hex.length === 8) {\n hex = hex.slice(0, 6)\n }\n if (!/^[0-9a-fA-F]{6}$/.test(hex)) return null\n return {\n r: parseInt(hex.slice(0, 2), 16),\n g: parseInt(hex.slice(2, 4), 16),\n b: parseInt(hex.slice(4, 6), 16),\n }\n}\n\n/**\n * Parse a theme colour value to RGB: `#rgb`, `#rrggbb` (alpha ignored), `rgb()`/`rgba()`,\n * `hsl()`/`hsla()` and a raw triplet. Anything else (`oklch()`, a `var()`) is `null`.\n */\nexport function parseColor(value: string): Rgb | null {\n const c = value.trim()\n if (c.startsWith('#')) return parseHex(c)\n const rgb = RGB_FN_RE.exec(c)\n if (rgb) return { r: Number(rgb[1]), g: Number(rgb[2]), b: Number(rgb[3]) }\n const hsl = HSL_FN_RE.exec(c) ?? TRIPLET_RE.exec(c)\n if (hsl) return hslToRgb({ h: Number(hsl[1]), s: Number(hsl[2]), l: Number(hsl[3]) })\n return null\n}\n\n/** HSL of a colour value, or `null` when it cannot be parsed. A triplet keeps its exact numbers. */\nexport function parseHsl(value: string): Hsl | null {\n const c = value.trim()\n const m = TRIPLET_RE.exec(c) ?? HSL_FN_RE.exec(c)\n if (m) return { h: Number(m[1]), s: Number(m[2]), l: Number(m[3]) }\n const rgb = parseColor(c)\n return rgb ? rgbToHsl(rgb) : null\n}\n\nconst hex2 = (n: number) =>\n Math.round(clamp(n, 0, 255))\n .toString(16)\n .padStart(2, '0')\n\nexport function rgbToHex({ r, g, b }: Rgb): string {\n return `#${hex2(r)}${hex2(g)}${hex2(b)}`\n}\n\nexport function hslToHex(hsl: Hsl): string {\n return rgbToHex(hslToRgb(hsl))\n}\n\n/** `#rrggbb` of any parseable value (what `<input type=\"color\">` needs); `fallback` otherwise. */\nexport function toHex(value: string, fallback = '#000000'): string {\n const rgb = parseColor(value)\n return rgb ? rgbToHex(rgb) : fallback\n}\n\n/** `H S% L%` of an HSL value, one decimal. */\nexport function formatHslTriplet({ h, s, l }: Hsl): string {\n return `${fmt(((h % 360) + 360) % 360)} ${fmt(s)}% ${fmt(l)}%`\n}\n\n/**\n * Convert a colour to the blocks contract's `H S% L%` triplet.\n *\n * An existing triplet passes through untouched (so a host that seeds its stylesheet's exact\n * triplets gets a byte-identical no-op). Hex, `rgb()` and `hsl()` convert with one decimal, the\n * precision of the stylesheets. Values it cannot parse (`oklch()`, `var()`) are returned unchanged.\n */\nexport function toHslTriplet(color: string): string {\n const c = color.trim()\n if (TRIPLET_RE.test(c)) return c\n const hsl = parseHsl(c)\n return hsl ? formatHslTriplet(hsl) : c\n}\n\n/**\n * The full colour for a Tailwind `--color-*` variable: a raw triplet is wrapped as `hsl(...)`, any\n * other value (hex, `rgb()`, `oklch()`) is already a colour and is kept as written.\n */\nexport function toCssColor(value: string): string {\n const c = value.trim()\n return TRIPLET_RE.test(c) ? `hsl(${c})` : c\n}\n","/**\n * The theme-token model. Firm-agnostic: the token *catalog*, default values and\n * presets are supplied by the consuming app (via {@link createThemeStore}); this\n * module owns the shared types and the logic for writing tokens onto the live\n * document.\n *\n * **One value, both outputs.** The blocks token contract is raw HSL triplets\n * (`--primary: 228 50% 25%`, read as `hsl(var(--primary))`), and Tailwind's\n * `--color-*` map is derived from them. A host may theme either half (Clarum's\n * `@theme` is hex `--color-*`; the ARBI app's stylesheet is triplets), so every\n * token is written to BOTH from the one value ({@link themeCssVars}): the triplet\n * and the full colour. Tailwind resolves a `--color-*` where it is declared, so a\n * theme that wrote only the triplets would leave `bg-primary` behind, and one\n * that wrote only `--color-*` would leave every part that reads a triplet\n * directly (step bar, charts, calendar, grid, canvas) on the package defaults.\n *\n * Where the variables are written is the emit model, {@link ThemeEmitMode}:\n *\n * - `'flat'` (default): inline custom properties on `<html>`, plus `--font-*` /\n * `--radius`. Inline styles override the stylesheet defaults, so an edit\n * previews live across the whole app and reverts cleanly. No dark variant.\n *\n * - `'cssVars'`: an injected `<style id=\"arbi-theme-vars\">` appended to `<head>`\n * with a `:root { light } / :root.dark { dark }` structure, so an app with a\n * real `.dark` variant keeps it. The injected sheet is *unlayered*, so it wins\n * over the app's own `@layer base` colours at equal specificity.\n */\nimport { toCssColor, toHslTriplet } from './color'\n\nexport { toHslTriplet }\n\nexport interface ColorToken {\n /** Key without a prefix, e.g. \"primary\" → `--primary` and `--color-primary`. */\n key: string\n label: string\n /** Grouping id for the panel layout (e.g. \"shadcn\" | \"brand\" | \"ai\"). */\n group: string\n}\n\nexport interface ThemeFonts {\n display: string\n sans: string\n}\n\nexport interface ThemeTokens {\n /** Colour values keyed by token key (hex, `rgb()`, `hsl()` or a raw triplet). */\n colors: Record<string, string>\n fonts: ThemeFonts\n /** Base radius in rem. */\n radius: number\n}\n\nexport interface ThemePreset {\n id: string\n label: string\n tokens: ThemeTokens\n}\n\n/** Where a theme is written on the document. See the module doc for the models. */\nexport type ThemeEmitMode = 'flat' | 'cssVars'\n\nexport interface ApplyThemeOptions {\n /** Emit model. Defaults to `'flat'`. */\n mode?: ThemeEmitMode\n /**\n * `cssVars` mode only: dark-variant colour values keyed by token key. Emitted\n * under `:root.dark`. When omitted, only `:root` is emitted — note that an\n * overridden light token then also applies in dark (the injected `:root` is\n * unlayered and beats the app's own `.dark` rules), so a host with a dark mode\n * MUST supply this for every editable token to keep dark mode intact.\n */\n dark?: Record<string, string>\n /** `flat` mode only: target element. Defaults to `document.documentElement`. */\n root?: HTMLElement\n}\n\n/** Id of the injected `<style>` that carries the `cssVars`-mode custom properties. */\nexport const THEME_STYLE_ID = 'arbi-theme-vars'\n\n/**\n * The custom properties one set of colour values paints: for every key, the raw triplet\n * (`--primary: 214 51.7% 11.4%`) and Tailwind's full colour (`--color-primary`: hex as written, or\n * `hsl(<triplet>)` for a triplet value), from the one value. A value the converter does not know\n * (`oklch()`, `var()`) is written unchanged to both, as the contract's full-colour tokens\n * (`--status-*`) expect.\n */\nexport function themeCssVars(colors: Record<string, string>): Record<string, string> {\n const vars: Record<string, string> = {}\n for (const [key, value] of Object.entries(colors)) {\n vars[`--${key}`] = toHslTriplet(value)\n vars[`--color-${key}`] = toCssColor(value)\n }\n return vars\n}\n\n/** The typography and shape variables of a theme. */\nexport function themeMetaVars(\n theme: Pick<ThemeTokens, 'fonts' | 'radius'>\n): Record<string, string> {\n return {\n '--font-display': theme.fonts.display,\n '--font-sans': theme.fonts.sans,\n '--radius': `${theme.radius}rem`,\n }\n}\n\nfunction renderBlock(selector: string, vars: Record<string, string>): string {\n const body = Object.entries(vars)\n .map(([name, value]) => ` ${name}: ${value};`)\n .join('\\n')\n return `${selector} {\\n${body}\\n}`\n}\n\nfunction emitCssVars(theme: ThemeTokens, dark?: Record<string, string>): void {\n if (typeof document === 'undefined') return\n let css = renderBlock(':root', { ...themeCssVars(theme.colors), ...themeMetaVars(theme) })\n if (dark) css += `\\n${renderBlock(':root.dark', themeCssVars(dark))}`\n let style = document.getElementById(THEME_STYLE_ID) as HTMLStyleElement | null\n if (!style) {\n style = document.createElement('style')\n style.id = THEME_STYLE_ID\n document.head.appendChild(style)\n }\n style.textContent = css\n}\n\nfunction removeCssVars(): void {\n if (typeof document === 'undefined') return\n document.getElementById(THEME_STYLE_ID)?.remove()\n}\n\nfunction normalizeOptions(optionsOrRoot: ApplyThemeOptions | HTMLElement): ApplyThemeOptions {\n if (typeof HTMLElement !== 'undefined' && optionsOrRoot instanceof HTMLElement) {\n return { root: optionsOrRoot }\n }\n return optionsOrRoot as ApplyThemeOptions\n}\n\n/**\n * Write a theme onto the live document: every colour as both its triplet and its `--color-*`\n * (see {@link themeCssVars}), plus `--font-*` / `--radius`.\n *\n * In `flat` mode (default) inline on `document.documentElement` (or a supplied root). In `cssVars`\n * mode into an injected `<style#arbi-theme-vars>` with a `:root.dark` block for `dark` (see the\n * module doc). The legacy `applyThemeVars(theme, rootElement)` call form still works.\n */\nexport function applyThemeVars(\n theme: ThemeTokens,\n optionsOrRoot: ApplyThemeOptions | HTMLElement = {}\n): void {\n const { mode = 'flat', dark, root = document.documentElement } = normalizeOptions(optionsOrRoot)\n\n if (mode === 'cssVars') {\n emitCssVars(theme, dark)\n return\n }\n\n for (const [name, value] of Object.entries({\n ...themeCssVars(theme.colors),\n ...themeMetaVars(theme),\n })) {\n root.style.setProperty(name, value)\n }\n}\n\n/**\n * Set ONLY the typography vars, as inline styles on the root element.\n *\n * Typography is often chosen independently of colour — an app may let a reader\n * pick a typeface while its palette is owned elsewhere. Writing the two vars\n * inline (rather than through `applyThemeVars`) keeps this orthogonal in two\n * ways: it touches no colour or radius token, and an inline style outranks any\n * selector, so a font choice survives a `cssVars`-mode theme that emits its own\n * `:root` block (the ARBI studio's theme editor does exactly that).\n */\nexport function applyFontVars(\n fonts: ThemeFonts,\n root: HTMLElement = document.documentElement\n): void {\n root.style.setProperty('--font-display', fonts.display)\n root.style.setProperty('--font-sans', fonts.sans)\n}\n\n/** Undo {@link applyFontVars}, reverting to the stylesheet's own font tokens. */\nexport function clearFontVars(root: HTMLElement = document.documentElement): void {\n root.style.removeProperty('--font-display')\n root.style.removeProperty('--font-sans')\n}\n\n/**\n * Remove a theme's overrides, reverting to the stylesheet defaults.\n *\n * In `flat` mode removes the inline overrides (both halves) for the theme's keys. In `cssVars`\n * mode removes the injected `<style#arbi-theme-vars>` in full (restoring the app's own colours\n * exactly).\n */\nexport function clearThemeVars(\n theme: ThemeTokens,\n optionsOrRoot: ApplyThemeOptions | HTMLElement = {}\n): void {\n const { mode = 'flat', root = document.documentElement } = normalizeOptions(optionsOrRoot)\n\n if (mode === 'cssVars') {\n removeCssVars()\n return\n }\n\n for (const key of Object.keys(theme.colors)) {\n root.style.removeProperty(`--${key}`)\n root.style.removeProperty(`--color-${key}`)\n }\n root.style.removeProperty('--font-display')\n root.style.removeProperty('--font-sans')\n root.style.removeProperty('--radius')\n}\n","/**\n * The one theme editor, shared by every surface. `variant=\"panel\"` is the roomy\n * back-office layout (grouped token cards + a live preview); `variant=\"drawer\"`\n * is the compact slide-over beside the studio canvas; `variant=\"collapsed\"` is\n * the settings-page form: presets and a swatch strip always visible, the colour\n * and typography controls behind a \"Customize\" disclosure in a bounded scroller\n * (the full editor is very tall). All drive the same\n * {@link ThemeBundle} store, so there is a single token model, preset list and\n * apply path. Firm-agnostic: chrome uses only universal surface tokens and the\n * preview renders the theme's own swatches, so it needs no brand-specific\n * component variants.\n */\nimport { useEffect, useState } from 'react'\nimport { RotateCcw, Palette, Save, Check, ChevronDown } from 'lucide-react'\nimport { Card, CardHeader, CardTitle, CardContent, Input } from '@arbidocs/react/ui'\nimport { applyThemeVars } from './tokens'\nimport { FONT_PAIRINGS, matchFontPairing } from './fontPairings'\nimport type { ThemeBundle } from './store'\n\nexport interface ThemeEditorProps {\n /** The host's theme store bundle (from createThemeStore). */\n bundle: ThemeBundle\n variant?: 'panel' | 'drawer' | 'collapsed'\n /** Firm identity shown in the panel's live-preview header. */\n preview?: { title: string; subtitle?: string }\n /** Optional persistence side-channel (e.g. save theme to ARBI); returns a \"via\" label. */\n onSave?: () => Promise<string | void>\n /** Stable testid namespace, e.g. \"builder-theme\" | \"studio-theme\". */\n testIdPrefix?: string\n /** `collapsed` only: start with the controls open. */\n defaultOpen?: boolean\n}\n\nexport function ThemeEditor({\n bundle,\n variant = 'panel',\n preview,\n onSave,\n testIdPrefix = 'theme',\n defaultOpen = false,\n}: ThemeEditorProps) {\n const { useStore, tokens, presets, groupLabels, mode, darkColors } = bundle\n const colors = useStore((s) => s.colors)\n const fonts = useStore((s) => s.fonts)\n const radius = useStore((s) => s.radius)\n const activePresetId = useStore((s) => s.activePresetId)\n const setColor = useStore((s) => s.setColor)\n const setFont = useStore((s) => s.setFont)\n const setFontPairing = useStore((s) => s.setFontPairing)\n const setRadius = useStore((s) => s.setRadius)\n const applyPreset = useStore((s) => s.applyPreset)\n const reset = useStore((s) => s.reset)\n\n const [open, setOpen] = useState(defaultOpen)\n const [saving, setSaving] = useState(false)\n const [savedVia, setSavedVia] = useState<string | null>(null)\n\n // Live preview: reflect every token change onto the running app, using the\n // host's emit mode (flat inline vars, or injected HSL-triplet cssVars).\n useEffect(() => {\n applyThemeVars({ colors, fonts, radius }, { mode, dark: darkColors })\n }, [colors, fonts, radius, mode, darkColors])\n\n const tid = (suffix: string) => `${testIdPrefix}-${suffix}`\n const groups = [...new Set(tokens.map((t) => t.group))]\n\n const save = async () => {\n if (!onSave) return\n setSaving(true)\n try {\n const via = await onSave()\n setSavedVia(typeof via === 'string' ? via : 'saved')\n } catch {\n // The host's onSave reports the failure (notify); never show a false \"saved\".\n setSavedVia(null)\n } finally {\n setSaving(false)\n }\n }\n\n // ── Presets row ────────────────────────────────────────────────────────────\n const Presets = (\n <div className=\"flex flex-wrap items-center gap-2\">\n {presets.map((p) => (\n <button\n key={p.id}\n type=\"button\"\n onClick={() => applyPreset(p.id)}\n className={`rounded-full border px-3 py-1 text-xs font-medium transition-colors ${\n activePresetId === p.id\n ? 'border-primary bg-primary text-primary-foreground'\n : 'border-border text-foreground hover:border-primary'\n }`}\n data-testid={tid(`preset-${p.id}`)}\n >\n {p.label}\n </button>\n ))}\n <button\n type=\"button\"\n onClick={reset}\n className=\"ml-auto inline-flex items-center gap-1.5 text-xs font-medium text-muted-foreground hover:text-foreground\"\n data-testid={tid('reset')}\n >\n <RotateCcw className=\"size-3\" /> Reset\n </button>\n </div>\n )\n\n // ── A single colour control ─────────────────────────────────────────────────\n // A plain function (not a component) so it inlines into the parent tree: this\n // avoids remounting the inputs on every keystroke (which would drop focus).\n const colorRow = (k: string, label: string) => (\n <div key={k} className=\"flex items-center gap-3\">\n <input\n type=\"color\"\n value={colors[k] ?? '#000000'}\n onChange={(e) => setColor(k, e.target.value)}\n className=\"size-9 shrink-0 cursor-pointer rounded-md border border-border bg-transparent\"\n aria-label={label}\n data-testid={tid(`color-${k}`)}\n />\n <div className=\"min-w-0 flex-1\">\n <span className=\"block text-xs text-muted-foreground\">{label}</span>\n <Input\n value={colors[k] ?? ''}\n onChange={(e) => setColor(k, e.target.value)}\n aria-label={`${label} hex value`}\n className=\"bg-card placeholder:text-muted-foreground focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring h-7 font-mono text-xs\"\n data-testid={tid(`hex-${k}`)}\n />\n </div>\n </div>\n )\n\n // ── Typography + radius ─────────────────────────────────────────────────────\n // The pairing picker is the primary control; the raw stacks below stay for\n // anyone who needs a face the catalog doesn't carry. Editing a stack by hand\n // drops the selection to \"Custom\" rather than silently mismatching.\n const activePairing = matchFontPairing(fonts)\n const Typography = (\n <div className=\"space-y-4\">\n <div>\n <span className=\"block text-xs text-muted-foreground\">Typeface</span>\n <select\n value={activePairing?.id ?? ''}\n onChange={(e) => setFontPairing(e.target.value)}\n aria-label=\"Typeface\"\n className=\"mt-1 h-8 w-full rounded-md border border-border bg-card px-2 text-xs text-foreground focus-visible:border-ring/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n data-testid={tid('font-pairing')}\n >\n {!activePairing && <option value=\"\">Custom</option>}\n {FONT_PAIRINGS.map((pairing) => (\n <option key={pairing.id} value={pairing.id}>\n {pairing.label}\n </option>\n ))}\n </select>\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {activePairing?.description ?? 'Hand-edited font stacks.'}\n </p>\n </div>\n <div>\n <span className=\"block text-xs text-muted-foreground\">Display font stack</span>\n <Input\n value={fonts.display}\n onChange={(e) => setFont('display', e.target.value)}\n aria-label=\"Display font stack\"\n className=\"bg-card placeholder:text-muted-foreground focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring mt-1 font-mono text-xs\"\n data-testid={tid('font-display')}\n />\n </div>\n <div>\n <span className=\"block text-xs text-muted-foreground\">Body font stack</span>\n <Input\n value={fonts.sans}\n onChange={(e) => setFont('sans', e.target.value)}\n aria-label=\"Body font stack\"\n className=\"bg-card placeholder:text-muted-foreground focus-visible:border-ring/60 focus-visible:ring-2 focus-visible:ring-ring mt-1 font-mono text-xs\"\n data-testid={tid('font-sans')}\n />\n </div>\n <div>\n <span className=\"block text-xs text-muted-foreground\">Base radius — {radius}rem</span>\n <input\n type=\"range\"\n min={0}\n max={1.5}\n step={0.125}\n value={radius}\n onChange={(e) => setRadius(Number(e.target.value))}\n aria-label=\"Base radius\"\n className=\"mt-2 w-full accent-[color:var(--color-primary)]\"\n data-testid={tid('radius')}\n />\n </div>\n </div>\n )\n\n // ── Live preview (panel only) — renders the theme's own swatches ────────────\n const Preview = (\n <Card variant=\"elevated\" className=\"rounded-lg\" data-testid={tid('preview')}>\n <CardHeader>\n <CardTitle className=\"text-base\">Live preview</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n <div className=\"rounded-[var(--radius)] bg-primary p-4 text-primary-foreground\">\n <p className=\"font-display text-lg font-semibold\">{preview?.title ?? 'Preview'}</p>\n {preview?.subtitle && <p className=\"text-xs opacity-80\">{preview.subtitle}</p>}\n </div>\n <div className=\"grid grid-cols-6 gap-1.5\">\n {tokens.map((t) => (\n <div\n key={t.key}\n title={t.label}\n className=\"aspect-square rounded-md border border-border\"\n style={{ background: `var(--color-${t.key})` }}\n />\n ))}\n </div>\n <div className=\"rounded-[var(--radius)] border border-border bg-[color:var(--color-ai-accent-soft,var(--color-accent))] p-3\">\n <p className=\"text-sm font-medium text-[color:var(--color-ai-accent,var(--color-primary))]\">\n AI action surface\n </p>\n <p className=\"text-xs text-muted-foreground\">Themed by the AI-kit accent tokens.</p>\n </div>\n </CardContent>\n </Card>\n )\n\n const SaveBar = onSave && (\n <div className=\"mt-6 flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={() => void save()}\n disabled={saving}\n className=\"inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground hover:opacity-90 disabled:opacity-60\"\n data-testid={tid('save')}\n >\n {savedVia ? <Check className=\"size-4\" /> : <Save className=\"size-4\" />}\n {saving ? 'Saving…' : savedVia ? 'Saved' : 'Save theme'}\n </button>\n {savedVia && (\n <span className=\"text-xs text-muted-foreground\" data-testid={tid('via')}>\n stored via {savedVia}\n </span>\n )}\n </div>\n )\n\n // ── Collapsed layout — settings pages ───────────────────────────────────────\n if (variant === 'collapsed') {\n const controlsId = `${testIdPrefix}-controls`\n return (\n <div className=\"space-y-3\" data-testid={testIdPrefix}>\n {Presets}\n <div className=\"grid grid-cols-8 gap-1.5 @xl:grid-cols-12\" aria-hidden=\"true\">\n {tokens.slice(0, 12).map((t) => (\n <div\n key={t.key}\n title={t.label}\n className=\"aspect-square rounded-md border border-border\"\n style={{ background: `var(--color-${t.key})` }}\n />\n ))}\n </div>\n <button\n type=\"button\"\n onClick={() => setOpen((o) => !o)}\n aria-expanded={open}\n aria-controls={controlsId}\n className=\"inline-flex items-center gap-1.5 text-sm font-medium text-foreground hover:text-primary\"\n data-testid={tid('customize')}\n >\n <ChevronDown className={`size-4 transition-transform ${open ? 'rotate-180' : ''}`} />\n Customize colours and type\n </button>\n {open && (\n <div\n id={controlsId}\n className=\"max-h-[28rem] overflow-y-auto rounded-md border border-border bg-card p-4\"\n data-testid={tid('controls')}\n >\n <p className=\"mb-2 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground\">\n Colours\n </p>\n <div className=\"grid gap-3 @xl:grid-cols-2\">\n {tokens.map((t) => colorRow(t.key, t.label))}\n </div>\n <p className=\"mt-6 mb-2 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground\">\n Typography &amp; shape\n </p>\n {Typography}\n </div>\n )}\n {SaveBar}\n </div>\n )\n }\n\n // ── Drawer layout — compact, single column ──────────────────────────────────\n if (variant === 'drawer') {\n return (\n <div className=\"flex h-full flex-col overflow-y-auto bg-card p-5\" data-testid={testIdPrefix}>\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"font-display text-lg font-semibold text-foreground\">Theme</h2>\n </div>\n {Presets}\n <p className=\"mt-5 mb-2 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground\">\n Colours\n </p>\n <div className=\"space-y-3\">{tokens.map((t) => colorRow(t.key, t.label))}</div>\n <p className=\"mt-6 mb-2 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground\">\n Typography &amp; shape\n </p>\n {Typography}\n {SaveBar}\n </div>\n )\n }\n\n // ── Panel layout — grouped cards + live preview ─────────────────────────────\n return (\n <div className=\"grid gap-6 lg:grid-cols-[1fr_320px]\" data-testid={testIdPrefix}>\n <div className=\"space-y-6\">\n <Card variant=\"elevated\" className=\"rounded-lg\">\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2 text-base\">\n <Palette className=\"size-4 text-[color:var(--color-primary)]\" /> Presets\n </CardTitle>\n </CardHeader>\n <CardContent>{Presets}</CardContent>\n </Card>\n\n {groups.map((group) => (\n <Card\n key={group}\n variant=\"elevated\"\n className=\"rounded-lg\"\n data-testid={tid(`group-${group}`)}\n >\n <CardHeader>\n <CardTitle className=\"text-base\">{groupLabels[group] ?? group}</CardTitle>\n </CardHeader>\n <CardContent className=\"grid gap-3 @xl:grid-cols-2\">\n {tokens.filter((t) => t.group === group).map((t) => colorRow(t.key, t.label))}\n </CardContent>\n </Card>\n ))}\n\n <Card variant=\"elevated\" className=\"rounded-lg\">\n <CardHeader>\n <CardTitle className=\"text-base\">Typography &amp; shape</CardTitle>\n </CardHeader>\n <CardContent>{Typography}</CardContent>\n </Card>\n {SaveBar}\n </div>\n\n <div className=\"lg:sticky lg:top-4 lg:self-start\">{Preview}</div>\n </div>\n )\n}\n"]}