@usetheo/ui 0.1.0-next.1 → 0.4.0-next.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.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { clsx } from 'clsx';
2
- import { twMerge } from 'tailwind-merge';
2
+ import { extendTailwindMerge } from 'tailwind-merge';
3
3
  import { createContext, forwardRef, useId, Children, isValidElement, cloneElement, useState, useMemo, Fragment as Fragment$1, useRef, useEffect, useContext, useCallback } from 'react';
4
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
5
  import * as DropdownMenu2 from '@radix-ui/react-dropdown-menu';
@@ -20,6 +20,19 @@ import * as SwitchPrimitive from '@radix-ui/react-switch';
20
20
  import { Command } from 'cmdk';
21
21
 
22
22
  // src/lib/cn.ts
23
+ var twMerge = extendTailwindMerge({
24
+ extend: {
25
+ classGroups: {
26
+ "font-size": [
27
+ { text: ["display-2xl", "display-xl", "display-lg", "display-md"] },
28
+ { text: ["headline", "title-lg", "title-md"] },
29
+ { text: ["body-lg", "body-md", "body-sm"] },
30
+ { text: ["label", "label-caps"] },
31
+ { text: ["code-md", "code-sm"] }
32
+ ]
33
+ }
34
+ }
35
+ });
23
36
  function cn(...inputs) {
24
37
  return twMerge(clsx(inputs));
25
38
  }
@@ -39,8 +52,30 @@ function safeHref(url) {
39
52
  }
40
53
  return url;
41
54
  }
55
+ var DensityContext = createContext(void 0);
56
+ var STYLE_ELEMENT_ID = "theo-ui-density-vars";
57
+ var DENSITY_CSS = `[data-density="compact"] { --theo-control-h: 2rem; --theo-control-px: 0.75rem; }
58
+ [data-density="comfortable"] { --theo-control-h: 2.25rem; --theo-control-px: 0.875rem; }
59
+ [data-density="spacious"] { --theo-control-h: 2.75rem; --theo-control-px: 1rem; }
60
+ `;
61
+ function injectDensityCss() {
62
+ if (typeof document === "undefined") return false;
63
+ if (document.getElementById(STYLE_ELEMENT_ID)) return false;
64
+ const style = document.createElement("style");
65
+ style.id = STYLE_ELEMENT_ID;
66
+ style.textContent = DENSITY_CSS;
67
+ document.head.appendChild(style);
68
+ return true;
69
+ }
70
+ function useDensity() {
71
+ const ctx = useContext(DensityContext);
72
+ if (!ctx) {
73
+ throw new Error("useDensity must be used inside <ThemeProvider>.");
74
+ }
75
+ return ctx;
76
+ }
42
77
  var ThemeContext = createContext(void 0);
