@doneisbetter/gds-core 3.0.2 → 3.0.3

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.
@@ -123,6 +123,7 @@ function ThemeToggle({ size = "md", onColorSchemeChange }) {
123
123
  import { useEffect as useEffect2, useMemo, useState as useState2 } from "react";
124
124
  import {
125
125
  Badge,
126
+ Box,
126
127
  Button as Button2,
127
128
  Checkbox,
128
129
  Code,
@@ -140,6 +141,7 @@ import {
140
141
  applyGdsFontLane,
141
142
  getGdsFontLanes,
142
143
  getGdsThemePresets,
144
+ getGdsVibeThemes,
143
145
  resolveGdsThemePreset
144
146
  } from "@doneisbetter/gds-theme";
145
147
  import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
@@ -150,6 +152,8 @@ function resolvePreviewColorScheme(presetId, requestedScheme) {
150
152
  return requestedScheme;
151
153
  }
152
154
  var presetCatalog = getGdsThemePresets();
155
+ var vibeCatalog = getGdsVibeThemes();
156
+ var vibeCatalogById = Object.fromEntries(vibeCatalog.map((vibe) => [vibe.id, vibe]));
153
157
  var themePresetCatalog = Object.fromEntries(
154
158
  presetCatalog.map((preset) => [
155
159
  preset.id,
@@ -269,6 +273,7 @@ function ReferenceThemeExplorer({
269
273
  const effectiveComparisonScheme = resolvePreviewColorScheme(comparisonPreset, colorScheme);
270
274
  const previewKey = `${preset}-${effectiveColorScheme}-${brandPrimary}-${brandFlatSurfaces}-${brandEditorialSerif}-${fontLane}`;
271
275
  const comparisonPreviewKey = `${comparisonPreset}-${effectiveComparisonScheme}-${brandPrimary}-${brandFlatSurfaces}-${brandEditorialSerif}-${fontLane}`;
276
+ const selectedVibe = vibeCatalogById[preset];
272
277
  useEffect2(() => {
273
278
  onSelectionChange?.({
274
279
  preset,
@@ -421,22 +426,113 @@ function ReferenceThemeExplorer({
421
426
  ReferenceSection,
422
427
  {
423
428
  title: "Shipped theme lanes",
424
- description: "Every lane below is part of the supported system. The website uses these exact helpers as its live runtime proof.",
425
- children: /* @__PURE__ */ jsx4(SimpleGrid, { cols: { base: 1, md: 2, xl: 5 }, spacing: "md", children: Object.values(themePresetCatalog).map((lane) => /* @__PURE__ */ jsx4(Paper, { withBorder: true, radius: "lg", p: "md", children: /* @__PURE__ */ jsxs2(Stack, { gap: 6, children: [
426
- /* @__PURE__ */ jsx4(Text2, { fw: 700, size: "sm", children: lane.label }),
427
- /* @__PURE__ */ jsx4(Text2, { size: "sm", c: "dimmed", children: lane.summary }),
428
- /* @__PURE__ */ jsxs2(Text2, { size: "xs", children: [
429
- /* @__PURE__ */ jsx4("strong", { children: "Best for:" }),
430
- " ",
431
- lane.supportedUse
432
- ] }),
433
- /* @__PURE__ */ jsx4(Code, { block: true, fz: "10px", children: lane.themeKey }),
434
- /* @__PURE__ */ jsxs2(Text2, { size: "xs", c: "dimmed", children: [
435
- /* @__PURE__ */ jsx4("strong", { children: "Avoid for:" }),
436
- " ",
437
- lane.avoidFor ?? "No special exclusion noted for this lane."
438
- ] })
439
- ] }) }, lane.themeKey)) })
429
+ description: "Every lane below is a supported runtime preset. Colourful lanes ship as full CSS-based VibeThemes: canvas, shell, surface, control, focus, and accent tokens, not bitmap backgrounds.",
430
+ children: /* @__PURE__ */ jsx4(SimpleGrid, { cols: { base: 1, md: 2, xl: 4 }, spacing: "md", children: vibeCatalog.map((vibe) => {
431
+ const lane = themePresetCatalog[vibe.id];
432
+ const isSelected = vibe.id === preset;
433
+ return /* @__PURE__ */ jsx4(
434
+ Paper,
435
+ {
436
+ withBorder: true,
437
+ radius: "lg",
438
+ p: "md",
439
+ role: "group",
440
+ "aria-label": `${lane.label} vibe theme`,
441
+ style: {
442
+ background: `linear-gradient(135deg, ${vibe.surfaceLight}, color-mix(in srgb, ${vibe.primary} 12%, ${vibe.surfaceLight})), ${vibe.gradient}`,
443
+ borderColor: isSelected ? vibe.primary : vibe.borderLight,
444
+ boxShadow: isSelected ? `0 0 0 2px ${vibe.primary}, 0 18px 46px ${vibe.glow}` : void 0
445
+ },
446
+ children: /* @__PURE__ */ jsxs2(Stack, { gap: 6, children: [
447
+ /* @__PURE__ */ jsxs2(Group2, { gap: "xs", justify: "space-between", align: "flex-start", wrap: "nowrap", children: [
448
+ /* @__PURE__ */ jsxs2(Group2, { gap: 6, wrap: "nowrap", children: [
449
+ /* @__PURE__ */ jsx4(
450
+ Box,
451
+ {
452
+ "aria-hidden": "true",
453
+ style: {
454
+ width: 28,
455
+ height: 28,
456
+ borderRadius: 999,
457
+ background: `linear-gradient(135deg, ${vibe.primary}, ${vibe.accent})`,
458
+ boxShadow: `0 10px 28px ${vibe.glow}`,
459
+ border: `1px solid ${vibe.borderLight}`
460
+ }
461
+ }
462
+ ),
463
+ /* @__PURE__ */ jsx4(Text2, { fw: 700, size: "sm", children: lane.label })
464
+ ] }),
465
+ isSelected ? /* @__PURE__ */ jsx4(Badge, { variant: "light", children: "Selected" }) : null
466
+ ] }),
467
+ /* @__PURE__ */ jsx4(
468
+ Box,
469
+ {
470
+ "aria-hidden": "true",
471
+ style: {
472
+ height: 56,
473
+ borderRadius: 16,
474
+ background: vibe.hero,
475
+ border: `1px solid ${vibe.borderLight}`
476
+ }
477
+ }
478
+ ),
479
+ /* @__PURE__ */ jsx4(Text2, { fw: 700, size: "sm", children: "CSS VibeTheme" }),
480
+ /* @__PURE__ */ jsx4(Text2, { size: "sm", c: "dimmed", children: lane.summary }),
481
+ /* @__PURE__ */ jsxs2(Text2, { size: "xs", children: [
482
+ /* @__PURE__ */ jsx4("strong", { children: "Best for:" }),
483
+ " ",
484
+ lane.supportedUse
485
+ ] }),
486
+ /* @__PURE__ */ jsx4(Code, { block: true, fz: "10px", children: lane.themeKey }),
487
+ /* @__PURE__ */ jsx4(
488
+ Button2,
489
+ {
490
+ size: "xs",
491
+ variant: isSelected ? "filled" : "default",
492
+ onClick: () => setPreset(vibe.id),
493
+ children: "Preview this vibe"
494
+ }
495
+ ),
496
+ /* @__PURE__ */ jsxs2(Text2, { size: "xs", c: "dimmed", children: [
497
+ /* @__PURE__ */ jsx4("strong", { children: "Avoid for:" }),
498
+ " ",
499
+ lane.avoidFor ?? "No special exclusion noted for this lane."
500
+ ] })
501
+ ] })
502
+ },
503
+ lane.themeKey
504
+ );
505
+ }) })
506
+ }
507
+ ),
508
+ /* @__PURE__ */ jsx4(
509
+ ReferenceSection,
510
+ {
511
+ title: "Current VibeTheme contract",
512
+ description: "The selected preset exports these package-owned CSS tokens. Consumers can render expressive product surfaces while staying inside GDS theme ownership.",
513
+ children: /* @__PURE__ */ jsx4(Paper, { withBorder: true, radius: "xl", p: "lg", style: { background: selectedVibe?.hero }, children: /* @__PURE__ */ jsx4(SimpleGrid, { cols: { base: 1, md: 3 }, spacing: "md", children: selectedVibe ? [
514
+ ["Primary", selectedVibe.primary],
515
+ ["Accent", selectedVibe.accent],
516
+ ["Light canvas", selectedVibe.canvasLight],
517
+ ["Dark canvas", selectedVibe.canvasDark],
518
+ ["Light surface", selectedVibe.surfaceLight],
519
+ ["Dark surface", selectedVibe.surfaceDark]
520
+ ].map(([label, value]) => /* @__PURE__ */ jsx4(Paper, { withBorder: true, radius: "lg", p: "md", children: /* @__PURE__ */ jsxs2(Stack, { gap: 8, children: [
521
+ /* @__PURE__ */ jsx4(
522
+ Box,
523
+ {
524
+ "aria-hidden": "true",
525
+ style: {
526
+ height: 38,
527
+ borderRadius: 12,
528
+ background: value,
529
+ border: `1px solid ${selectedVibe.borderLight}`
530
+ }
531
+ }
532
+ ),
533
+ /* @__PURE__ */ jsx4(Text2, { fw: 700, size: "sm", children: label }),
534
+ /* @__PURE__ */ jsx4(Code, { fz: "11px", children: value })
535
+ ] }) }, label)) : null }) })
440
536
  }
441
537
  ),
442
538
  /* @__PURE__ */ jsx4(
@@ -628,7 +724,7 @@ function useListingState() {
628
724
 
629
725
  // src/DiscoveryShell.tsx
630
726
  import { useEffect as useEffect3, useState as useState3 } from "react";
631
- import { AppShell as MantineAppShell, Box, Burger, Group as Group3, ScrollArea } from "@mantine/core";
727
+ import { AppShell as MantineAppShell, Box as Box2, Burger, Group as Group3, ScrollArea } from "@mantine/core";
632
728
  import { useMediaQuery as useMediaQuery2 } from "@mantine/hooks";
633
729
  import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
634
730
  function useDiscoveryShellState({
@@ -736,10 +832,10 @@ function DiscoveryShell({
736
832
  "aria-label": desktopNavigationLabel
737
833
  }
738
834
  ) : null,
739
- /* @__PURE__ */ jsx7(Box, { style: { flex: 1, minWidth: 0 }, children: header })
835
+ /* @__PURE__ */ jsx7(Box2, { style: { flex: 1, minWidth: 0 }, children: header })
740
836
  ] }) }),
741
837
  /* @__PURE__ */ jsx7(MantineAppShell.Navbar, { p: "md", "data-sticky-sidebar": stickySidebar || void 0, children: /* @__PURE__ */ jsx7(ScrollArea, { h: "100%", type: "auto", children: /* @__PURE__ */ jsx7(
742
- Box,
838
+ Box2,
743
839
  {
744
840
  h: "100%",
745
841
  style: stickySidebar ? {
@@ -768,7 +864,7 @@ function DiscoveryShell({
768
864
 
769
865
  // src/DocsShell.tsx
770
866
  import { useState as useState4 } from "react";
771
- import { Box as Box2, Burger as Burger2, Container, Divider, Group as Group4, Stack as Stack2, Text as Text4, Transition } from "@mantine/core";
867
+ import { Box as Box3, Burger as Burger2, Container, Divider, Group as Group4, Stack as Stack2, Text as Text4, Transition } from "@mantine/core";
772
868
  import { Fragment, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
773
869
  function DocsShellSidebar({ primaryNavigation, secondaryNavigation }) {
774
870
  return /* @__PURE__ */ jsxs4(Stack2, { gap: "md", h: "100%", children: [
@@ -820,9 +916,9 @@ function DocsShell({
820
916
  "aria-label": "Toggle docs navigation"
821
917
  }
822
918
  ),
823
- /* @__PURE__ */ jsx8(Transition, { mounted: mobileNavOpen, transition: "pop", duration: 120, children: (styles) => /* @__PURE__ */ jsx8(Box2, { style: styles, children: /* @__PURE__ */ jsx8(Box2, { mt: "xs", p: "sm", style: { borderRadius: 8, border: "1px solid var(--mantine-color-default-border)" }, children: mobileNavigation }) }) })
919
+ /* @__PURE__ */ jsx8(Transition, { mounted: mobileNavOpen, transition: "pop", duration: 120, children: (styles) => /* @__PURE__ */ jsx8(Box3, { style: styles, children: /* @__PURE__ */ jsx8(Box3, { mt: "xs", p: "sm", style: { borderRadius: 8, border: "1px solid var(--mantine-color-default-border)" }, children: mobileNavigation }) }) })
824
920
  ] }) : null,
825
- /* @__PURE__ */ jsx8(Box2, { style: { minWidth: 0 }, children: brand }),
921
+ /* @__PURE__ */ jsx8(Box3, { style: { minWidth: 0 }, children: brand }),
826
922
  headerContext ? /* @__PURE__ */ jsx8(Text4, { size: "sm", c: "dimmed", lineClamp: 1, children: headerContext }) : null
827
923
  ] }),
828
924
  /* @__PURE__ */ jsx8(Group4, { gap: "sm", wrap: "nowrap", style: { minWidth: 0 }, children: actions })
@@ -844,7 +940,7 @@ function DocsShell({
844
940
 
845
941
  // src/SidebarNav.tsx
846
942
  import { forwardRef } from "react";
847
- import { Box as Box3, NavLink, Stack as Stack3, Text as Text5, createPolymorphicComponent } from "@mantine/core";
943
+ import { Box as Box4, NavLink, Stack as Stack3, Text as Text5, createPolymorphicComponent } from "@mantine/core";
848
944
  import { useGdsTranslation as useGdsTranslation3 } from "@doneisbetter/gds-theme";
849
945
  import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
850
946
  function SidebarNav({ children, ariaLabel = "Primary navigation", gap = "md" }) {
@@ -879,7 +975,7 @@ var _SidebarNavItem = forwardRef(
879
975
  label: resolvedLabel,
880
976
  description,
881
977
  leftSection: icon ?? (Icon ? /* @__PURE__ */ jsx9(Icon, { size: "1rem", stroke: 1.5 }) : void 0),
882
- rightSection: badge ? /* @__PURE__ */ jsx9(Box3, { children: badge }) : props.rightSection,
978
+ rightSection: badge ? /* @__PURE__ */ jsx9(Box4, { children: badge }) : props.rightSection,
883
979
  "aria-label": ariaLabel ?? (typeof resolvedLabel === "string" ? resolvedLabel : void 0),
884
980
  "aria-current": props.active ? "page" : ariaCurrent,
885
981
  ...props
@@ -1014,7 +1110,7 @@ function ShareButtonGroup({
1014
1110
 
1015
1111
  // src/UploadDropzone.tsx
1016
1112
  import { useRef, useState as useState7 } from "react";
1017
- import { Badge as Badge2, Box as Box4, Button as Button4, Group as Group7, Stack as Stack6, Text as Text8 } from "@mantine/core";
1113
+ import { Badge as Badge2, Box as Box5, Button as Button4, Group as Group7, Stack as Stack6, Text as Text8 } from "@mantine/core";
1018
1114
  import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
1019
1115
  function UploadDropzone({
1020
1116
  title,
@@ -1047,7 +1143,7 @@ function UploadDropzone({
1047
1143
  onFilesSelected(Array.from(files));
1048
1144
  };
1049
1145
  return /* @__PURE__ */ jsxs8(
1050
- Box4,
1146
+ Box5,
1051
1147
  {
1052
1148
  onDragOver: (event) => {
1053
1149
  event.preventDefault();
package/dist/client.js CHANGED
@@ -1025,6 +1025,8 @@ function resolvePreviewColorScheme(presetId, requestedScheme) {
1025
1025
  return requestedScheme;
1026
1026
  }
1027
1027
  var presetCatalog = (0, import_gds_theme3.getGdsThemePresets)();
1028
+ var vibeCatalog = (0, import_gds_theme3.getGdsVibeThemes)();
1029
+ var vibeCatalogById = Object.fromEntries(vibeCatalog.map((vibe) => [vibe.id, vibe]));
1028
1030
  var themePresetCatalog = Object.fromEntries(
1029
1031
  presetCatalog.map((preset) => [
1030
1032
  preset.id,
@@ -1144,6 +1146,7 @@ function ReferenceThemeExplorer({
1144
1146
  const effectiveComparisonScheme = resolvePreviewColorScheme(comparisonPreset, colorScheme);
1145
1147
  const previewKey = `${preset}-${effectiveColorScheme}-${brandPrimary}-${brandFlatSurfaces}-${brandEditorialSerif}-${fontLane}`;
1146
1148
  const comparisonPreviewKey = `${comparisonPreset}-${effectiveComparisonScheme}-${brandPrimary}-${brandFlatSurfaces}-${brandEditorialSerif}-${fontLane}`;
1149
+ const selectedVibe = vibeCatalogById[preset];
1147
1150
  (0, import_react2.useEffect)(() => {
1148
1151
  onSelectionChange?.({
1149
1152
  preset,
@@ -1296,22 +1299,113 @@ function ReferenceThemeExplorer({
1296
1299
  ReferenceSection,
1297
1300
  {
1298
1301
  title: "Shipped theme lanes",
1299
- description: "Every lane below is part of the supported system. The website uses these exact helpers as its live runtime proof.",
1300
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.SimpleGrid, { cols: { base: 1, md: 2, xl: 5 }, spacing: "md", children: Object.values(themePresetCatalog).map((lane) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Paper, { withBorder: true, radius: "lg", p: "md", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Stack, { gap: 6, children: [
1301
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { fw: 700, size: "sm", children: lane.label }),
1302
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { size: "sm", c: "dimmed", children: lane.summary }),
1303
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Text, { size: "xs", children: [
1304
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { children: "Best for:" }),
1305
- " ",
1306
- lane.supportedUse
1307
- ] }),
1308
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Code, { block: true, fz: "10px", children: lane.themeKey }),
1309
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Text, { size: "xs", c: "dimmed", children: [
1310
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { children: "Avoid for:" }),
1311
- " ",
1312
- lane.avoidFor ?? "No special exclusion noted for this lane."
1313
- ] })
1314
- ] }) }, lane.themeKey)) })
1302
+ description: "Every lane below is a supported runtime preset. Colourful lanes ship as full CSS-based VibeThemes: canvas, shell, surface, control, focus, and accent tokens, not bitmap backgrounds.",
1303
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.SimpleGrid, { cols: { base: 1, md: 2, xl: 4 }, spacing: "md", children: vibeCatalog.map((vibe) => {
1304
+ const lane = themePresetCatalog[vibe.id];
1305
+ const isSelected = vibe.id === preset;
1306
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1307
+ import_core14.Paper,
1308
+ {
1309
+ withBorder: true,
1310
+ radius: "lg",
1311
+ p: "md",
1312
+ role: "group",
1313
+ "aria-label": `${lane.label} vibe theme`,
1314
+ style: {
1315
+ background: `linear-gradient(135deg, ${vibe.surfaceLight}, color-mix(in srgb, ${vibe.primary} 12%, ${vibe.surfaceLight})), ${vibe.gradient}`,
1316
+ borderColor: isSelected ? vibe.primary : vibe.borderLight,
1317
+ boxShadow: isSelected ? `0 0 0 2px ${vibe.primary}, 0 18px 46px ${vibe.glow}` : void 0
1318
+ },
1319
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Stack, { gap: 6, children: [
1320
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Group, { gap: "xs", justify: "space-between", align: "flex-start", wrap: "nowrap", children: [
1321
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Group, { gap: 6, wrap: "nowrap", children: [
1322
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1323
+ import_core14.Box,
1324
+ {
1325
+ "aria-hidden": "true",
1326
+ style: {
1327
+ width: 28,
1328
+ height: 28,
1329
+ borderRadius: 999,
1330
+ background: `linear-gradient(135deg, ${vibe.primary}, ${vibe.accent})`,
1331
+ boxShadow: `0 10px 28px ${vibe.glow}`,
1332
+ border: `1px solid ${vibe.borderLight}`
1333
+ }
1334
+ }
1335
+ ),
1336
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { fw: 700, size: "sm", children: lane.label })
1337
+ ] }),
1338
+ isSelected ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Badge, { variant: "light", children: "Selected" }) : null
1339
+ ] }),
1340
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1341
+ import_core14.Box,
1342
+ {
1343
+ "aria-hidden": "true",
1344
+ style: {
1345
+ height: 56,
1346
+ borderRadius: 16,
1347
+ background: vibe.hero,
1348
+ border: `1px solid ${vibe.borderLight}`
1349
+ }
1350
+ }
1351
+ ),
1352
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { fw: 700, size: "sm", children: "CSS VibeTheme" }),
1353
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { size: "sm", c: "dimmed", children: lane.summary }),
1354
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Text, { size: "xs", children: [
1355
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { children: "Best for:" }),
1356
+ " ",
1357
+ lane.supportedUse
1358
+ ] }),
1359
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Code, { block: true, fz: "10px", children: lane.themeKey }),
1360
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1361
+ import_core14.Button,
1362
+ {
1363
+ size: "xs",
1364
+ variant: isSelected ? "filled" : "default",
1365
+ onClick: () => setPreset(vibe.id),
1366
+ children: "Preview this vibe"
1367
+ }
1368
+ ),
1369
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Text, { size: "xs", c: "dimmed", children: [
1370
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { children: "Avoid for:" }),
1371
+ " ",
1372
+ lane.avoidFor ?? "No special exclusion noted for this lane."
1373
+ ] })
1374
+ ] })
1375
+ },
1376
+ lane.themeKey
1377
+ );
1378
+ }) })
1379
+ }
1380
+ ),
1381
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1382
+ ReferenceSection,
1383
+ {
1384
+ title: "Current VibeTheme contract",
1385
+ description: "The selected preset exports these package-owned CSS tokens. Consumers can render expressive product surfaces while staying inside GDS theme ownership.",
1386
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Paper, { withBorder: true, radius: "xl", p: "lg", style: { background: selectedVibe?.hero }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.SimpleGrid, { cols: { base: 1, md: 3 }, spacing: "md", children: selectedVibe ? [
1387
+ ["Primary", selectedVibe.primary],
1388
+ ["Accent", selectedVibe.accent],
1389
+ ["Light canvas", selectedVibe.canvasLight],
1390
+ ["Dark canvas", selectedVibe.canvasDark],
1391
+ ["Light surface", selectedVibe.surfaceLight],
1392
+ ["Dark surface", selectedVibe.surfaceDark]
1393
+ ].map(([label, value]) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Paper, { withBorder: true, radius: "lg", p: "md", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Stack, { gap: 8, children: [
1394
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1395
+ import_core14.Box,
1396
+ {
1397
+ "aria-hidden": "true",
1398
+ style: {
1399
+ height: 38,
1400
+ borderRadius: 12,
1401
+ background: value,
1402
+ border: `1px solid ${selectedVibe.borderLight}`
1403
+ }
1404
+ }
1405
+ ),
1406
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { fw: 700, size: "sm", children: label }),
1407
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Code, { fz: "11px", children: value })
1408
+ ] }) }, label)) : null }) })
1315
1409
  }
1316
1410
  ),
1317
1411
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
package/dist/client.mjs CHANGED
@@ -34,7 +34,7 @@ import {
34
34
  useGdsTelemetry,
35
35
  useListingState,
36
36
  useOverlayManager
37
- } from "./chunk-6FX7WZZO.mjs";
37
+ } from "./chunk-QA7LTXDE.mjs";
38
38
  import {
39
39
  AccentPanel,
40
40
  AccessSummary,
package/dist/index.js CHANGED
@@ -1025,6 +1025,8 @@ function resolvePreviewColorScheme(presetId, requestedScheme) {
1025
1025
  return requestedScheme;
1026
1026
  }
1027
1027
  var presetCatalog = (0, import_gds_theme3.getGdsThemePresets)();
1028
+ var vibeCatalog = (0, import_gds_theme3.getGdsVibeThemes)();
1029
+ var vibeCatalogById = Object.fromEntries(vibeCatalog.map((vibe) => [vibe.id, vibe]));
1028
1030
  var themePresetCatalog = Object.fromEntries(
1029
1031
  presetCatalog.map((preset) => [
1030
1032
  preset.id,
@@ -1144,6 +1146,7 @@ function ReferenceThemeExplorer({
1144
1146
  const effectiveComparisonScheme = resolvePreviewColorScheme(comparisonPreset, colorScheme);
1145
1147
  const previewKey = `${preset}-${effectiveColorScheme}-${brandPrimary}-${brandFlatSurfaces}-${brandEditorialSerif}-${fontLane}`;
1146
1148
  const comparisonPreviewKey = `${comparisonPreset}-${effectiveComparisonScheme}-${brandPrimary}-${brandFlatSurfaces}-${brandEditorialSerif}-${fontLane}`;
1149
+ const selectedVibe = vibeCatalogById[preset];
1147
1150
  (0, import_react2.useEffect)(() => {
1148
1151
  onSelectionChange?.({
1149
1152
  preset,
@@ -1296,22 +1299,113 @@ function ReferenceThemeExplorer({
1296
1299
  ReferenceSection,
1297
1300
  {
1298
1301
  title: "Shipped theme lanes",
1299
- description: "Every lane below is part of the supported system. The website uses these exact helpers as its live runtime proof.",
1300
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.SimpleGrid, { cols: { base: 1, md: 2, xl: 5 }, spacing: "md", children: Object.values(themePresetCatalog).map((lane) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Paper, { withBorder: true, radius: "lg", p: "md", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Stack, { gap: 6, children: [
1301
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { fw: 700, size: "sm", children: lane.label }),
1302
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { size: "sm", c: "dimmed", children: lane.summary }),
1303
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Text, { size: "xs", children: [
1304
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { children: "Best for:" }),
1305
- " ",
1306
- lane.supportedUse
1307
- ] }),
1308
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Code, { block: true, fz: "10px", children: lane.themeKey }),
1309
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Text, { size: "xs", c: "dimmed", children: [
1310
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { children: "Avoid for:" }),
1311
- " ",
1312
- lane.avoidFor ?? "No special exclusion noted for this lane."
1313
- ] })
1314
- ] }) }, lane.themeKey)) })
1302
+ description: "Every lane below is a supported runtime preset. Colourful lanes ship as full CSS-based VibeThemes: canvas, shell, surface, control, focus, and accent tokens, not bitmap backgrounds.",
1303
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.SimpleGrid, { cols: { base: 1, md: 2, xl: 4 }, spacing: "md", children: vibeCatalog.map((vibe) => {
1304
+ const lane = themePresetCatalog[vibe.id];
1305
+ const isSelected = vibe.id === preset;
1306
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1307
+ import_core14.Paper,
1308
+ {
1309
+ withBorder: true,
1310
+ radius: "lg",
1311
+ p: "md",
1312
+ role: "group",
1313
+ "aria-label": `${lane.label} vibe theme`,
1314
+ style: {
1315
+ background: `linear-gradient(135deg, ${vibe.surfaceLight}, color-mix(in srgb, ${vibe.primary} 12%, ${vibe.surfaceLight})), ${vibe.gradient}`,
1316
+ borderColor: isSelected ? vibe.primary : vibe.borderLight,
1317
+ boxShadow: isSelected ? `0 0 0 2px ${vibe.primary}, 0 18px 46px ${vibe.glow}` : void 0
1318
+ },
1319
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Stack, { gap: 6, children: [
1320
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Group, { gap: "xs", justify: "space-between", align: "flex-start", wrap: "nowrap", children: [
1321
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Group, { gap: 6, wrap: "nowrap", children: [
1322
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1323
+ import_core14.Box,
1324
+ {
1325
+ "aria-hidden": "true",
1326
+ style: {
1327
+ width: 28,
1328
+ height: 28,
1329
+ borderRadius: 999,
1330
+ background: `linear-gradient(135deg, ${vibe.primary}, ${vibe.accent})`,
1331
+ boxShadow: `0 10px 28px ${vibe.glow}`,
1332
+ border: `1px solid ${vibe.borderLight}`
1333
+ }
1334
+ }
1335
+ ),
1336
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { fw: 700, size: "sm", children: lane.label })
1337
+ ] }),
1338
+ isSelected ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Badge, { variant: "light", children: "Selected" }) : null
1339
+ ] }),
1340
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1341
+ import_core14.Box,
1342
+ {
1343
+ "aria-hidden": "true",
1344
+ style: {
1345
+ height: 56,
1346
+ borderRadius: 16,
1347
+ background: vibe.hero,
1348
+ border: `1px solid ${vibe.borderLight}`
1349
+ }
1350
+ }
1351
+ ),
1352
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { fw: 700, size: "sm", children: "CSS VibeTheme" }),
1353
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { size: "sm", c: "dimmed", children: lane.summary }),
1354
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Text, { size: "xs", children: [
1355
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { children: "Best for:" }),
1356
+ " ",
1357
+ lane.supportedUse
1358
+ ] }),
1359
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Code, { block: true, fz: "10px", children: lane.themeKey }),
1360
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1361
+ import_core14.Button,
1362
+ {
1363
+ size: "xs",
1364
+ variant: isSelected ? "filled" : "default",
1365
+ onClick: () => setPreset(vibe.id),
1366
+ children: "Preview this vibe"
1367
+ }
1368
+ ),
1369
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Text, { size: "xs", c: "dimmed", children: [
1370
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { children: "Avoid for:" }),
1371
+ " ",
1372
+ lane.avoidFor ?? "No special exclusion noted for this lane."
1373
+ ] })
1374
+ ] })
1375
+ },
1376
+ lane.themeKey
1377
+ );
1378
+ }) })
1379
+ }
1380
+ ),
1381
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1382
+ ReferenceSection,
1383
+ {
1384
+ title: "Current VibeTheme contract",
1385
+ description: "The selected preset exports these package-owned CSS tokens. Consumers can render expressive product surfaces while staying inside GDS theme ownership.",
1386
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Paper, { withBorder: true, radius: "xl", p: "lg", style: { background: selectedVibe?.hero }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.SimpleGrid, { cols: { base: 1, md: 3 }, spacing: "md", children: selectedVibe ? [
1387
+ ["Primary", selectedVibe.primary],
1388
+ ["Accent", selectedVibe.accent],
1389
+ ["Light canvas", selectedVibe.canvasLight],
1390
+ ["Dark canvas", selectedVibe.canvasDark],
1391
+ ["Light surface", selectedVibe.surfaceLight],
1392
+ ["Dark surface", selectedVibe.surfaceDark]
1393
+ ].map(([label, value]) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Paper, { withBorder: true, radius: "lg", p: "md", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_core14.Stack, { gap: 8, children: [
1394
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1395
+ import_core14.Box,
1396
+ {
1397
+ "aria-hidden": "true",
1398
+ style: {
1399
+ height: 38,
1400
+ borderRadius: 12,
1401
+ background: value,
1402
+ border: `1px solid ${selectedVibe.borderLight}`
1403
+ }
1404
+ }
1405
+ ),
1406
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Text, { fw: 700, size: "sm", children: label }),
1407
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_core14.Code, { fz: "11px", children: value })
1408
+ ] }) }, label)) : null }) })
1315
1409
  }
