@mikenotthepope/substrateui 0.1.1 → 0.1.2

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
@@ -76,6 +76,7 @@ __export(index_exports, {
76
76
  Chart: () => ChartComponent,
77
77
  Checkbox: () => Checkbox,
78
78
  Collapsible: () => CollapsibleComponent,
79
+ ColorThemeToggle: () => ColorThemeToggle,
79
80
  Combobox: () => ComboboxComponent,
80
81
  Command: () => CommandComponent,
81
82
  Container: () => Container,
@@ -3396,30 +3397,58 @@ var React40 = __toESM(require("react"));
3396
3397
  // components/ThemeProvider.tsx
3397
3398
  var import_react9 = require("react");
3398
3399
  var import_jsx_runtime43 = require("react/jsx-runtime");
3400
+ var VALID_THEMES = ["light", "dark", "system"];
3401
+ var COLOR_THEMES = ["blue", "plum", "plum-trio"];
3399
3402
  var ThemeContext = (0, import_react9.createContext)(void 0);
3400
3403
  var STORAGE_KEY = "substrateui-theme";
3404
+ var COLOR_STORAGE_KEY = "substrateui-color-theme";
3401
3405
  function getSystemTheme() {
3402
3406
  if (typeof window === "undefined") return "light";
3403
3407
  return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
3404
3408
  }
3409
+ function readStoredTheme(key, fallback) {
3410
+ if (typeof window === "undefined") return fallback;
3411
+ const stored = localStorage.getItem(key);
3412
+ return VALID_THEMES.includes(stored) ? stored : fallback;
3413
+ }
3414
+ function readStoredColorTheme(key, fallback) {
3415
+ if (typeof window === "undefined") return fallback;
3416
+ const stored = localStorage.getItem(key);
3417
+ return COLOR_THEMES.includes(stored != null ? stored : "") ? stored : fallback;
3418
+ }
3405
3419
  function applyClass(resolved) {
3406
3420
  document.documentElement.classList.remove("light", "dark");
3407
3421
  document.documentElement.classList.add(resolved);
3408
3422
  }
3423
+ function applyColorTheme(colorTheme) {
3424
+ for (const t of COLOR_THEMES) {
3425
+ document.documentElement.classList.remove(`theme-${t}`);
3426
+ }
3427
+ if (colorTheme !== "blue") {
3428
+ document.documentElement.classList.add(`theme-${colorTheme}`);
3429
+ }
3430
+ }
3409
3431
  function ThemeProvider({
3410
3432
  children,
3411
3433
  defaultTheme = "system",
3412
- storageKey = STORAGE_KEY
3434
+ defaultColorTheme = "blue",
3435
+ storageKey = STORAGE_KEY,
3436
+ colorStorageKey = COLOR_STORAGE_KEY
3413
3437
  }) {
3414
- const [theme, setThemeState] = (0, import_react9.useState)(() => {
3415
- if (typeof window === "undefined") return defaultTheme;
3416
- return localStorage.getItem(storageKey) || defaultTheme;
3417
- });
3438
+ const [theme, setThemeState] = (0, import_react9.useState)(
3439
+ () => readStoredTheme(storageKey, defaultTheme)
3440
+ );
3441
+ const [colorTheme, setColorThemeState] = (0, import_react9.useState)(
3442
+ () => readStoredColorTheme(colorStorageKey, defaultColorTheme)
3443
+ );
3418
3444
  const [systemTheme, setSystemTheme] = (0, import_react9.useState)(getSystemTheme);
3419
3445
  const resolvedTheme = theme === "system" ? systemTheme : theme;
3420
3446
  (0, import_react9.useEffect)(() => {
3421
3447
  applyClass(resolvedTheme);
3422
3448
  }, [resolvedTheme]);
3449
+ (0, import_react9.useEffect)(() => {
3450
+ applyColorTheme(colorTheme);
3451
+ }, [colorTheme]);
3423
3452
  (0, import_react9.useEffect)(() => {
3424
3453
  const mq = window.matchMedia("(prefers-color-scheme: dark)");
3425
3454
  const handler = (e) => {
@@ -3428,6 +3457,23 @@ function ThemeProvider({
3428
3457
  mq.addEventListener("change", handler);
3429
3458
  return () => mq.removeEventListener("change", handler);
3430
3459
  }, []);
3460
+ (0, import_react9.useEffect)(() => {
3461
+ const handler = (e) => {
3462
+ var _a;
3463
+ if (e.key === storageKey) {
3464
+ setThemeState(
3465
+ VALID_THEMES.includes(e.newValue) ? e.newValue : defaultTheme
3466
+ );
3467
+ }
3468
+ if (e.key === colorStorageKey) {
3469
+ setColorThemeState(
3470
+ COLOR_THEMES.includes((_a = e.newValue) != null ? _a : "") ? e.newValue : defaultColorTheme
3471
+ );
3472
+ }
3473
+ };
3474
+ window.addEventListener("storage", handler);
3475
+ return () => window.removeEventListener("storage", handler);
3476
+ }, [storageKey, colorStorageKey, defaultTheme, defaultColorTheme]);
3431
3477
  const setTheme = (0, import_react9.useCallback)(
3432
3478
  (newTheme) => {
3433
3479
  localStorage.setItem(storageKey, newTheme);
@@ -3435,9 +3481,16 @@ function ThemeProvider({
3435
3481
  },
3436
3482
  [storageKey]
3437
3483
  );
3484
+ const setColorTheme = (0, import_react9.useCallback)(
3485
+ (newColorTheme) => {
3486
+ localStorage.setItem(colorStorageKey, newColorTheme);
3487
+ setColorThemeState(newColorTheme);
3488
+ },
3489
+ [colorStorageKey]
3490
+ );
3438
3491
  const value = (0, import_react9.useMemo)(
3439
- () => ({ theme, resolvedTheme, setTheme }),
3440
- [theme, resolvedTheme, setTheme]
3492
+ () => ({ theme, resolvedTheme, setTheme, colorTheme, setColorTheme, colorThemes: COLOR_THEMES }),
3493
+ [theme, resolvedTheme, setTheme, colorTheme, setColorTheme]
3441
3494
  );
3442
3495
  return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(ThemeContext.Provider, { value, children });
3443
3496
  }
@@ -5949,6 +6002,83 @@ function ThemeToggle(_a) {
5949
6002
  );
5950
6003
  }
5951
6004
 
6005
+ // components/ColorThemeToggle.tsx
6006
+ var import_react15 = require("react");
6007
+ var import_jsx_runtime65 = require("react/jsx-runtime");
6008
+ var subscribe2 = () => () => {
6009
+ };
6010
+ var getSnapshot2 = () => true;
6011
+ var getServerSnapshot2 = () => false;
6012
+ var COLOR_SWATCHES = {
6013
+ blue: "#5294FF",
6014
+ plum: "#B254CF",
6015
+ "plum-trio": "#B254CF"
6016
+ };
6017
+ var COLOR_LABELS = {
6018
+ blue: "Blue",
6019
+ plum: "Plum",
6020
+ "plum-trio": "Plum Trio"
6021
+ };
6022
+ function ColorThemeToggle(_a) {
6023
+ var _b = _a, {
6024
+ variant = "ghost",
6025
+ size = "md",
6026
+ className
6027
+ } = _b, props = __objRest(_b, [
6028
+ "variant",
6029
+ "size",
6030
+ "className"
6031
+ ]);
6032
+ const { colorTheme, setColorTheme, colorThemes } = useTheme();
6033
+ const mounted = (0, import_react15.useSyncExternalStore)(subscribe2, getSnapshot2, getServerSnapshot2);
6034
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(DropdownMenuComponent, { children: [
6035
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(DropdownMenuComponent.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
6036
+ IconButton,
6037
+ __spreadProps(__spreadValues({
6038
+ variant,
6039
+ size,
6040
+ className,
6041
+ "aria-label": mounted ? `Color theme: ${colorTheme}` : "Color theme"
6042
+ }, props), {
6043
+ children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
6044
+ "span",
6045
+ {
6046
+ className: "block w-4 h-4 border-2 border-border",
6047
+ style: {
6048
+ backgroundColor: mounted ? COLOR_SWATCHES[colorTheme] : void 0,
6049
+ borderRadius: "var(--radius, 0)"
6050
+ }
6051
+ }
6052
+ )
6053
+ })
6054
+ ) }),
6055
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(DropdownMenuComponent.Content, { align: "end", children: [
6056
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(DropdownMenuComponent.Label, { children: "Color Theme" }),
6057
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(DropdownMenuComponent.Separator, {}),
6058
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
6059
+ DropdownMenuComponent.RadioGroup,
6060
+ {
6061
+ value: colorTheme,
6062
+ onValueChange: (v) => setColorTheme(v),
6063
+ children: colorThemes.map((theme) => /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(DropdownMenuComponent.RadioItem, { value: theme, children: [
6064
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
6065
+ "span",
6066
+ {
6067
+ className: "inline-block w-3 h-3 border border-border mr-1",
6068
+ style: {
6069
+ backgroundColor: COLOR_SWATCHES[theme],
6070
+ borderRadius: "var(--radius, 0)"
6071
+ }
6072
+ }
6073
+ ),
6074
+ COLOR_LABELS[theme]
6075
+ ] }, theme))
6076
+ }
6077
+ )
6078
+ ] })
6079
+ ] });
6080
+ }
6081
+
5952
6082
  // lib/create-theme.ts
5953
6083
  function createTheme(name, config) {
5954
6084
  const declarations = [];
@@ -5989,7 +6119,7 @@ ${declarations.join("\n")}
5989
6119
  }
5990
6120
 
5991
6121
  // components/landing/Hero.tsx
5992
- var import_jsx_runtime65 = require("react/jsx-runtime");
6122
+ var import_jsx_runtime66 = require("react/jsx-runtime");
5993
6123
  function Hero({
5994
6124
  badge,
5995
6125
  title,
@@ -5999,14 +6129,14 @@ function Hero({
5999
6129
  className,
6000
6130
  align = "center"
6001
6131
  }) {
6002
- return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
6132
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
6003
6133
  "section",
6004
6134
  {
6005
6135
  className: cn(
6006
6136
  "w-full border-b-2 bg-background",
6007
6137
  className
6008
6138
  ),
6009
- children: /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(
6139
+ children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
6010
6140
  "div",
6011
6141
  {
6012
6142
  className: cn(
@@ -6015,10 +6145,10 @@ function Hero({
6015
6145
  align === "left" && "items-start text-left"
6016
6146
  ),
6017
6147
  children: [
6018
- badge && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { children: badge }),
6019
- /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("h1", { className: "font-head text-4xl sm:text-5xl lg:text-6xl max-w-4xl", children: title }),
6020
- subtitle && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("p", { className: "font-sans text-lg lg:text-xl text-muted-foreground max-w-2xl", children: subtitle }),
6021
- actions && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { className: "flex flex-wrap gap-3 mt-2", children: actions }),
6148
+ badge && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { children: badge }),
6149
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("h1", { className: "font-head text-4xl sm:text-5xl lg:text-6xl max-w-4xl", children: title }),
6150
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("p", { className: "font-sans text-lg lg:text-xl text-muted-foreground max-w-2xl", children: subtitle }),
6151
+ actions && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "flex flex-wrap gap-3 mt-2", children: actions }),
6022
6152
  children
6023
6153
  ]
6024
6154
  }
@@ -6029,7 +6159,7 @@ function Hero({
6029
6159
 
6030
6160
  // components/landing/Section.tsx
6031
6161
  var import_class_variance_authority20 = require("class-variance-authority");
6032
- var import_jsx_runtime66 = require("react/jsx-runtime");
6162
+ var import_jsx_runtime67 = require("react/jsx-runtime");
6033
6163
  var sectionVariants = (0, import_class_variance_authority20.cva)("w-full py-16 lg:py-24 scroll-mt-[120px]", {
6034
6164
  variants: {
6035
6165
  background: {
@@ -6059,13 +6189,13 @@ function Section(_a) {
6059
6189
  "background",
6060
6190
  "align"
6061
6191
  ]);
6062
- return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
6192
+ return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
6063
6193
  "section",
6064
6194
  __spreadProps(__spreadValues({
6065
6195
  className: cn(sectionVariants({ background }), className)
6066
6196
  }, props), {
6067
- children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: "mx-auto max-w-6xl px-4", children: [
6068
- (title || subtitle) && /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
6197
+ children: /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "mx-auto max-w-6xl px-4", children: [
6198
+ (title || subtitle) && /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(
6069
6199
  "div",
6070
6200
  {
6071
6201
  className: cn(
@@ -6074,8 +6204,8 @@ function Section(_a) {
6074
6204
  align === "left" && "text-left"
6075
6205
  ),
6076
6206
  children: [
6077
- title && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("h2", { className: "font-head text-3xl lg:text-4xl mb-3", children: title }),
6078
- subtitle && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("p", { className: "font-sans text-lg text-muted-foreground max-w-2xl mx-auto", children: subtitle })
6207
+ title && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("h2", { className: "font-head text-3xl lg:text-4xl mb-3", children: title }),
6208
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("p", { className: "font-sans text-lg text-muted-foreground max-w-2xl mx-auto", children: subtitle })
6079
6209
  ]
6080
6210
  }
6081
6211
  ),
@@ -6086,7 +6216,7 @@ function Section(_a) {
6086
6216
  }
6087
6217
 
6088
6218
  // components/landing/Footer.tsx
6089
- var import_jsx_runtime67 = require("react/jsx-runtime");
6219
+ var import_jsx_runtime68 = require("react/jsx-runtime");
6090
6220
  function Footer({
6091
6221
  brand,
6092
6222
  tagline,
@@ -6094,15 +6224,15 @@ function Footer({
6094
6224
  bottom,
6095
6225
  className
6096
6226
  }) {
6097
- return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("footer", { className: cn("w-full border-t-2 bg-background", className), children: /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "mx-auto max-w-6xl px-4 py-12 lg:py-16", children: [
6098
- /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "grid gap-8 lg:grid-cols-[1.5fr_repeat(auto-fit,1fr)]", children: [
6099
- /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "max-w-xs", children: [
6100
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { className: "font-head text-2xl mb-2", children: brand }),
6101
- tagline && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("p", { className: "font-sans text-sm text-muted-foreground", children: tagline })
6227
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("footer", { className: cn("w-full border-t-2 bg-background", className), children: /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "mx-auto max-w-6xl px-4 py-12 lg:py-16", children: [
6228
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "grid gap-8 lg:grid-cols-[1.5fr_repeat(auto-fit,1fr)]", children: [
6229
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "max-w-xs", children: [
6230
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "font-head text-2xl mb-2", children: brand }),
6231
+ tagline && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("p", { className: "font-sans text-sm text-muted-foreground", children: tagline })
6102
6232
  ] }),
6103
- groups.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { className: "grid gap-8 sm:grid-cols-2 lg:grid-cols-3 col-span-full lg:col-span-1", children: groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { children: [
6104
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("h4", { className: "font-head text-sm uppercase mb-3", children: group.title }),
6105
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("ul", { className: "flex flex-col gap-2", children: group.links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
6233
+ groups.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "grid gap-8 sm:grid-cols-2 lg:grid-cols-3 col-span-full lg:col-span-1", children: groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { children: [
6234
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("h4", { className: "font-head text-sm uppercase mb-3", children: group.title }),
6235
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("ul", { className: "flex flex-col gap-2", children: group.links.map((link) => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6106
6236
  "a",
6107
6237
  {
6108
6238
  href: link.href,
@@ -6112,21 +6242,21 @@ function Footer({
6112
6242
  ) }, link.label)) })
6113
6243
  ] }, group.title)) })
6114
6244
  ] }),
6115
- bottom && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("div", { className: "mt-12 pt-6 border-t-2 font-sans text-sm text-muted-foreground", children: bottom })
6245
+ bottom && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "mt-12 pt-6 border-t-2 font-sans text-sm text-muted-foreground", children: bottom })
6116
6246
  ] }) });
6117
6247
  }
6118
6248
 
6119
6249
  // components/landing/PricingTable.tsx
6120
- var import_jsx_runtime68 = require("react/jsx-runtime");
6250
+ var import_jsx_runtime69 = require("react/jsx-runtime");
6121
6251
  function PricingTable({ tiers, className }) {
6122
- return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6252
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
6123
6253
  "div",
6124
6254
  {
6125
6255
  className: cn(
6126
6256
  "grid gap-6 sm:grid-cols-2 lg:grid-cols-3",
6127
6257
  className
6128
6258
  ),
6129
- children: tiers.map((tier) => /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
6259
+ children: tiers.map((tier) => /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
6130
6260
  "div",
6131
6261
  {
6132
6262
  className: cn(
@@ -6134,15 +6264,15 @@ function PricingTable({ tiers, className }) {
6134
6264
  tier.highlighted ? "shadow-lg border-primary ring-2 ring-primary scale-[1.02]" : "shadow-md"
6135
6265
  ),
6136
6266
  children: [
6137
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "p-6 border-b-2", children: [
6138
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
6139
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("h3", { className: "font-head text-xl", children: tier.name }),
6267
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "p-6 border-b-2", children: [
6268
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "flex items-center justify-between mb-2", children: [
6269
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("h3", { className: "font-head text-xl", children: tier.name }),
6140
6270
  tier.badge
6141
6271
  ] }),
6142
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "font-head text-4xl mb-1", children: tier.price }),
6143
- tier.description && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("p", { className: "font-sans text-sm text-muted-foreground", children: tier.description })
6272
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "font-head text-4xl mb-1", children: tier.price }),
6273
+ tier.description && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("p", { className: "font-sans text-sm text-muted-foreground", children: tier.description })
6144
6274
  ] }),
6145
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "p-6 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("ul", { className: "flex flex-col gap-3", children: tier.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
6275
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "p-6 flex-1", children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("ul", { className: "flex flex-col gap-3", children: tier.features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
6146
6276
  "li",
6147
6277
  {
6148
6278
  className: cn(
@@ -6150,7 +6280,7 @@ function PricingTable({ tiers, className }) {
6150
6280
  !feature.included && "text-muted-foreground line-through"
6151
6281
  ),
6152
6282
  children: [
6153
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
6283
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
6154
6284
  "span",
6155
6285
  {
6156
6286
  className: cn(
@@ -6165,7 +6295,7 @@ function PricingTable({ tiers, className }) {
6165
6295
  },
6166
6296
  feature.text
6167
6297
  )) }) }),
6168
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "p-6 border-t-2", children: tier.cta })
6298
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "p-6 border-t-2", children: tier.cta })
6169
6299
  ]
6170
6300
  },
6171
6301
  tier.name
@@ -6175,7 +6305,7 @@ function PricingTable({ tiers, className }) {
6175
6305
  }
6176
6306
 
6177
6307
  // components/landing/FeatureSection.tsx
6178
- var import_jsx_runtime69 = require("react/jsx-runtime");
6308
+ var import_jsx_runtime70 = require("react/jsx-runtime");
6179
6309
  var columnClasses2 = {
6180
6310
  2: "grid gap-6 sm:grid-cols-2",
6181
6311
  3: "grid gap-6 sm:grid-cols-2 lg:grid-cols-3",
@@ -6186,14 +6316,14 @@ function FeatureSection({
6186
6316
  columns = 3,
6187
6317
  className
6188
6318
  }) {
6189
- return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: cn(columnClasses2[columns], className), children: features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
6319
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: cn(columnClasses2[columns], className), children: features.map((feature) => /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(
6190
6320
  "div",
6191
6321
  {
6192
6322
  className: "border-2 p-6 bg-card shadow-md",
6193
6323
  children: [
6194
- feature.icon && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "mb-4 inline-flex items-center justify-center h-12 w-12 border-2 bg-primary text-primary-foreground shadow-sm", children: feature.icon }),
6195
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("h3", { className: "font-head text-lg mb-2", children: feature.title }),
6196
- /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("p", { className: "font-sans text-sm text-muted-foreground", children: feature.description })
6324
+ feature.icon && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "mb-4 inline-flex items-center justify-center h-12 w-12 border-2 bg-primary text-primary-foreground shadow-sm", children: feature.icon }),
6325
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("h3", { className: "font-head text-lg mb-2", children: feature.title }),
6326
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("p", { className: "font-sans text-sm text-muted-foreground", children: feature.description })
6197
6327
  ]
6198
6328
  },
6199
6329
  feature.title
@@ -6201,7 +6331,7 @@ function FeatureSection({
6201
6331
  }
6202
6332
 
6203
6333
  // components/landing/Testimonial.tsx
6204
- var import_jsx_runtime70 = require("react/jsx-runtime");
6334
+ var import_jsx_runtime71 = require("react/jsx-runtime");
6205
6335
  var columnClasses3 = {
6206
6336
  1: "grid gap-6 max-w-2xl mx-auto",
6207
6337
  2: "grid gap-6 sm:grid-cols-2",
@@ -6212,21 +6342,21 @@ function Testimonial({
6212
6342
  columns = 3,
6213
6343
  className
6214
6344
  }) {
6215
- return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: cn(columnClasses3[columns], className), children: testimonials.map((t) => /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(
6345
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: cn(columnClasses3[columns], className), children: testimonials.map((t) => /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)(
6216
6346
  "div",
6217
6347
  {
6218
6348
  className: "border-2 p-6 bg-card shadow-md flex flex-col",
6219
6349
  children: [
6220
- /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("blockquote", { className: "font-sans text-sm leading-relaxed flex-1 mb-6", children: [
6350
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("blockquote", { className: "font-sans text-sm leading-relaxed flex-1 mb-6", children: [
6221
6351
  "\u201C",
6222
6352
  t.quote,
6223
6353
  "\u201D"
6224
6354
  ] }),
6225
- /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "flex items-center gap-3 border-t-2 pt-4", children: [
6226
- t.avatar && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "h-10 w-10 shrink-0 border-2 overflow-hidden", children: t.avatar }),
6227
- /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { children: [
6228
- /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("p", { className: "font-head text-sm", children: t.name }),
6229
- (t.role || t.company) && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("p", { className: "font-sans text-xs text-muted-foreground", children: [t.role, t.company].filter(Boolean).join(", ") })
6355
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "flex items-center gap-3 border-t-2 pt-4", children: [
6356
+ t.avatar && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "h-10 w-10 shrink-0 border-2 overflow-hidden", children: t.avatar }),
6357
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { children: [
6358
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("p", { className: "font-head text-sm", children: t.name }),
6359
+ (t.role || t.company) && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("p", { className: "font-sans text-xs text-muted-foreground", children: [t.role, t.company].filter(Boolean).join(", ") })
6230
6360
  ] })
6231
6361
  ] })
6232
6362
  ]
@@ -6236,9 +6366,9 @@ function Testimonial({
6236
6366
  }
6237
6367
 
6238
6368
  // components/landing/LogoCloud.tsx
6239
- var import_jsx_runtime71 = require("react/jsx-runtime");
6369
+ var import_jsx_runtime72 = require("react/jsx-runtime");
6240
6370
  function LogoCloud({ children, className }) {
6241
- return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(
6371
+ return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
6242
6372
  "div",
6243
6373
  {
6244
6374
  className: cn(
@@ -6251,24 +6381,24 @@ function LogoCloud({ children, className }) {
6251
6381
  }
6252
6382
 
6253
6383
  // components/landing/CTABanner.tsx
6254
- var import_jsx_runtime72 = require("react/jsx-runtime");
6384
+ var import_jsx_runtime73 = require("react/jsx-runtime");
6255
6385
  function CTABanner({
6256
6386
  title,
6257
6387
  subtitle,
6258
6388
  actions,
6259
6389
  className
6260
6390
  }) {
6261
- return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)(
6391
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
6262
6392
  "section",
6263
6393
  {
6264
6394
  className: cn(
6265
6395
  "w-full border-y-2 bg-primary text-primary-foreground",
6266
6396
  className
6267
6397
  ),
6268
- children: /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { className: "mx-auto max-w-6xl px-4 py-16 lg:py-20 flex flex-col items-center text-center gap-4", children: [
6269
- /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("h2", { className: "font-head text-3xl lg:text-4xl", children: title }),
6270
- subtitle && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("p", { className: "font-sans text-lg max-w-xl", children: subtitle }),
6271
- actions && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "flex flex-wrap gap-3 mt-2", children: actions })
6398
+ children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "mx-auto max-w-6xl px-4 py-16 lg:py-20 flex flex-col items-center text-center gap-4", children: [
6399
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("h2", { className: "font-head text-3xl lg:text-4xl", children: title }),
6400
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("p", { className: "font-sans text-lg max-w-xl", children: subtitle }),
6401
+ actions && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "flex flex-wrap gap-3 mt-2", children: actions })
6272
6402
  ] })
6273
6403
  }
6274
6404
  );
@@ -6277,20 +6407,20 @@ function CTABanner({
6277
6407
  // components/landing/FAQ.tsx
6278
6408
  var React60 = __toESM(require("react"));
6279
6409
  var import_lucide_react23 = require("lucide-react");
6280
- var import_jsx_runtime73 = require("react/jsx-runtime");
6410
+ var import_jsx_runtime74 = require("react/jsx-runtime");
6281
6411
  function FAQ({ items, className }) {
6282
6412
  const [openIndex, setOpenIndex] = React60.useState(null);
6283
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: cn("w-full max-w-3xl mx-auto", className), children: items.map((item, i) => {
6413
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: cn("w-full max-w-3xl mx-auto", className), children: items.map((item, i) => {
6284
6414
  const isOpen = openIndex === i;
6285
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "border-2 border-b-0 last:border-b-2", children: [
6286
- /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
6415
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "border-2 border-b-0 last:border-b-2", children: [
6416
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(
6287
6417
  "button",
6288
6418
  {
6289
6419
  onClick: () => setOpenIndex(isOpen ? null : i),
6290
6420
  className: "w-full flex items-center justify-between p-4 text-left cursor-pointer hover:bg-accent/30 transition-colors",
6291
6421
  children: [
6292
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "font-head text-sm pr-4", children: item.question }),
6293
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
6422
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { className: "font-head text-sm pr-4", children: item.question }),
6423
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
6294
6424
  import_lucide_react23.ChevronDown,
6295
6425
  {
6296
6426
  className: cn(
@@ -6302,24 +6432,24 @@ function FAQ({ items, className }) {
6302
6432
  ]
6303
6433
  }
6304
6434
  ),
6305
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "px-4 pb-4 font-sans text-sm text-muted-foreground", children: item.answer })
6435
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "px-4 pb-4 font-sans text-sm text-muted-foreground", children: item.answer })
6306
6436
  ] }, i);
6307
6437
  }) });
6308
6438
  }
6309
6439
 
6310
6440
  // components/landing/StatsBar.tsx
6311
- var import_jsx_runtime74 = require("react/jsx-runtime");
6441
+ var import_jsx_runtime75 = require("react/jsx-runtime");
6312
6442
  function StatsBar({ stats, className }) {
6313
- return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
6443
+ return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
6314
6444
  "div",
6315
6445
  {
6316
6446
  className: cn(
6317
6447
  "w-full border-y-2 bg-card",
6318
6448
  className
6319
6449
  ),
6320
- children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "mx-auto max-w-6xl px-4 py-10 grid grid-cols-2 lg:grid-cols-4 gap-8", children: stats.map((stat) => /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "text-center", children: [
6321
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "font-head text-3xl lg:text-4xl mb-1", children: stat.value }),
6322
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "font-sans text-sm text-muted-foreground uppercase", children: stat.label })
6450
+ children: /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: "mx-auto max-w-6xl px-4 py-10 grid grid-cols-2 lg:grid-cols-4 gap-8", children: stats.map((stat) => /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "text-center", children: [
6451
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: "font-head text-3xl lg:text-4xl mb-1", children: stat.value }),
6452
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("div", { className: "font-sans text-sm text-muted-foreground uppercase", children: stat.label })
6323
6453
  ] }, stat.label)) })
6324
6454
  }
6325
6455
  );
@@ -6328,37 +6458,39 @@ function StatsBar({ stats, className }) {
6328
6458
  // components/landing/AnnouncementBanner.tsx
6329
6459
  var React61 = __toESM(require("react"));
6330
6460
  var import_lucide_react24 = require("lucide-react");
6331
- var import_jsx_runtime75 = require("react/jsx-runtime");
6461
+ var import_jsx_runtime76 = require("react/jsx-runtime");
6332
6462
  function AnnouncementBanner({
6333
6463
  children,
6334
6464
  dismissible = true,
6335
6465
  className
6336
6466
  }) {
6337
- const [visible, setVisible] = React61.useState(() => {
6338
- if (typeof window === "undefined") return true;
6339
- return sessionStorage.getItem("announcement-dismissed") !== "true";
6340
- });
6467
+ const [visible, setVisible] = React61.useState(true);
6468
+ React61.useEffect(() => {
6469
+ if (sessionStorage.getItem("announcement-dismissed") === "true") {
6470
+ setVisible(false);
6471
+ }
6472
+ }, []);
6341
6473
  const handleDismiss = () => {
6342
6474
  setVisible(false);
6343
6475
  sessionStorage.setItem("announcement-dismissed", "true");
6344
6476
  };
6345
6477
  if (!visible) return null;
6346
- return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
6478
+ return /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
6347
6479
  "div",
6348
6480
  {
6349
6481
  className: cn(
6350
6482
  "w-full bg-primary text-primary-foreground border-b-2",
6351
6483
  className
6352
6484
  ),
6353
- children: /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "mx-auto max-w-6xl px-4 py-2 flex items-center justify-center gap-3", children: [
6354
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("p", { className: "font-sans text-sm text-center flex-1", children }),
6355
- dismissible && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
6485
+ children: /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "mx-auto max-w-6xl px-4 py-2 flex items-center justify-center gap-3", children: [
6486
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("p", { className: "font-sans text-sm text-center flex-1", children }),
6487
+ dismissible && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
6356
6488
  "button",
6357
6489
  {
6358
6490
  onClick: handleDismiss,
6359
6491
  className: "shrink-0 p-2 min-w-[44px] min-h-[44px] inline-flex items-center justify-center hover:bg-foreground/10 transition-colors cursor-pointer",
6360
6492
  "aria-label": "Dismiss",
6361
- children: /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(import_lucide_react24.X, { className: "h-4 w-4" })
6493
+ children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(import_lucide_react24.X, { className: "h-4 w-4" })
6362
6494
  }
6363
6495
  )
6364
6496
  ] })
@@ -6367,7 +6499,7 @@ function AnnouncementBanner({
6367
6499
  }
6368
6500
 
6369
6501
  // components/landing/NewsletterSignup.tsx
6370
- var import_jsx_runtime76 = require("react/jsx-runtime");
6502
+ var import_jsx_runtime77 = require("react/jsx-runtime");
6371
6503
  function NewsletterSignup({
6372
6504
  title = "Stay in the loop",
6373
6505
  subtitle,
@@ -6375,16 +6507,16 @@ function NewsletterSignup({
6375
6507
  buttonLabel = "Subscribe",
6376
6508
  className
6377
6509
  }) {
6378
- return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: cn("w-full max-w-md mx-auto", className), children: [
6379
- title && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("h3", { className: "font-head text-xl mb-2 text-center", children: title }),
6380
- subtitle && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("p", { className: "font-sans text-sm text-muted-foreground text-center mb-4", children: subtitle }),
6381
- /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
6510
+ return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: cn("w-full max-w-md mx-auto", className), children: [
6511
+ title && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("h3", { className: "font-head text-xl mb-2 text-center", children: title }),
6512
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("p", { className: "font-sans text-sm text-muted-foreground text-center mb-4", children: subtitle }),
6513
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(
6382
6514
  "form",
6383
6515
  {
6384
6516
  onSubmit: (e) => e.preventDefault(),
6385
6517
  className: "flex gap-2",
6386
6518
  children: [
6387
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
6519
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
6388
6520
  "input",
6389
6521
  {
6390
6522
  type: "email",
@@ -6393,7 +6525,7 @@ function NewsletterSignup({
6393
6525
  required: true
6394
6526
  }
6395
6527
  ),
6396
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
6528
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
6397
6529
  "button",
6398
6530
  {
6399
6531
  type: "submit",
@@ -6424,6 +6556,7 @@ function NewsletterSignup({
6424
6556
  Chart,
6425
6557
  Checkbox,
6426
6558
  Collapsible,
6559
+ ColorThemeToggle,
6427
6560
  Combobox,
6428
6561
  Command,
6429
6562
  Container,