43
- var STYLE_ELEMENT_ID = "theo-ui-theme-vars";
78
+ var STYLE_ELEMENT_ID2 = "theo-ui-theme-vars";
44
79
  var COLOR_VALUE_PATTERN = /^(#[0-9a-fA-F]{3,8}|(?:oklch|oklab|rgb|rgba|hsl|hsla|lab|lch|color)\(\s*[\d.\s%,/+\-]+\s*\)|-?\d+(?:\.\d+)?%?(?:\s+-?\d+(?:\.\d+)?%?){1,3}|var\(--[a-zA-Z0-9-]+(?:\s*,\s*[^();{}]+)?\)|transparent|currentColor|inherit|initial|unset)$/;
45
80
  var FONT_FAMILY_PATTERN = /^[\w\s,"'\-.]+$/;
46
81
  var THEME_NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
@@ -86,10 +121,10 @@ function fontsToCss(name, fonts) {
86
121
  }
87
122
  function injectThemeCss(themes) {
88
123
  if (typeof document === "undefined") return;
89
- let style = document.getElementById(STYLE_ELEMENT_ID);
124
+ let style = document.getElementById(STYLE_ELEMENT_ID2);
90
125
  if (!style) {
91
126
  style = document.createElement("style");
92
- style.id = STYLE_ELEMENT_ID;
127
+ style.id = STYLE_ELEMENT_ID2;
93
128
  document.head.appendChild(style);
94
129
  }
95
130
  const blocks = [];
@@ -124,7 +159,8 @@ function ThemeProvider({
124
159
  defaultTheme = "violet-forge",
125
160
  defaultMode = "dark",
126
161
  themes: themesProp,
127
- storageKey = "theo-ui:theme"
162
+ storageKey = "theo-ui:theme",
163
+ defaultDensity = "comfortable"
128
164
  }) {
129
165
  if (!themesProp || themesProp.length === 0) {
130
166
  throw new Error(
@@ -171,6 +207,16 @@ function ThemeProvider({
171
207
  return defaultMode;
172
208
  }
173
209
  });
210
+ const [density, setDensityState] = useState(() => {
211
+ if (typeof window === "undefined" || !storageKey) return defaultDensity;
212
+ try {
213
+ const stored = window.localStorage.getItem(`${storageKey}:density`);
214
+ return stored === "compact" || stored === "comfortable" || stored === "spacious" ? stored : defaultDensity;
215
+ } catch (err) {
216
+ warnStorageFailure("read density", err);
217
+ return defaultDensity;
218
+ }
219
+ });
174
220
  useEffect(() => {
175
221
  injectThemeCss(themes);
176
222
  }, [themes]);
@@ -180,24 +226,28 @@ function ThemeProvider({
180
226
  if (!active2) return;
181
227
  document.documentElement.setAttribute("data-theme", active2.name);
182
228
  document.documentElement.setAttribute("data-mode", mode);
229
+ document.documentElement.setAttribute("data-density", density);
183
230
  document.documentElement.classList.toggle("dark", mode === "dark");
184
231
  loadThemeFonts(active2);
185
- }, [themeName, mode, themes]);
232
+ injectDensityCss();
233
+ }, [themeName, mode, density, themes]);
186
234
  useEffect(() => {
187
235
  if (typeof window === "undefined" || !storageKey) return;
188
236
  try {
189
237
  window.localStorage.setItem(`${storageKey}:name`, themeName);
190
238
  window.localStorage.setItem(`${storageKey}:mode`, mode);
239
+ window.localStorage.setItem(`${storageKey}:density`, density);
191
240
  } catch (err) {
192
- warnStorageFailure("persist theme + mode", err);
241
+ warnStorageFailure("persist theme + mode + density", err);
193
242
  }
194
- }, [themeName, mode, storageKey]);
243
+ }, [themeName, mode, density, storageKey]);
195
244
  const setTheme = useCallback((name) => setThemeName(name), []);
196
245
  const setMode = useCallback((next) => setModeState(next), []);
197
246
  const toggleMode = useCallback(
198
247
  () => setModeState((cur) => cur === "light" ? "dark" : "light"),
199
248
  []
200
249
  );
250
+ const setDensity = useCallback((next) => setDensityState(next), []);
201
251
  const registerTheme = useCallback((theme) => {
202
252
  setThemes((cur) => {
203
253
  const idx = cur.findIndex((t) => t.name === theme.name);
@@ -222,7 +272,8 @@ function ThemeProvider({
222
272
  }),
223
273
  [active, mode, themes, setTheme, setMode, toggleMode, registerTheme]
224
274
  );
225
- return /* @__PURE__ */ jsx(ThemeContext.Provider, { value, children });
275
+ const densityValue = useMemo(() => ({ density, setDensity }), [density, setDensity]);
276
+ return /* @__PURE__ */ jsx(ThemeContext.Provider, { value, children: /* @__PURE__ */ jsx(DensityContext.Provider, { value: densityValue, children }) });
226
277
  }
227
278
  function useTheme() {
228
279
  const ctx = useContext(ThemeContext);
@@ -424,8 +475,8 @@ var classicPaper = {
424
475
  "primary-foreground": "0 0% 100%",
425
476
  secondary: "210 40% 96%",
426
477
  "secondary-foreground": "222 47% 11%",
427
- accent: "37 92% 50%",
428
- "accent-deep": "32 81% 40%",
478
+ accent: "37 92% 40%",
479
+ "accent-deep": "32 81% 30%",
429
480
  "accent-foreground": "0 0% 100%",
430
481
  muted: "210 40% 96%",
431
482
  "muted-foreground": "215 16% 47%",
@@ -550,11 +601,655 @@ var auroraTerminal = {
550
601
  }
551
602
  };
552
603
 
604
+ // src/themes/define.ts
605
+ var NAME_PATTERN = /^[a-z][a-z0-9-]*$/i;
606
+ function defaultLabel(name) {
607
+ if (name.length === 0) return name;
608
+ return name.charAt(0).toUpperCase() + name.slice(1);
609
+ }
610
+ function defineTheme(input) {
611
+ if (typeof input?.name !== "string" || input.name.length === 0) {
612
+ throw new Error("defineTheme: `name` is required and cannot be empty.");
613
+ }
614
+ if (!NAME_PATTERN.test(input.name)) {
615
+ throw new Error(
616
+ `defineTheme: invalid name "${input.name}". Must match /^[a-z][a-z0-9-]*$/i \u2014 letters, digits, and hyphens only, starting with a letter.`
617
+ );
618
+ }
619
+ const lightOverride = input.light ?? {};
620
+ const darkOverride = input.dark ?? {};
621
+ const fontsOverride = input.fonts ?? {};
622
+ const theme = {
623
+ name: input.name,
624
+ label: input.label ?? defaultLabel(input.name),
625
+ description: input.description,
626
+ fonts: { ...violetForge.fonts, ...fontsOverride },
627
+ light: { ...violetForge.light, ...lightOverride },
628
+ dark: { ...violetForge.dark, ...darkOverride },
629
+ fontUrls: input.fontUrls ?? violetForge.fontUrls
630
+ };
631
+ return theme;
632
+ }
633
+
634
+ // src/themes/color.ts
635
+ function hexCharToNibble(ch) {
636
+ if (ch >= "0" && ch <= "9") return ch.charCodeAt(0) - 48;
637
+ if (ch >= "a" && ch <= "f") return ch.charCodeAt(0) - 87;
638
+ if (ch >= "A" && ch <= "F") return ch.charCodeAt(0) - 55;
639
+ throw new Error(`hex(): invalid hex character "${ch}"`);
640
+ }
641
+ function parseHex(input) {
642
+ if (!input.startsWith("#")) {
643
+ throw new Error(`hex(): expected '#'-prefixed input, got "${input}"`);
644
+ }
645
+ const body = input.slice(1);
646
+ let r;
647
+ let g;
648
+ let b;
649
+ if (body.length === 3 || body.length === 4) {
650
+ const nr = hexCharToNibble(body.charAt(0));
651
+ const ng = hexCharToNibble(body.charAt(1));
652
+ const nb = hexCharToNibble(body.charAt(2));
653
+ r = nr << 4 | nr;
654
+ g = ng << 4 | ng;
655
+ b = nb << 4 | nb;
656
+ } else if (body.length === 6 || body.length === 8) {
657
+ r = hexCharToNibble(body.charAt(0)) << 4 | hexCharToNibble(body.charAt(1));
658
+ g = hexCharToNibble(body.charAt(2)) << 4 | hexCharToNibble(body.charAt(3));
659
+ b = hexCharToNibble(body.charAt(4)) << 4 | hexCharToNibble(body.charAt(5));
660
+ } else {
661
+ throw new Error(
662
+ `hex(): invalid length ${body.length} for hex input "${input}" \u2014 expected 3, 4, 6, or 8 hex chars after the '#'.`
663
+ );
664
+ }
665
+ return { r, g, b };
666
+ }
667
+ function rgbToHsl(r, g, b) {
668
+ const rn = r / 255;
669
+ const gn = g / 255;
670
+ const bn = b / 255;
671
+ const max = Math.max(rn, gn, bn);
672
+ const min = Math.min(rn, gn, bn);
673
+ const l = (max + min) / 2;
674
+ let h = 0;
675
+ let s = 0;
676
+ if (max !== min) {
677
+ const d = max - min;
678
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
679
+ switch (max) {
680
+ case rn:
681
+ h = (gn - bn) / d + (gn < bn ? 6 : 0);
682
+ break;
683
+ case gn:
684
+ h = (bn - rn) / d + 2;
685
+ break;
686
+ default:
687
+ h = (rn - gn) / d + 4;
688
+ break;
689
+ }
690
+ h *= 60;
691
+ }
692
+ const hh = Math.round(h);
693
+ const ss = Math.round(s * 100);
694
+ const ll = Math.round(l * 100);
695
+ return `${hh} ${ss}% ${ll}%`;
696
+ }
697
+ function hex(input) {
698
+ const { r, g, b } = parseHex(input);
699
+ return rgbToHsl(r, g, b);
700
+ }
701
+ function rgb(r, g, b) {
702
+ for (const value of [r, g, b]) {
703
+ if (!Number.isFinite(value) || value < 0 || value > 255) {
704
+ throw new Error(
705
+ `rgb(): channel out of range \u2014 expected 0..255, got ${value}. Did you mix percentage values?`
706
+ );
707
+ }
708
+ }
709
+ return rgbToHsl(Math.round(r), Math.round(g), Math.round(b));
710
+ }
711
+
712
+ // src/themes/vercel-mono.ts
713
+ var vercelMono = {
714
+ name: "vercel-mono",
715
+ label: "Vercel Mono",
716
+ description: "Inspired by, not affiliated with Vercel. Monochrome canvas + signature blue.",
717
+ fonts: {
718
+ display: '"Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
719
+ body: '"Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
720
+ mono: '"Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace'
721
+ },
722
+ fontUrls: [
723
+ "https://fonts.googleapis.com/css2?family=Geist:wght@100..900&family=Geist+Mono:wght@100..900&display=swap"
724
+ ],
725
+ light: {
726
+ background: "0 0% 100%",
727
+ foreground: "0 0% 0%",
728
+ card: "0 0% 100%",
729
+ "card-foreground": "0 0% 0%",
730
+ popover: "0 0% 100%",
731
+ "popover-foreground": "0 0% 0%",
732
+ primary: "212 100% 47%",
733
+ "primary-deep": "212 100% 36%",
734
+ "primary-glow": "212 100% 72%",
735
+ "primary-foreground": "0 0% 100%",
736
+ secondary: "0 0% 96%",
737
+ "secondary-foreground": "0 0% 0%",
738
+ accent: "212 100% 47%",
739
+ "accent-deep": "212 100% 36%",
740
+ "accent-foreground": "0 0% 100%",
741
+ muted: "0 0% 96%",
742
+ "muted-foreground": "0 0% 40%",
743
+ border: "0 0% 92%",
744
+ input: "0 0% 92%",
745
+ ring: "212 100% 47%",
746
+ success: "168 76% 40%",
747
+ "success-foreground": "0 0% 100%",
748
+ warning: "34 92% 45%",
749
+ "warning-foreground": "0 0% 100%",
750
+ destructive: "0 100% 40%",
751
+ "destructive-foreground": "0 0% 100%",
752
+ info: "212 100% 47%",
753
+ "info-foreground": "0 0% 100%"
754
+ },
755
+ dark: {
756
+ background: "0 0% 4%",
757
+ foreground: "0 0% 93%",
758
+ card: "0 0% 7%",
759
+ "card-foreground": "0 0% 93%",
760
+ popover: "0 0% 7%",
761
+ "popover-foreground": "0 0% 93%",
762
+ primary: "212 100% 55%",
763
+ "primary-deep": "212 100% 42%",
764
+ "primary-glow": "212 100% 75%",
765
+ "primary-foreground": "0 0% 100%",
766
+ secondary: "0 0% 13%",
767
+ "secondary-foreground": "0 0% 93%",
768
+ accent: "212 100% 60%",
769
+ "accent-deep": "212 100% 47%",
770
+ "accent-foreground": "0 0% 0%",
771
+ muted: "0 0% 13%",
772
+ "muted-foreground": "0 0% 60%",
773
+ border: "0 0% 20%",
774
+ input: "0 0% 20%",
775
+ ring: "212 100% 55%",
776
+ success: "144 89% 50%",
777
+ "success-foreground": "0 0% 0%",
778
+ warning: "34 92% 65%",
779
+ "warning-foreground": "0 0% 0%",
780
+ destructive: "0 100% 55%",
781
+ "destructive-foreground": "0 0% 100%",
782
+ info: "212 100% 55%",
783
+ "info-foreground": "0 0% 100%"
784
+ }
785
+ };
786
+
787
+ // src/themes/github-dark.ts
788
+ var githubDark = {
789
+ name: "github-dark",
790
+ label: "GitHub Dark",
791
+ description: "GitHub's default dark theme. Primer Primitives tokens.",
792
+ fonts: {
793
+ display: '"Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
794
+ body: '"Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
795
+ mono: '"Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace'
796
+ },
797
+ fontUrls: [
798
+ "https://fonts.googleapis.com/css2?family=Geist:wght@100..900&family=Geist+Mono:wght@100..900&display=swap"
799
+ ],
800
+ light: {
801
+ background: "0 0% 100%",
802
+ foreground: "213 13% 16%",
803
+ card: "210 29% 97%",
804
+ "card-foreground": "213 13% 16%",
805
+ popover: "0 0% 100%",
806
+ "popover-foreground": "213 13% 16%",
807
+ primary: "212 92% 44%",
808
+ "primary-deep": "212 92% 36%",
809
+ "primary-glow": "212 92% 58%",
810
+ "primary-foreground": "0 0% 100%",
811
+ secondary: "210 29% 97%",
812
+ "secondary-foreground": "213 13% 16%",
813
+ accent: "213 84% 52%",
814
+ "accent-deep": "213 84% 42%",
815
+ "accent-foreground": "0 0% 100%",
816
+ muted: "210 29% 97%",
817
+ "muted-foreground": "213 8% 43%",
818
+ border: "210 14% 84%",
819
+ input: "210 14% 84%",
820
+ ring: "212 92% 44%",
821
+ success: "137 66% 30%",
822
+ "success-foreground": "0 0% 100%",
823
+ warning: "41 100% 30%",
824
+ "warning-foreground": "0 0% 100%",
825
+ destructive: "355 71% 47%",
826
+ "destructive-foreground": "0 0% 100%",
827
+ info: "212 92% 44%",
828
+ "info-foreground": "0 0% 100%"
829
+ },
830
+ dark: {
831
+ background: "215 28% 7%",
832
+ foreground: "210 67% 96%",
833
+ card: "215 21% 11%",
834
+ "card-foreground": "210 67% 96%",
835
+ popover: "215 21% 11%",
836
+ "popover-foreground": "210 67% 96%",
837
+ primary: "212 92% 57%",
838
+ "primary-deep": "212 92% 47%",
839
+ "primary-glow": "213 92% 67%",
840
+ "primary-foreground": "0 0% 100%",
841
+ secondary: "215 21% 14%",
842
+ "secondary-foreground": "210 67% 96%",
843
+ accent: "213 92% 61%",
844
+ "accent-deep": "213 92% 50%",
845
+ "accent-foreground": "0 0% 100%",
846
+ muted: "215 21% 14%",
847
+ "muted-foreground": "213 9% 59%",
848
+ border: "213 13% 21%",
849
+ input: "213 13% 21%",
850
+ ring: "212 92% 57%",
851
+ success: "135 53% 49%",
852
+ "success-foreground": "0 0% 0%",
853
+ warning: "41 73% 48%",
854
+ "warning-foreground": "0 0% 0%",
855
+ destructive: "1 90% 62%",
856
+ "destructive-foreground": "0 0% 100%",
857
+ info: "212 92% 57%",
858
+ "info-foreground": "0 0% 100%"
859
+ }
860
+ };
861
+
862
+ // src/themes/dracula.ts
863
+ var dracula = {
864
+ name: "dracula",
865
+ label: "Dracula",
866
+ description: "Cult OSS theme (draculatheme.com, MIT). Light mode is Theo-adapted for WCAG AA.",
867
+ fonts: {
868
+ display: '"Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
869
+ body: '"Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
870
+ mono: '"Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace'
871
+ },
872
+ fontUrls: [
873
+ "https://fonts.googleapis.com/css2?family=Geist:wght@100..900&family=Geist+Mono:wght@100..900&display=swap"
874
+ ],
875
+ light: {
876
+ background: "60 30% 96%",
877
+ foreground: "231 15% 18%",
878
+ card: "0 0% 100%",
879
+ "card-foreground": "231 15% 18%",
880
+ popover: "0 0% 100%",
881
+ "popover-foreground": "231 15% 18%",
882
+ primary: "275 70% 45%",
883
+ "primary-deep": "271 63% 35%",
884
+ "primary-glow": "265 89% 70%",
885
+ "primary-foreground": "0 0% 100%",
886
+ secondary: "60 20% 92%",
887
+ "secondary-foreground": "231 15% 18%",
888
+ accent: "271 63% 40%",
889
+ "accent-deep": "271 63% 30%",
890
+ "accent-foreground": "0 0% 100%",
891
+ muted: "60 20% 92%",
892
+ "muted-foreground": "225 20% 40%",
893
+ border: "60 15% 88%",
894
+ input: "60 15% 88%",
895
+ ring: "275 70% 45%",
896
+ success: "129 33% 35%",
897
+ "success-foreground": "0 0% 100%",
898
+ warning: "43 89% 30%",
899
+ "warning-foreground": "0 0% 100%",
900
+ destructive: "0 71% 42%",
901
+ "destructive-foreground": "0 0% 100%",
902
+ info: "190 88% 30%",
903
+ "info-foreground": "0 0% 100%"
904
+ },
905
+ dark: {
906
+ background: "231 15% 18%",
907
+ foreground: "60 30% 96%",
908
+ card: "232 14% 22%",
909
+ "card-foreground": "60 30% 96%",
910
+ popover: "232 14% 22%",
911
+ "popover-foreground": "60 30% 96%",
912
+ primary: "326 100% 74%",
913
+ "primary-deep": "326 100% 60%",
914
+ "primary-glow": "326 100% 85%",
915
+ "primary-foreground": "231 15% 18%",
916
+ secondary: "232 14% 28%",
917
+ "secondary-foreground": "60 30% 96%",
918
+ accent: "265 89% 78%",
919
+ "accent-deep": "265 89% 65%",
920
+ "accent-foreground": "231 15% 18%",
921
+ muted: "232 14% 28%",
922
+ "muted-foreground": "225 27% 65%",
923
+ border: "232 14% 31%",
924
+ input: "232 14% 31%",
925
+ ring: "326 100% 74%",
926
+ success: "135 94% 65%",
927
+ "success-foreground": "231 15% 18%",
928
+ warning: "65 92% 76%",
929
+ "warning-foreground": "231 15% 18%",
930
+ destructive: "0 100% 67%",
931
+ "destructive-foreground": "0 0% 100%",
932
+ info: "191 97% 77%",
933
+ "info-foreground": "231 15% 18%"
934
+ }
935
+ };
936
+
937
+ // src/themes/one-dark.ts
938
+ var oneDark = {
939
+ name: "one-dark",
940
+ label: "One Dark",
941
+ description: "Atom's One Dark + One Light syntax theme (MIT). Iconic IDE look.",
942
+ fonts: {
943
+ display: '"Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
944
+ body: '"Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
945
+ mono: '"Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace'
946
+ },
947
+ fontUrls: [
948
+ "https://fonts.googleapis.com/css2?family=Geist:wght@100..900&family=Geist+Mono:wght@100..900&display=swap"
949
+ ],
950
+ light: {
951
+ background: "0 0% 98%",
952
+ foreground: "230 8% 24%",
953
+ card: "0 0% 100%",
954
+ "card-foreground": "230 8% 24%",
955
+ popover: "0 0% 100%",
956
+ "popover-foreground": "230 8% 24%",
957
+ primary: "220 88% 50%",
958
+ "primary-deep": "220 88% 40%",
959
+ "primary-glow": "220 88% 70%",
960
+ "primary-foreground": "0 0% 100%",
961
+ secondary: "0 0% 95%",
962
+ "secondary-foreground": "230 8% 24%",
963
+ accent: "301 62% 40%",
964
+ "accent-deep": "301 62% 30%",
965
+ "accent-foreground": "0 0% 100%",
966
+ muted: "0 0% 95%",
967
+ "muted-foreground": "230 4% 50%",
968
+ border: "0 0% 90%",
969
+ input: "0 0% 90%",
970
+ ring: "220 88% 50%",
971
+ success: "119 34% 35%",
972
+ "success-foreground": "0 0% 100%",
973
+ warning: "41 99% 30%",
974
+ "warning-foreground": "0 0% 100%",
975
+ destructive: "5 74% 45%",
976
+ "destructive-foreground": "0 0% 100%",
977
+ info: "198 99% 30%",
978
+ "info-foreground": "0 0% 100%"
979
+ },
980
+ dark: {
981
+ background: "220 13% 18%",
982
+ foreground: "220 14% 71%",
983
+ card: "220 13% 15%",
984
+ "card-foreground": "220 14% 71%",
985
+ popover: "220 13% 15%",
986
+ "popover-foreground": "220 14% 71%",
987
+ primary: "207 82% 66%",
988
+ "primary-deep": "207 82% 52%",
989
+ "primary-glow": "207 82% 78%",
990
+ "primary-foreground": "220 13% 18%",
991
+ secondary: "220 13% 23%",
992
+ "secondary-foreground": "220 14% 71%",
993
+ accent: "286 60% 67%",
994
+ "accent-deep": "286 60% 52%",
995
+ "accent-foreground": "220 13% 18%",
996
+ muted: "220 13% 23%",
997
+ "muted-foreground": "220 8% 55%",
998
+ border: "220 13% 28%",
999
+ input: "220 13% 28%",
1000
+ ring: "207 82% 66%",
1001
+ success: "95 38% 62%",
1002
+ "success-foreground": "220 13% 18%",
1003
+ warning: "29 54% 61%",
1004
+ "warning-foreground": "220 13% 18%",
1005
+ destructive: "355 65% 65%",
1006
+ "destructive-foreground": "0 0% 100%",
1007
+ info: "187 47% 55%",
1008
+ "info-foreground": "220 13% 18%"
1009
+ }
1010
+ };
1011
+
1012
+ // src/themes/anthropic-style.ts
1013
+ var anthropicStyle = {
1014
+ name: "anthropic-style",
1015
+ label: "Anthropic-style",
1016
+ description: "Inspired by, not affiliated with Anthropic. Warm cream + burnt sienna editorial feel.",
1017
+ fonts: {
1018
+ display: '"Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
1019
+ body: '"Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
1020
+ mono: '"Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace'
1021
+ },
1022
+ fontUrls: [
1023
+ "https://fonts.googleapis.com/css2?family=Geist:wght@100..900&family=Geist+Mono:wght@100..900&display=swap"
1024
+ ],
1025
+ light: {
1026
+ background: "60 27% 97%",
1027
+ foreground: "0 0% 10%",
1028
+ card: "0 0% 100%",
1029
+ "card-foreground": "0 0% 10%",
1030
+ popover: "0 0% 100%",
1031
+ "popover-foreground": "0 0% 10%",
1032
+ primary: "15 54% 45%",
1033
+ "primary-deep": "15 54% 35%",
1034
+ "primary-glow": "15 54% 65%",
1035
+ "primary-foreground": "0 0% 100%",
1036
+ secondary: "45 22% 92%",
1037
+ "secondary-foreground": "0 0% 10%",
1038
+ accent: "26 39% 39%",
1039
+ "accent-deep": "26 39% 29%",
1040
+ "accent-foreground": "0 0% 100%",
1041
+ muted: "45 22% 92%",
1042
+ "muted-foreground": "0 0% 39%",
1043
+ border: "45 22% 87%",
1044
+ input: "45 22% 87%",
1045
+ ring: "15 54% 45%",
1046
+ success: "127 35% 35%",
1047
+ "success-foreground": "0 0% 100%",
1048
+ warning: "35 65% 35%",
1049
+ "warning-foreground": "0 0% 100%",
1050
+ destructive: "5 60% 40%",
1051
+ "destructive-foreground": "0 0% 100%",
1052
+ info: "200 50% 35%",
1053
+ "info-foreground": "0 0% 100%"
1054
+ },
1055
+ dark: {
1056
+ background: "0 0% 10%",
1057
+ foreground: "36 28% 93%",
1058
+ card: "0 0% 15%",
1059
+ "card-foreground": "36 28% 93%",
1060
+ popover: "0 0% 15%",
1061
+ "popover-foreground": "36 28% 93%",
1062
+ primary: "16 62% 60%",
1063
+ "primary-deep": "16 62% 48%",
1064
+ "primary-glow": "16 62% 72%",
1065
+ "primary-foreground": "0 0% 100%",
1066
+ secondary: "0 0% 18%",
1067
+ "secondary-foreground": "36 28% 93%",
1068
+ accent: "21 33% 55%",
1069
+ "accent-deep": "21 33% 42%",
1070
+ "accent-foreground": "0 0% 100%",
1071
+ muted: "0 0% 18%",
1072
+ "muted-foreground": "30 6% 64%",
1073
+ border: "0 0% 25%",
1074
+ input: "0 0% 25%",
1075
+ ring: "16 62% 60%",
1076
+ success: "142 71% 58%",
1077
+ "success-foreground": "0 0% 10%",
1078
+ warning: "45 96% 65%",
1079
+ "warning-foreground": "0 0% 10%",
1080
+ destructive: "0 84% 60%",
1081
+ "destructive-foreground": "0 0% 100%",
1082
+ info: "200 70% 60%",
1083
+ "info-foreground": "0 0% 10%"
1084
+ }
1085
+ };
1086
+
1087
+ // src/themes/openai-style.ts
1088
+ var openaiStyle = {
1089
+ name: "openai-style",
1090
+ label: "OpenAI-style",
1091
+ description: "Inspired by, not affiliated with OpenAI. Minimal canvas + ChatGPT green.",
1092
+ fonts: {
1093
+ display: '"Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
1094
+ body: '"Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
1095
+ mono: '"Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace'
1096
+ },
1097
+ fontUrls: [
1098
+ "https://fonts.googleapis.com/css2?family=Geist:wght@100..900&family=Geist+Mono:wght@100..900&display=swap"
1099
+ ],
1100
+ light: {
1101
+ background: "0 0% 100%",
1102
+ foreground: "0 0% 13%",
1103
+ card: "240 5% 97%",
1104
+ "card-foreground": "0 0% 13%",
1105
+ popover: "0 0% 100%",
1106
+ "popover-foreground": "0 0% 13%",
1107
+ primary: "165 82% 35%",
1108
+ "primary-deep": "165 82% 28%",
1109
+ "primary-glow": "165 82% 50%",
1110
+ "primary-foreground": "0 0% 100%",
1111
+ secondary: "240 5% 96%",
1112
+ "secondary-foreground": "0 0% 13%",
1113
+ accent: "165 82% 35%",
1114
+ "accent-deep": "165 82% 28%",
1115
+ "accent-foreground": "0 0% 100%",
1116
+ muted: "240 5% 96%",
1117
+ "muted-foreground": "240 7% 47%",
1118
+ border: "0 0% 90%",
1119
+ input: "0 0% 90%",
1120
+ ring: "165 82% 35%",
1121
+ success: "165 82% 35%",
1122
+ "success-foreground": "0 0% 100%",
1123
+ warning: "30 91% 44%",
1124
+ "warning-foreground": "0 0% 100%",
1125
+ destructive: "0 73% 50%",
1126
+ "destructive-foreground": "0 0% 100%",
1127
+ info: "212 100% 47%",
1128
+ "info-foreground": "0 0% 100%"
1129
+ },
1130
+ dark: {
1131
+ background: "0 0% 13%",
1132
+ foreground: "0 0% 93%",
1133
+ card: "0 0% 18%",
1134
+ "card-foreground": "0 0% 93%",
1135
+ popover: "0 0% 18%",
1136
+ "popover-foreground": "0 0% 93%",
1137
+ primary: "155 78% 30%",
1138
+ "primary-deep": "155 78% 22%",
1139
+ "primary-glow": "155 78% 50%",
1140
+ "primary-foreground": "0 0% 100%",
1141
+ secondary: "0 0% 20%",
1142
+ "secondary-foreground": "0 0% 93%",
1143
+ accent: "155 78% 50%",
1144
+ "accent-deep": "155 78% 40%",
1145
+ "accent-foreground": "0 0% 13%",
1146
+ muted: "0 0% 20%",
1147
+ "muted-foreground": "0 0% 61%",
1148
+ border: "0 0% 26%",
1149
+ input: "0 0% 26%",
1150
+ ring: "155 78% 43%",
1151
+ success: "155 78% 43%",
1152
+ "success-foreground": "0 0% 100%",
1153
+ warning: "38 92% 50%",
1154
+ "warning-foreground": "0 0% 13%",
1155
+ destructive: "0 84% 60%",
1156
+ "destructive-foreground": "0 0% 100%",
1157
+ info: "212 100% 55%",
1158
+ "info-foreground": "0 0% 100%"
1159
+ }
1160
+ };
1161
+
1162
+ // src/themes/linear-glass.ts
1163
+ var linearGlass = {
1164
+ name: "linear-glass",
1165
+ label: "Linear Glass",
1166
+ description: "Inspired by, not affiliated with Linear. Refined indigo on glassy surfaces.",
1167
+ fonts: {
1168
+ display: '"Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
1169
+ body: '"Geist", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
1170
+ mono: '"Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace'
1171
+ },
1172
+ fontUrls: [
1173
+ "https://fonts.googleapis.com/css2?family=Geist:wght@100..900&family=Geist+Mono:wght@100..900&display=swap"
1174
+ ],
1175
+ light: {
1176
+ background: "0 0% 100%",
1177
+ foreground: "240 5% 12%",
1178
+ card: "220 25% 98%",
1179
+ "card-foreground": "240 5% 12%",
1180
+ popover: "0 0% 100%",
1181
+ "popover-foreground": "240 5% 12%",
1182
+ primary: "233 56% 55%",
1183
+ "primary-deep": "233 56% 45%",
1184
+ "primary-glow": "233 56% 70%",
1185
+ "primary-foreground": "0 0% 100%",
1186
+ secondary: "240 9% 96%",
1187
+ "secondary-foreground": "240 5% 12%",
1188
+ accent: "245 60% 60%",
1189
+ "accent-deep": "245 60% 50%",
1190
+ "accent-foreground": "0 0% 100%",
1191
+ muted: "240 9% 96%",
1192
+ "muted-foreground": "240 4% 44%",
1193
+ border: "240 9% 93%",
1194
+ input: "240 9% 93%",
1195
+ ring: "233 56% 55%",
1196
+ success: "155 62% 35%",
1197
+ "success-foreground": "0 0% 100%",
1198
+ warning: "35 76% 45%",
1199
+ "warning-foreground": "0 0% 100%",
1200
+ destructive: "358 75% 50%",
1201
+ "destructive-foreground": "0 0% 100%",
1202
+ info: "233 56% 55%",
1203
+ "info-foreground": "0 0% 100%"
1204
+ },
1205
+ dark: {
1206
+ background: "240 9% 6%",
1207
+ foreground: "0 0% 90%",
1208
+ card: "240 8% 11%",
1209
+ "card-foreground": "0 0% 90%",
1210
+ popover: "240 8% 11%",
1211
+ "popover-foreground": "0 0% 90%",
1212
+ primary: "245 60% 67%",
1213
+ "primary-deep": "245 60% 55%",
1214
+ "primary-glow": "245 60% 78%",
1215
+ "primary-foreground": "0 0% 100%",
1216
+ secondary: "240 8% 14%",
1217
+ "secondary-foreground": "0 0% 90%",
1218
+ accent: "253 100% 78%",
1219
+ "accent-deep": "253 100% 65%",
1220
+ "accent-foreground": "240 9% 6%",
1221
+ muted: "240 8% 14%",
1222
+ "muted-foreground": "240 5% 67%",
1223
+ border: "240 6% 17%",
1224
+ input: "240 6% 17%",
1225
+ ring: "245 60% 67%",
1226
+ success: "147 49% 53%",
1227
+ "success-foreground": "240 9% 6%",
1228
+ warning: "32 100% 66%",
1229
+ "warning-foreground": "240 9% 6%",
1230
+ destructive: "357 100% 70%",
1231
+ "destructive-foreground": "240 9% 6%",
1232
+ info: "245 60% 67%",
1233
+ "info-foreground": "0 0% 100%"
1234
+ }
1235
+ };
1236
+
553
1237
  // src/themes/index.ts
554
- var builtinThemes = [violetForge, classicPaper, auroraTerminal];
1238
+ var builtinThemes = [
1239
+ violetForge,
1240
+ classicPaper,
1241
+ auroraTerminal,
1242
+ vercelMono,
1243
+ githubDark,
1244
+ dracula,
1245
+ oneDark,
1246
+ anthropicStyle,
1247
+ openaiStyle,
1248
+ linearGlass
1249
+ ];
555
1250
  var toastVariants = cva(
556
1251
  [
557
- "group pointer-events-auto relative flex w-full items-start gap-3 overflow-hidden rounded-lg border p-4 pr-10 shadow-md",
1252
+ "group pointer-events-auto relative flex w-full items-start gap-3 overflow-hidden rounded-lg border pr-10 shadow-md",
558
1253
  "data-[state=open]:slide-in-from-top-full data-[state=open]:fade-in-0 data-[state=open]:animate-in",
559
1254
  "data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=closed]:animate-out",
560
1255
  "data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)]",
@@ -568,9 +1263,14 @@ var toastVariants = cva(
568
1263
  success: "border-success/40 bg-popover text-popover-foreground",
569
1264
  warning: "border-warning/40 bg-popover text-popover-foreground",
570
1265
  destructive: "border-destructive/50 bg-popover text-popover-foreground"
1266
+ },
1267
+ size: {
1268
+ sm: "p-3 text-body-sm",
1269
+ md: "p-4 text-body-md",
1270
+ lg: "p-5 text-body-lg"
571
1271
  }
572
1272
  },
573
- defaultVariants: { variant: "default" }
1273
+ defaultVariants: { variant: "default", size: "md" }
574
1274
  }
575
1275
  );
576
1276
  var iconForVariant = {
@@ -581,10 +1281,18 @@ var iconForVariant = {
581
1281
  destructive: /* @__PURE__ */ jsx(AlertCircle, { className: "size-4 shrink-0 text-destructive", "aria-hidden": "true" })
582
1282
  };
583
1283
  var ToastRoot = forwardRef(
584
- ({ className, variant = "default", children, ...props }, ref) => /* @__PURE__ */ jsxs(ToastPrimitive.Root, { ref, className: cn(toastVariants({ variant }), className), ...props, children: [
585
- /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: iconForVariant[variant] }),
586
- /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children })
587
- ] })
1284
+ ({ className, variant = "default", size, children, ...props }, ref) => /* @__PURE__ */ jsxs(
1285
+ ToastPrimitive.Root,
1286
+ {
1287
+ ref,
1288
+ className: cn(toastVariants({ variant, size }), className),
1289
+ ...props,
1290
+ children: [
1291
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: iconForVariant[variant] }),
1292
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children })
1293
+ ]
1294
+ }
1295
+ )
588
1296
  );