1316
1410
  ),
1317
1411
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
package/dist/index.mjs CHANGED
@@ -34,7 +34,7 @@ import {
34
34
  useGdsTelemetry,
35
35
  useListingState,
36
36
  useOverlayManager
37
- } from "./chunk-6FX7WZZO.mjs";
37
+ } from "./chunk-QA7LTXDE.mjs";
38
38
  import {
39
39
  AccentPanel,
40
40
  AccessSummary,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doneisbetter/gds-core",
3
- "version": "3.0.2",
3
+ "version": "3.0.3",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
@@ -38,7 +38,7 @@
38
38
  "dev": "tsup --watch"
39
39
  },
40
40
  "peerDependencies": {
41
- "@doneisbetter/gds-theme": "^3.0.2",
41
+ "@doneisbetter/gds-theme": "^3.0.3",
42
42
  "@mantine/core": "^7.9.0 || ^8.3.0 || ^9.0.0",
43
43
  "@mantine/hooks": "^7.9.0 || ^8.3.0 || ^9.0.0",
44
44
  "@tabler/icons-react": "^3.5.0",
@@ -52,5 +52,8 @@
52
52
  "@tabler/icons-react": "^3.5.0",
53
53
  "react": "^18.2.0",
54
54
  "react-dom": "^18.2.0"
55
+ },
56
+ "dependencies": {
57
+ "@doneisbetter/gds-theme": "^3.0.3"
55
58
  }
56
59
  }