589
1297
  ToastRoot.displayName = "Toast";
590
1298
  var ToastTitle = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
@@ -747,9 +1455,12 @@ var buttonVariants = cva(
747
1455
  },
748
1456
  size: {
749
1457
  sm: "h-8 px-3 text-body-sm",
750
- md: "h-10 px-4 text-body-md",
751
- lg: "h-12 px-6 text-body-lg",
752
- icon: "h-10 w-10 p-0"
1458
+ // md: tier ajustável via density (CSS var on :root). See D3 ADR of
1459
+ // faang-density-tightening plan. Default `comfortable` density makes
1460
+ // this 36px (--theo-control-h: 2.25rem). sm and lg stay hardcoded.
1461
+ md: "h-[var(--theo-control-h,2.25rem)] px-[var(--theo-control-px,0.875rem)] text-body-sm",
1462
+ lg: "h-11 px-4 text-body-md",
1463
+ icon: "h-[var(--theo-control-h,2.25rem)] w-[var(--theo-control-h,2.25rem)] p-0"
753
1464
  }
754
1465
  },
755
1466
  defaultVariants: {
@@ -775,8 +1486,8 @@ var Button = forwardRef(
775
1486
  Button.displayName = "Button";
776
1487
  var badgeVariants = cva(
777
1488
  [
778
- "inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5",
779
- "font-sans text-label uppercase tracking-wider",
1489
+ "inline-flex items-center gap-1.5 rounded-full border",
1490
+ "font-sans uppercase tracking-wider",
780
1491
  "transition-colors"
781
1492
  ],
782
1493
  {
@@ -789,12 +1500,19 @@ var badgeVariants = cva(
789
1500
  warning: "border-warning/40 bg-warning/15 text-warning",
790
1501
  destructive: "border-destructive/40 bg-destructive/15 text-destructive",
791
1502
  outline: "border-border bg-transparent text-foreground"
1503
+ },
1504
+ size: {
1505
+ sm: "px-2 py-0.5 text-label-caps",
1506
+ md: "px-2.5 py-0.5 text-label",
1507
+ lg: "px-3 py-1 text-body-md"
792
1508
  }
793
1509
  },
794
- defaultVariants: { variant: "default" }
1510
+ defaultVariants: { variant: "default", size: "md" }
795
1511
  }
796
1512
  );
797
- var Badge = forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx("span", { ref, className: cn(badgeVariants({ variant }), className), ...props }));
1513
+ var Badge = forwardRef(
1514
+ ({ className, variant, size, ...props }, ref) => /* @__PURE__ */ jsx("span", { ref, className: cn(badgeVariants({ variant, size }), className), ...props })
1515
+ );
798
1516
  Badge.displayName = "Badge";
799
1517
  var toneClass = {
800
1518
  primary: "bg-primary",
@@ -823,8 +1541,10 @@ var Dot = forwardRef(
823
1541
  Dot.displayName = "Badge.Dot";
824
1542
  var BadgeWithDot = Badge;
825
1543
  BadgeWithDot.Dot = Dot;
1544
+ var CardContext = createContext({ size: "md" });
1545
+ var useCardSize = () => useContext(CardContext).size;
826
1546
  var Root3 = forwardRef(
827
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1547
+ ({ className, size = "md", ...props }, ref) => /* @__PURE__ */ jsx(CardContext.Provider, { value: { size }, children: /* @__PURE__ */ jsx(
828
1548
  "div",
829
1549
  {
830
1550
  ref,
@@ -835,21 +1555,39 @@ var Root3 = forwardRef(
835
1555
  ),
836
1556
  ...props
837
1557
  }
838
- )
1558
+ ) })
839
1559
  );
840
1560
  Root3.displayName = "Card";
1561
+ var headerPadBySize = {
1562
+ sm: "gap-1 p-3 pb-1.5",
1563
+ md: "gap-1.5 p-5 pb-2.5",
1564
+ lg: "gap-2 p-6 pb-3"
1565
+ };
841
1566
  var Header = forwardRef(
842
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col gap-1.5 p-6 pb-3", className), ...props })
1567
+ ({ className, ...props }, ref) => {
1568
+ const size = useCardSize();
1569
+ return /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col", headerPadBySize[size], className), ...props });
1570
+ }
843
1571
  );
844
1572
  Header.displayName = "Card.Header";
1573
+ var titleFontBySize = {
1574
+ sm: "text-title-md",
1575
+ md: "text-title-lg",
1576
+ lg: "text-headline"
1577
+ };
845
1578
  var Title2 = forwardRef(
846
1579
  ({ className, asChild = false, ...props }, ref) => {
847
1580
  const Comp = asChild ? Slot : "h3";
1581
+ const size = useCardSize();
848
1582
  return /* @__PURE__ */ jsx(
849
1583
  Comp,
850
1584
  {
851
1585
  ref,
852
- className: cn("font-display text-foreground text-title-lg tracking-tight", className),
1586
+ className: cn(
1587
+ "font-display text-foreground tracking-tight",
1588
+ titleFontBySize[size],
1589
+ className
1590
+ ),
853
1591
  ...props
854
1592
  }
855
1593
  );
@@ -860,19 +1598,39 @@ var Description2 = forwardRef(
860
1598
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx("p", { ref, className: cn("text-body-sm text-muted-foreground", className), ...props })
861
1599
  );
862
1600
  Description2.displayName = "Card.Description";
1601
+ var bodyPadBySize = {
1602
+ sm: "p-3 pt-1.5",
1603
+ md: "p-5 pt-2.5",
1604
+ lg: "p-6 pt-3"
1605
+ };
863
1606
  var Body = forwardRef(
864
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("p-6 pt-3", className), ...props })
1607
+ ({ className, ...props }, ref) => {
1608
+ const size = useCardSize();
1609
+ return /* @__PURE__ */ jsx("div", { ref, className: cn(bodyPadBySize[size], className), ...props });
1610
+ }
865
1611
  );
866
1612
  Body.displayName = "Card.Body";
1613
+ var footerPadBySize = {
1614
+ sm: "gap-2 p-3 pt-2",
1615
+ md: "gap-3 p-5 pt-3",
1616
+ lg: "gap-4 p-6 pt-4"
1617
+ };
867
1618
  var Footer = forwardRef(
868
- ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
869
- "div",
870
- {
871
- ref,
872
- className: cn("flex items-center gap-3 border-border/40 border-t p-6 pt-4", className),
873
- ...props
874
- }
875
- )
1619
+ ({ className, ...props }, ref) => {
1620
+ const size = useCardSize();
1621
+ return /* @__PURE__ */ jsx(
1622
+ "div",
1623
+ {
1624
+ ref,
1625
+ className: cn(
1626
+ "flex items-center border-border/40 border-t",
1627
+ footerPadBySize[size],
1628
+ className
1629
+ ),
1630
+ ...props
1631
+ }
1632
+ );
1633
+ }
876
1634
  );
877
1635
  Footer.displayName = "Card.Footer";
878
1636
  var Card = /* @__PURE__ */ Object.assign(Root3, {
@@ -882,25 +1640,30 @@ var Card = /* @__PURE__ */ Object.assign(Root3, {
882
1640
  Body,
883
1641
  Footer
884
1642
  });
1643
+ var inputVariants = cva(
1644
+ [
1645
+ "flex w-full rounded-md border border-input bg-card",
1646
+ "text-foreground placeholder:text-muted-foreground",
1647
+ "transition-[box-shadow,border-color] duration-base ease-out-soft",
1648
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
1649
+ "focus-visible:border-primary",
1650
+ "disabled:cursor-not-allowed disabled:opacity-50",
1651
+ "file:border-0 file:bg-transparent file:font-medium file:text-body-sm"
1652
+ ],
1653
+ {
1654
+ variants: {
1655
+ size: {
1656
+ sm: "h-8 px-2.5 py-1 text-body-sm",
1657
+ // md: density-tunable via CSS var. Comfortable (default) = 36px.
1658
+ md: "h-[var(--theo-control-h,2.25rem)] px-[var(--theo-control-px,0.875rem)] py-1.5 text-body-sm",
1659
+ lg: "h-11 px-4 py-2.5 text-body-md"
1660
+ }
1661
+ },
1662
+ defaultVariants: { size: "md" }
1663
+ }
1664
+ );
885
1665
  var Input = forwardRef(
886
- ({ className, type = "text", ...props }, ref) => /* @__PURE__ */ jsx(
887
- "input",
888
- {
889
- ref,
890
- type,
891
- className: cn(
892
- "flex h-10 w-full rounded-md border border-input bg-card px-3 py-2",
893
- "text-body-md text-foreground placeholder:text-muted-foreground",
894
- "transition-[box-shadow,border-color] duration-base ease-out-soft",
895
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
896
- "focus-visible:border-primary",
897
- "disabled:cursor-not-allowed disabled:opacity-50",
898
- "file:border-0 file:bg-transparent file:font-medium file:text-body-sm",
899
- className
900
- ),
901
- ...props
902
- }
903
- )
1666
+ ({ className, type = "text", size, ...props }, ref) => /* @__PURE__ */ jsx("input", { ref, type, className: cn(inputVariants({ size }), className), ...props })
904
1667
  );
905
1668
  Input.displayName = "Input";
906
1669
  var Overlay2 = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
@@ -1251,30 +2014,47 @@ function useFormField() {
1251
2014
  if (!ctx) throw new Error("FormField subcomponents must be inside <FormField>.");
1252
2015
  return ctx;
1253
2016
  }
2017
+ var rootGapBySize = {
2018
+ sm: "gap-1",
2019
+ md: "gap-1.5",
2020
+ lg: "gap-2"
2021
+ };
1254
2022
  var FormFieldRoot = forwardRef(
1255
- ({ className, id: idProp, invalid, ...props }, ref) => {
2023
+ ({ className, id: idProp, invalid, size = "md", ...props }, ref) => {
1256
2024
  const auto = useId();
1257
2025
  const fieldId = idProp ?? `field-${auto}`;
1258
2026
  const ctx = {
1259
2027
  fieldId,
1260
2028
  hintId: `${fieldId}-hint`,
1261
2029
  errorId: `${fieldId}-error`,
1262
- hasError: !!invalid
2030
+ hasError: !!invalid,
2031
+ size
1263
2032
  };
1264
- return /* @__PURE__ */ jsx(FormFieldContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx("div", { ref, className: cn("grid gap-1.5", className), ...props }) });
2033
+ return /* @__PURE__ */ jsx(FormFieldContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx("div", { ref, className: cn("grid", rootGapBySize[size], className), ...props }) });
1265
2034
  }
1266
2035
  );
1267
2036
  FormFieldRoot.displayName = "FormField";
2037
+ var labelFontBySize = {
2038
+ sm: "text-label-caps",
2039
+ md: "text-body-sm",
2040
+ lg: "text-body-md"
2041
+ };
2042
+ var hintFontBySize = {
2043
+ sm: "text-label-caps",
2044
+ md: "text-body-sm",
2045
+ lg: "text-body-md"
2046
+ };
1268
2047
  var FormFieldLabel = forwardRef(
1269
2048
  ({ className, required, children, ...props }, ref) => {
1270
- const { fieldId } = useFormField();
2049
+ const { fieldId, size } = useFormField();
1271
2050
  return /* @__PURE__ */ jsxs(
1272
2051
  LabelPrimitive.Root,
1273
2052
  {
1274
2053
  ref,
1275
2054
  htmlFor: fieldId,
1276
2055
  className: cn(
1277
- "inline-flex items-center gap-1 font-medium font-sans text-body-sm text-foreground",
2056
+ "inline-flex items-center gap-1 font-medium font-sans text-foreground",
2057
+ labelFontBySize[size],
1278
2058
  "peer-disabled:cursor-not-allowed peer-disabled:opacity-60",
1279
2059
  className
1280
2060
  ),
@@ -1304,14 +2084,14 @@ var FormFieldControl = forwardRef(
1304
2084
  FormFieldControl.displayName = "FormField.Control";
1305
2085
  var FormFieldHint = forwardRef(
1306
2086
  ({ className, children, ...props }, ref) => {
1307
- const { hintId, hasError } = useFormField();
2087
+ const { hintId, hasError, size } = useFormField();
1308
2088
  if (hasError) return null;
1309
2089
  return /* @__PURE__ */ jsx(
1310
2090
  "p",
1311
2091
  {
1312
2092
  ref,
1313
2093
  id: hintId,
1314
- className: cn("text-body-sm text-muted-foreground", className),
2094
+ className: cn("text-muted-foreground", hintFontBySize[size], className),
1315
2095
  ...props,
1316
2096
  children
1317
2097
  }
@@ -1321,7 +2101,7 @@ var FormFieldHint = forwardRef(
1321
2101
  FormFieldHint.displayName = "FormField.Hint";
1322
2102
  var FormFieldError = forwardRef(
1323
2103
  ({ className, children, ...props }, ref) => {
1324
- const { errorId, hasError } = useFormField();
2104
+ const { errorId, hasError, size } = useFormField();
1325
2105
  if (!hasError) return null;
1326
2106
  return /* @__PURE__ */ jsxs(
1327
2107
  "p",
@@ -1329,7 +2109,7 @@ var FormFieldError = forwardRef(
1329
2109
  ref,
1330
2110
  id: errorId,
1331
2111
  role: "alert",
1332
- className: cn("flex items-center gap-1 text-body-sm text-destructive", className),
2112
+ className: cn("flex items-center gap-1 text-destructive", hintFontBySize[size], className),
1333
2113
  ...props,
1334
2114
  children: [
1335
2115
  /* @__PURE__ */ jsx(AlertCircle, { className: "size-3.5 shrink-0", "aria-hidden": "true" }),
@@ -1368,28 +2148,42 @@ var EmptyState = forwardRef(
1368
2148
  )
1369
2149
  );
1370
2150
  EmptyState.displayName = "EmptyState";
1371
- var SelectTrigger = forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
1372
- SelectPrimitive.Trigger,
2151
+ var selectTriggerVariants = cva(
2152
+ [
2153
+ "flex w-full items-center justify-between gap-2 rounded-md border border-input bg-card",
2154
+ "text-foreground placeholder:text-muted-foreground",
2155
+ "transition-[border-color,box-shadow] duration-base ease-out-soft",
2156
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
2157
+ "focus-visible:border-primary",
2158
+ "data-[placeholder]:text-muted-foreground",
2159
+ "disabled:cursor-not-allowed disabled:opacity-50",
2160
+ "[&>span]:line-clamp-1"
2161
+ ],
1373
2162
  {
1374
- ref,
1375
- className: cn(
1376
- "flex h-10 w-full items-center justify-between gap-2 rounded-md border border-input bg-card px-3 py-2",
1377
- "text-body-md text-foreground placeholder:text-muted-foreground",
1378
- "transition-[border-color,box-shadow] duration-base ease-out-soft",
1379
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
1380
- "focus-visible:border-primary",
1381
- "data-[placeholder]:text-muted-foreground",
1382
- "disabled:cursor-not-allowed disabled:opacity-50",
1383
- "[&>span]:line-clamp-1",
1384
- className
1385
- ),
1386
- ...props,
1387
- children: [
1388
- children,
1389
- /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-4 shrink-0 text-muted-foreground", "aria-hidden": "true" }) })
1390
- ]
2163
+ variants: {
2164
+ size: {
2165
+ sm: "h-8 px-2.5 py-1 text-body-sm",
2166
+ md: "h-[var(--theo-control-h,2.25rem)] px-[var(--theo-control-px,0.875rem)] py-1.5 text-body-sm",
2167
+ lg: "h-11 px-4 py-2.5 text-body-md"
2168
+ }
2169
+ },
2170
+ defaultVariants: { size: "md" }
1391
2171
  }
1392
- ));
2172
+ );
2173
+ var SelectTrigger = forwardRef(
2174
+ ({ className, children, size, ...props }, ref) => /* @__PURE__ */ jsxs(
2175
+ SelectPrimitive.Trigger,
2176
+ {
2177
+ ref,
2178
+ className: cn(selectTriggerVariants({ size }), className),
2179
+ ...props,
2180
+ children: [
2181
+ children,
2182
+ /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDown, { className: "size-4 shrink-0 text-muted-foreground", "aria-hidden": "true" }) })
2183
+ ]
2184
+ }
2185
+ )
2186
+ );
1393
2187
  SelectTrigger.displayName = "Select.Trigger";
1394
2188
  var SelectScrollUpButton = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1395
2189
  SelectPrimitive.ScrollUpButton,
@@ -1489,23 +2283,45 @@ Select.Group = SelectPrimitive.Group;
1489
2283
  Select.Label = SelectLabel;
1490
2284
  Select.Item = SelectItem;
1491
2285
  Select.Separator = SelectSeparator;
1492
- var Checkbox = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1493
- CheckboxPrimitive.Root,
2286
+ var checkboxVariants = cva(
2287
+ [
2288
+ "peer relative shrink-0 rounded-sm border border-border bg-card",
2289
+ "transition-[background-color,border-color,box-shadow] duration-base ease-out-soft",
2290
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
2291
+ "data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
2292
+ "data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground",
2293
+ "disabled:cursor-not-allowed disabled:opacity-50"
2294
+ ],
1494
2295
  {
1495
- ref,
1496
- className: cn(
1497
- "peer size-4 shrink-0 rounded-sm border border-border bg-card",
1498
- "transition-[background-color,border-color,box-shadow] duration-base ease-out-soft",
1499
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
1500
- "data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
1501
- "data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground",
1502
- "disabled:cursor-not-allowed disabled:opacity-50",
1503
- className
1504
- ),
1505
- ...props,
1506
- children: /* @__PURE__ */ jsx(CheckboxPrimitive.Indicator, { className: "flex items-center justify-center text-current", children: props.checked === "indeterminate" ? /* @__PURE__ */ jsx(Minus, { className: "size-3.5", "aria-hidden": "true", strokeWidth: 3 }) : /* @__PURE__ */ jsx(Check, { className: "size-3.5", "aria-hidden": "true", strokeWidth: 3 }) })
2296
+ variants: {
2297
+ size: {
2298
+ sm: "size-3.5 before:absolute before:inset-[-5px] before:content-['']",
2299
+ md: "size-4",
2300
+ lg: "size-5"
2301
+ }
2302
+ },
2303
+ defaultVariants: { size: "md" }
1507
2304
  }
1508
- ));
2305
+ );
2306
+ var iconClassBySize = {
2307
+ sm: "size-2.5",
2308
+ md: "size-3.5",
2309
+ lg: "size-3.5"
2310
+ };
2311
+ var Checkbox = forwardRef(
2312
+ ({ className, size, ...props }, ref) => {
2313
+ const iconClass = iconClassBySize[size ?? "md"];
2314
+ return /* @__PURE__ */ jsx(
2315
+ CheckboxPrimitive.Root,
2316
+ {
2317
+ ref,
2318
+ className: cn(checkboxVariants({ size }), className),
2319
+ ...props,
2320
+ children: /* @__PURE__ */ jsx(CheckboxPrimitive.Indicator, { className: "flex items-center justify-center text-current", children: props.checked === "indeterminate" ? /* @__PURE__ */ jsx(Minus, { className: iconClass, "aria-hidden": "true", strokeWidth: 3 }) : /* @__PURE__ */ jsx(Check, { className: iconClass, "aria-hidden": "true", strokeWidth: 3 }) })
2321
+ }
2322
+ );
2323
+ }
2324
+ );
1509
2325
  Checkbox.displayName = "Checkbox";
1510
2326
  var RadioGroupRoot = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(RadioGroupPrimitive.Root, { ref, className: cn("grid gap-3", className), ...props }));
1511
2327
  RadioGroupRoot.displayName = "RadioGroup";
@@ -1529,48 +2345,73 @@ RadioGroupItem.displayName = "RadioGroup.Item";
1529
2345
  var RadioGroup = /* @__PURE__ */ Object.assign(RadioGroupRoot, {
1530
2346
  Item: RadioGroupItem
1531
2347
  });
1532
- var Switch = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1533
- SwitchPrimitive.Root,
2348
+ var switchVariants = cva(
2349
+ [
2350
+ "peer inline-flex shrink-0 cursor-pointer items-center rounded-full border border-transparent",
2351
+ "transition-[background-color,box-shadow] duration-base ease-out-soft",
2352
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
2353
+ "data-[state=checked]:bg-primary data-[state=checked]:shadow-[0_0_8px_hsl(var(--primary)/0.35)]",
2354
+ "data-[state=unchecked]:bg-muted",
2355
+ "disabled:cursor-not-allowed disabled:opacity-50"
2356
+ ],
1534
2357
  {
1535
- ref,
1536
- className: cn(
1537
- "peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border border-transparent",
1538
- "transition-[background-color,box-shadow] duration-base ease-out-soft",
1539
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
1540
- "data-[state=checked]:bg-primary data-[state=checked]:shadow-[0_0_8px_hsl(var(--primary)/0.35)]",
1541
- "data-[state=unchecked]:bg-muted",
1542
- "disabled:cursor-not-allowed disabled:opacity-50",
1543
- className
1544
- ),
1545
- ...props,
1546
- children: /* @__PURE__ */ jsx(
1547
- SwitchPrimitive.Thumb,
1548
- {
1549
- className: cn(
1550
- "pointer-events-none block size-4 rounded-full bg-card shadow-sm",
1551
- "transition-transform duration-base ease-out-soft",
1552
- "data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0.5"
1553
- )
2358
+ variants: {
2359
+ size: {
2360
+ sm: "h-4 w-7",
2361
+ md: "h-5 w-9",
2362
+ lg: "h-6 w-11"
1554
2363
  }
1555
- )
2364
+ },
2365
+ defaultVariants: { size: "md" }
1556
2366
  }
1557
- ));
2367
+ );
2368
+ var thumbClassBySize = {
2369
+ sm: "size-3 data-[state=checked]:translate-x-3 data-[state=unchecked]:translate-x-0.5",
2370
+ md: "size-4 data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0.5",
2371
+ lg: "size-5 data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0.5"
2372
+ };
2373
+ var Switch = forwardRef(
2374
+ ({ className, size, ...props }, ref) => /* @__PURE__ */ jsx(SwitchPrimitive.Root, { ref, className: cn(switchVariants({ size }), className), ...props, children: /* @__PURE__ */ jsx(
2375
+ SwitchPrimitive.Thumb,
2376
+ {
2377
+ className: cn(
2378
+ "pointer-events-none block rounded-full bg-card shadow-sm",
2379
+ "transition-transform duration-base ease-out-soft",
2380
+ thumbClassBySize[size ?? "md"]
2381
+ )
2382
+ }
2383
+ ) })
2384
+ );
1558
2385
  Switch.displayName = "Switch";
2386
+ var textareaVariants = cva(
2387
+ [
2388
+ "flex w-full resize-y rounded-md border border-input bg-card",
2389
+ "text-foreground placeholder:text-muted-foreground",
2390
+ "transition-[box-shadow,border-color] duration-base ease-out-soft",
2391
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
2392
+ "focus-visible:border-primary",
2393
+ "disabled:cursor-not-allowed disabled:opacity-50"
2394
+ ],
2395
+ {
2396
+ variants: {
2397
+ size: {
2398
+ sm: "min-h-[64px] px-2.5 py-1.5 text-body-sm",
2399
+ // md: text scale + padding tighten to body-sm per FAANG density.
2400
+ // min-h stays 96px because multiline has its own height rationale.
2401
+ md: "min-h-[6rem] px-[var(--theo-control-px,0.875rem)] py-1.5 text-body-sm",
2402
+ lg: "min-h-[128px] px-4 py-2.5 text-body-md"
2403
+ }
2404
+ },
2405
+ defaultVariants: { size: "md" }
2406
+ }
2407
+ );
1559
2408
  var Textarea = forwardRef(
1560
- ({ className, rows = 3, ...props }, ref) => /* @__PURE__ */ jsx(
2409
+ ({ className, rows = 3, size, ...props }, ref) => /* @__PURE__ */ jsx(
1561
2410
  "textarea",
1562
2411
  {
1563
2412
  ref,
1564
2413
  rows,
1565
- className: cn(
1566
- "flex min-h-[6rem] w-full resize-y rounded-md border border-input bg-card px-3 py-2",
1567
- "text-body-md text-foreground placeholder:text-muted-foreground",
1568
- "transition-[box-shadow,border-color] duration-base ease-out-soft",
1569
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
1570
- "focus-visible:border-primary",
1571
- "disabled:cursor-not-allowed disabled:opacity-50",
1572
- className
1573
- ),
2414
+ className: cn(textareaVariants({ size }), className),
1574
2415
  ...props
1575
2416
  }
1576
2417
  )
@@ -7741,6 +8582,6 @@ function CommandPalette({
7741
8582
  ] }) });
7742
8583
  }
7743
8584
 
7744
- export { ALL_MODES, AgentComposer, AgentEditor, AgentErrorCard, AgentEvent, AgentHandoff, AgentProfile, AgentStartingState, AgentStream, AgentStreaming, AgentTimeline, ApprovalCard, ArtifactPreview, AttachmentChip, AuditLogEntry, AutoCompactNotice, Avatar, BadgeWithDot as Badge, BrowserControls, BuildLogStream, Button, CapabilityIndicator, Card, ChatComposer, ChatMessage, ChatThread, Checkbox, CommandPalette, ContextCard, ContextWindowBar, CostMeter, CreatedFilesCard, CronJobCard, CronJobsList, DeploymentRow, Dialog, DiffViewer, DomainConfig, EmptyState, EnvVarEditor, FolderContextCard, FolderSelector, FormField, HOOK_EVENTS, HookConfig, HookEventLog, Input, IntentSelector, Label, LaneBoard, LoginSplit, MCPServerCard, MCPServerList, MODE_LABEL, MemoryEditor, MentionMenu, MetricsPanel, ModelCard, ModelSelector, PermissionMatrix, PermissionModal, PreviewEnvCard, PreviewPanel, ProgressChecklist, ProjectCard, ProjectSwitcher, QuickActionChips, RadioGroup, RecentFoldersList, RollbackUI, RuleCard, RuleEditor, RunStats, RunningTasksPanel, ScrollArea, Select, SessionListItem, SessionTimeline, Sheet, Sidebar, Skeleton, SkillCard, SkillEditor, SkillsList, SocialAuthRow, StepsRail, SubAgentDispatch, Switch, SystemPromptEditor, Tabs, TaskHeader, TaskNode, TaskPlan, TerminalPanel, Textarea, ThemeProvider, ThemeScript, ThemeSwitcher, TheoUIProvider, Toast, Toaster, TokenUsageChart, ToolCall, ToolCallCard, ToolResult, ToolsList, TooltipWithStatics as Tooltip, TopNav, auroraTerminal, avatarVariants, badgeVariants, builtinThemes, buttonVariants, capabilityPresets, classicPaper, cn, modelCapabilityPresets, sheetVariants, useTheme, useToast, violetForge };
8585
+ export { ALL_MODES, AgentComposer, AgentEditor, AgentErrorCard, AgentEvent, AgentHandoff, AgentProfile, AgentStartingState, AgentStream, AgentStreaming, AgentTimeline, ApprovalCard, ArtifactPreview, AttachmentChip, AuditLogEntry, AutoCompactNotice, Avatar, BadgeWithDot as Badge, BrowserControls, BuildLogStream, Button, CapabilityIndicator, Card, ChatComposer, ChatMessage, ChatThread, Checkbox, CommandPalette, ContextCard, ContextWindowBar, CostMeter, CreatedFilesCard, CronJobCard, CronJobsList, DeploymentRow, Dialog, DiffViewer, DomainConfig, EmptyState, EnvVarEditor, FolderContextCard, FolderSelector, FormField, HOOK_EVENTS, HookConfig, HookEventLog, Input, IntentSelector, Label, LaneBoard, LoginSplit, MCPServerCard, MCPServerList, MODE_LABEL, MemoryEditor, MentionMenu, MetricsPanel, ModelCard, ModelSelector, PermissionMatrix, PermissionModal, PreviewEnvCard, PreviewPanel, ProgressChecklist, ProjectCard, ProjectSwitcher, QuickActionChips, RadioGroup, RecentFoldersList, RollbackUI, RuleCard, RuleEditor, RunStats, RunningTasksPanel, ScrollArea, Select, SessionListItem, SessionTimeline, Sheet, Sidebar, Skeleton, SkillCard, SkillEditor, SkillsList, SocialAuthRow, StepsRail, SubAgentDispatch, Switch, SystemPromptEditor, Tabs, TaskHeader, TaskNode, TaskPlan, TerminalPanel, Textarea, ThemeProvider, ThemeScript, ThemeSwitcher, TheoUIProvider, Toast, Toaster, TokenUsageChart, ToolCall, ToolCallCard, ToolResult, ToolsList, TooltipWithStatics as Tooltip, TopNav, anthropicStyle, auroraTerminal, avatarVariants, badgeVariants, builtinThemes, buttonVariants, capabilityPresets, classicPaper, cn, defineTheme, dracula, githubDark, hex, linearGlass, modelCapabilityPresets, oneDark, openaiStyle, rgb, sheetVariants, useDensity, useTheme, useToast, vercelMono, violetForge };
7745
8586
  //# sourceMappingURL=index.js.map
7746
8587
  //# sourceMappingURL=index.js.map