@drawnagency/primitives 0.1.78 → 0.1.79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/{chunk-NS3UTJ3E.js → chunk-4XXLH5CL.js} +4 -4
  2. package/dist/{chunk-K4JD6FD3.js → chunk-DR22HM44.js} +1 -1
  3. package/dist/{chunk-BAQYZSFF.js → chunk-FRTJNS5F.js} +5 -5
  4. package/dist/{chunk-MK4POMLZ.js → chunk-QB5Q23G2.js} +1 -1
  5. package/dist/{chunk-4SIWBWKZ.js → chunk-RSITF24B.js} +8 -0
  6. package/dist/{chunk-UA6OCJJK.js → chunk-RWMSDDQM.js} +2 -2
  7. package/dist/{chunk-Z5IYWUW3.js → chunk-UNUJPLZV.js} +1 -1
  8. package/dist/components/editor/index.js +1 -1
  9. package/dist/components/primitives/index.js +3 -3
  10. package/dist/components/sections/brand-guide.js +3 -3
  11. package/dist/components/sections/register-schemas.js +5 -5
  12. package/dist/components/sections/register.js +5 -5
  13. package/dist/components/shell/EditorShell.d.ts.map +1 -1
  14. package/dist/components/shell/SiteSettingsDisplay.d.ts.map +1 -1
  15. package/dist/index.js +3 -3
  16. package/dist/lib/corner-radius.d.ts +6 -0
  17. package/dist/lib/corner-radius.d.ts.map +1 -0
  18. package/dist/lib/index.js +2 -2
  19. package/dist/media/index.js +1 -1
  20. package/dist/schemas/index.js +2 -2
  21. package/dist/schemas/site-config.d.ts +6 -0
  22. package/dist/schemas/site-config.d.ts.map +1 -1
  23. package/package.json +1 -1
  24. package/src/components/brandguide/Colors.tsx +2 -2
  25. package/src/components/chat/ChatPanel.tsx +8 -8
  26. package/src/components/primitives/ResolvedMedia.tsx +1 -1
  27. package/src/components/sections/Button/CTAButton.tsx +1 -1
  28. package/src/components/sections/Media/MediaBlock.tsx +1 -1
  29. package/src/components/shared/Navigation.tsx +5 -5
  30. package/src/components/shell/EditorModal.tsx +7 -7
  31. package/src/components/shell/EditorShell.tsx +3 -0
  32. package/src/components/shell/SiteSettingsDisplay.tsx +19 -0
  33. package/src/lib/corner-radius.ts +22 -0
  34. package/src/schemas/site-config.ts +4 -0
@@ -9,7 +9,7 @@ import {
9
9
  MediaBlock,
10
10
  containerGridClass,
11
11
  useEditableCollection
12
- } from "./chunk-UA6OCJJK.js";
12
+ } from "./chunk-RWMSDDQM.js";
13
13
  import {
14
14
  AddIcon,
15
15
  DeleteIcon,
@@ -30,7 +30,7 @@ import {
30
30
  import {
31
31
  HexColorSchema,
32
32
  SingleMediaReferenceSchema
33
- } from "./chunk-4SIWBWKZ.js";
33
+ } from "./chunk-RSITF24B.js";
34
34
  import {
35
35
  defineSection
36
36
  } from "./chunk-VKAGMEKE.js";
@@ -184,7 +184,7 @@ function ColorsView({
184
184
  /* @__PURE__ */ jsx2("div", { className: "@container", children: /* @__PURE__ */ jsx2("div", { className: cn("grid gap-4", containerGridClass[columns] || containerGridClass[3]), children: colors.map((color, i) => {
185
185
  const hex = color.spaces[0]?.hex;
186
186
  const contrast = getContrastClass(hex);
187
- return /* @__PURE__ */ jsxs2("div", { className: "overflow-hidden rounded-md border border-base-200", children: [
187
+ return /* @__PURE__ */ jsxs2("div", { className: "overflow-hidden rounded-outer border border-base-200", children: [
188
188
  /* @__PURE__ */ jsxs2("div", { className: cn("relative flex min-h-[80px] items-end p-3", contrast), style: { backgroundColor: hex || "#ccc" }, children: [
189
189
  color.name && /* @__PURE__ */ jsx2("span", { className: "text-sm font-bold", children: color.name }),
190
190
  copiedIndex === i && /* @__PURE__ */ jsx2("span", { className: cn(
@@ -290,7 +290,7 @@ function ColorSwatchEditable({
290
290
  const newColors = colors.map((c, i) => i === index ? updated : c);
291
291
  onChange(buildContent(newColors, options));
292
292
  };
293
- return /* @__PURE__ */ jsxs2("div", { className: "overflow-hidden rounded-md border border-base-200", children: [
293
+ return /* @__PURE__ */ jsxs2("div", { className: "overflow-hidden rounded-outer border border-base-200", children: [
294
294
  /* @__PURE__ */ jsx2("div", { className: cn("flex min-h-[80px] items-end p-3", contrast), style: { backgroundColor: hex || "#ccc" }, children: /* @__PURE__ */ jsx2(
295
295
  EditablePlainText,
296
296
  {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  EditablePlainText
3
- } from "./chunk-UA6OCJJK.js";
3
+ } from "./chunk-RWMSDDQM.js";
4
4
  import {
5
5
  Button,
6
6
  usePages
@@ -3,7 +3,7 @@ import {
3
3
  pluralize,
4
4
  stripHtmlToPlainText,
5
5
  truncate
6
- } from "./chunk-NS3UTJ3E.js";
6
+ } from "./chunk-4XXLH5CL.js";
7
7
  import {
8
8
  DeleteButton,
9
9
  DragHandle,
@@ -19,7 +19,7 @@ import {
19
19
  import {
20
20
  EditableRichText,
21
21
  defineHeadingSection
22
- } from "./chunk-K4JD6FD3.js";
22
+ } from "./chunk-DR22HM44.js";
23
23
  import {
24
24
  EditablePlainText,
25
25
  ImageDropZone,
@@ -28,7 +28,7 @@ import {
28
28
  colSpanClass,
29
29
  containerGridClass,
30
30
  spacerHiddenClass
31
- } from "./chunk-UA6OCJJK.js";
31
+ } from "./chunk-RWMSDDQM.js";
32
32
  import {
33
33
  useMediaLibrary,
34
34
  useResolvedMedia
@@ -51,7 +51,7 @@ import {
51
51
  } from "./chunk-TZQPOR5A.js";
52
52
  import {
53
53
  SingleMediaReferenceSchema
54
- } from "./chunk-4SIWBWKZ.js";
54
+ } from "./chunk-RSITF24B.js";
55
55
  import {
56
56
  defineSection,
57
57
  getSection
@@ -397,7 +397,7 @@ import { RectangleHorizontal } from "lucide-react";
397
397
  import { Download } from "lucide-react";
398
398
  import { jsx as jsx9, jsxs as jsxs2 } from "react/jsx-runtime";
399
399
  function Button({ text, link, download, onChange }) {
400
- const base = "inline-block rounded-md px-6 py-3 font-bold transition-colors";
400
+ const base = "inline-block rounded-outer px-6 py-3 font-bold transition-colors";
401
401
  const variant = "border-2 border-primary text-primary hover:bg-primary hover:text-primary-contrast";
402
402
  if (onChange) {
403
403
  return /* @__PURE__ */ jsxs2("span", { className: cn(base, variant, "inline-flex items-center gap-2"), children: [
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  HexColorSchema
3
- } from "./chunk-4SIWBWKZ.js";
3
+ } from "./chunk-RSITF24B.js";
4
4
 
5
5
  // src/schemas/audience.ts
6
6
  import { z } from "zod";
@@ -113,6 +113,11 @@ var MediaConfigSchema = z2.object({
113
113
 
114
114
  // src/schemas/site-config.ts
115
115
  import { z as z3 } from "zod";
116
+
117
+ // src/lib/corner-radius.ts
118
+ var CORNER_RADIUS_OPTIONS = ["none", "small", "medium", "large"];
119
+
120
+ // src/schemas/site-config.ts
116
121
  var StatusSchema = z3.enum(["draft", "live", "archived", "published"]).transform(
117
122
  (val) => val === "published" ? "live" : val
118
123
  );
@@ -254,6 +259,9 @@ var SiteConfigSchema = z3.object({
254
259
  primaryColor: HexColorSchema.default("#009ca6"),
255
260
  primaryContrast: HexColorSchema.default("#f0f0f0"),
256
261
  darkMode: z3.enum(["light", "dark", "optional"]).default("light"),
262
+ // Maps to the --radius-outer design token (see lib/corner-radius.ts);
263
+ // defaults so pre-existing site-config.json files keep parsing.
264
+ cornerRadius: z3.enum(CORNER_RADIUS_OPTIONS).default("medium"),
257
265
  headingFont: FontNameSchema.default("system-ui"),
258
266
  bodyFont: FontNameSchema.default("system-ui"),
259
267
  uppercaseHeadings: z3.boolean().default(true),
@@ -195,7 +195,7 @@ function ResolvedMedia({
195
195
  onError: () => setLoaded(true)
196
196
  }
197
197
  )
198
- ] }) : /* @__PURE__ */ jsxs("div", { className: "flex aspect-video h-full w-full flex-col items-center justify-center gap-1 rounded bg-base-accent text-base-contrast-light/50", children: [
198
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "flex aspect-video h-full w-full flex-col items-center justify-center gap-1 rounded-outer bg-base-accent text-base-contrast-light/50", children: [
199
199
  /* @__PURE__ */ jsx(ImageIcon, { size: 24 }),
200
200
  /* @__PURE__ */ jsx("span", { className: "text-sm", children: "No Image" })
201
201
  ] }) });
@@ -293,7 +293,7 @@ function MediaBlock({ refValue, options, link, isEditMode, onRefChange }) {
293
293
  {
294
294
  "data-testid": "media-open-surface",
295
295
  className: cn(
296
- "overflow-hidden rounded-md",
296
+ "overflow-hidden rounded-outer",
297
297
  showBorder && "border border-base-200",
298
298
  options.square && "aspect-square",
299
299
  onImageClick && "cursor-pointer"
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-TZQPOR5A.js";
10
10
  import {
11
11
  IndexSchema
12
- } from "./chunk-4SIWBWKZ.js";
12
+ } from "./chunk-RSITF24B.js";
13
13
  import {
14
14
  getAllSchemas
15
15
  } from "./chunk-VKAGMEKE.js";
@@ -24,7 +24,7 @@ import {
24
24
  cn
25
25
  } from "../../chunk-7EOSDFS3.js";
26
26
  import "../../chunk-4YEOTFVU.js";
27
- import "../../chunk-4SIWBWKZ.js";
27
+ import "../../chunk-RSITF24B.js";
28
28
  import "../../chunk-JSBRDJBE.js";
29
29
 
30
30
  // src/components/editor/InsertButton.tsx
@@ -2,7 +2,7 @@ import {
2
2
  EditableRichText,
3
3
  LinkPopover,
4
4
  defineHeadingSection
5
- } from "../../chunk-K4JD6FD3.js";
5
+ } from "../../chunk-DR22HM44.js";
6
6
  import {
7
7
  EditableGrid,
8
8
  EditablePlainText,
@@ -10,7 +10,7 @@ import {
10
10
  MediaBlock,
11
11
  ResolvedMedia,
12
12
  useEditableCollection
13
- } from "../../chunk-UA6OCJJK.js";
13
+ } from "../../chunk-RWMSDDQM.js";
14
14
  import "../../chunk-ZSPCE6MZ.js";
15
15
  import {
16
16
  DeleteIcon,
@@ -23,7 +23,7 @@ import {
23
23
  cn
24
24
  } from "../../chunk-7EOSDFS3.js";
25
25
  import "../../chunk-4YEOTFVU.js";
26
- import "../../chunk-4SIWBWKZ.js";
26
+ import "../../chunk-RSITF24B.js";
27
27
  import "../../chunk-VKAGMEKE.js";
28
28
  import "../../chunk-JSBRDJBE.js";
29
29
 
@@ -2,16 +2,16 @@ import {
2
2
  ColorItemSchema,
3
3
  ColorSpaceSchema,
4
4
  brandGuideSectionDefs
5
- } from "../../chunk-NS3UTJ3E.js";
5
+ } from "../../chunk-4XXLH5CL.js";
6
6
  import "../../chunk-5THS4K5D.js";
7
- import "../../chunk-UA6OCJJK.js";
7
+ import "../../chunk-RWMSDDQM.js";
8
8
  import "../../chunk-EMGLZQCM.js";
9
9
  import "../../chunk-3LNKOLZP.js";
10
10
  import "../../chunk-PZJL2S3Z.js";
11
11
  import "../../chunk-WDSVHKAH.js";
12
12
  import "../../chunk-7EOSDFS3.js";
13
13
  import "../../chunk-4YEOTFVU.js";
14
- import "../../chunk-4SIWBWKZ.js";
14
+ import "../../chunk-RSITF24B.js";
15
15
  import "../../chunk-VKAGMEKE.js";
16
16
  import "../../chunk-JSBRDJBE.js";
17
17
  export {
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  allSectionDefs
3
- } from "../../chunk-BAQYZSFF.js";
4
- import "../../chunk-NS3UTJ3E.js";
3
+ } from "../../chunk-FRTJNS5F.js";
4
+ import "../../chunk-4XXLH5CL.js";
5
5
  import "../../chunk-2DDWWTRX.js";
6
6
  import "../../chunk-5THS4K5D.js";
7
- import "../../chunk-K4JD6FD3.js";
8
- import "../../chunk-UA6OCJJK.js";
7
+ import "../../chunk-DR22HM44.js";
8
+ import "../../chunk-RWMSDDQM.js";
9
9
  import "../../chunk-ZSPCE6MZ.js";
10
10
  import "../../chunk-EMGLZQCM.js";
11
11
  import "../../chunk-Y4JQGO6G.js";
@@ -16,7 +16,7 @@ import "../../chunk-53DKVAB6.js";
16
16
  import "../../chunk-7EOSDFS3.js";
17
17
  import "../../chunk-4YEOTFVU.js";
18
18
  import "../../chunk-TZQPOR5A.js";
19
- import "../../chunk-4SIWBWKZ.js";
19
+ import "../../chunk-RSITF24B.js";
20
20
  import {
21
21
  registerRichText,
22
22
  registerSchema
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  allSectionDefs
3
- } from "../../chunk-BAQYZSFF.js";
4
- import "../../chunk-NS3UTJ3E.js";
3
+ } from "../../chunk-FRTJNS5F.js";
4
+ import "../../chunk-4XXLH5CL.js";
5
5
  import "../../chunk-2DDWWTRX.js";
6
6
  import "../../chunk-5THS4K5D.js";
7
- import "../../chunk-K4JD6FD3.js";
8
- import "../../chunk-UA6OCJJK.js";
7
+ import "../../chunk-DR22HM44.js";
8
+ import "../../chunk-RWMSDDQM.js";
9
9
  import "../../chunk-ZSPCE6MZ.js";
10
10
  import "../../chunk-EMGLZQCM.js";
11
11
  import "../../chunk-Y4JQGO6G.js";
@@ -16,7 +16,7 @@ import "../../chunk-53DKVAB6.js";
16
16
  import "../../chunk-7EOSDFS3.js";
17
17
  import "../../chunk-4YEOTFVU.js";
18
18
  import "../../chunk-TZQPOR5A.js";
19
- import "../../chunk-4SIWBWKZ.js";
19
+ import "../../chunk-RSITF24B.js";
20
20
  import {
21
21
  registerSection
22
22
  } from "../../chunk-VKAGMEKE.js";
@@ -1 +1 @@
1
- {"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAiDjD,OAAO,KAAK,EAAE,eAAe,EAA2D,MAAM,oBAAoB,CAAC;AAmCnH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAoBxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAIhB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;IAIhE,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAKjC,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,YAAY,EACZ,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,EACX,sBAA8B,EAC9B,eAAe,GAChB,EAAE,KAAK,2CA28CP"}
1
+ {"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAkDjD,OAAO,KAAK,EAAE,eAAe,EAA2D,MAAM,oBAAoB,CAAC;AAmCnH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAoBxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAIhB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;IAIhE,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAKjC,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,YAAY,EACZ,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,EACX,sBAA8B,EAC9B,eAAe,GAChB,EAAE,KAAK,2CA68CP"}
@@ -1 +1 @@
1
- {"version":3,"file":"SiteSettingsDisplay.d.ts","sourceRoot":"","sources":["../../../src/components/shell/SiteSettingsDisplay.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,UAAU,KAAK;IACb,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;CACxC;AAWD,wBAAgB,mBAAmB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,KAAK,2CAiKlE"}
1
+ {"version":3,"file":"SiteSettingsDisplay.d.ts","sourceRoot":"","sources":["../../../src/components/shell/SiteSettingsDisplay.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,UAAU,KAAK;IACb,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;CACxC;AAkBD,wBAAgB,mBAAmB,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,KAAK,2CA6KlE"}
package/dist/index.js CHANGED
@@ -49,7 +49,7 @@ import {
49
49
  AudienceNameSchema,
50
50
  MediaGridOptionsSchema,
51
51
  slugifyAudienceName
52
- } from "./chunk-MK4POMLZ.js";
52
+ } from "./chunk-QB5Q23G2.js";
53
53
  import {
54
54
  AudienceSchema,
55
55
  RoleSchema,
@@ -71,7 +71,7 @@ import {
71
71
  loadStaticSiteContent,
72
72
  mergeSiteContent,
73
73
  safeRedirect
74
- } from "./chunk-Z5IYWUW3.js";
74
+ } from "./chunk-UNUJPLZV.js";
75
75
  import {
76
76
  createEvent,
77
77
  darkModeEvent,
@@ -124,7 +124,7 @@ import {
124
124
  TextLineSchema,
125
125
  VariantSchema,
126
126
  normalizeSiteIndex
127
- } from "./chunk-4SIWBWKZ.js";
127
+ } from "./chunk-RSITF24B.js";
128
128
  import {
129
129
  clearRegistry,
130
130
  createRegistry,
@@ -0,0 +1,6 @@
1
+ export declare const CORNER_RADIUS_OPTIONS: readonly ["none", "small", "medium", "large"];
2
+ export type CornerRadius = (typeof CORNER_RADIUS_OPTIONS)[number];
3
+ export declare const CORNER_RADIUS_VALUES: Record<CornerRadius, string>;
4
+ /** CSS length for `--radius-outer`; unknown/missing values fall back to medium. */
5
+ export declare function cornerRadiusValue(radius?: string | null): string;
6
+ //# sourceMappingURL=corner-radius.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corner-radius.d.ts","sourceRoot":"","sources":["../../src/lib/corner-radius.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,qBAAqB,+CAAgD,CAAC;AAEnF,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAIlE,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAK7D,CAAC;AAEF,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAEhE"}
package/dist/lib/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  loadStaticSiteContent,
8
8
  mergeSiteContent,
9
9
  safeRedirect
10
- } from "../chunk-Z5IYWUW3.js";
10
+ } from "../chunk-UNUJPLZV.js";
11
11
  import {
12
12
  createEvent,
13
13
  darkModeEvent,
@@ -33,7 +33,7 @@ import {
33
33
  audiencePasses
34
34
  } from "../chunk-4YEOTFVU.js";
35
35
  import "../chunk-TZQPOR5A.js";
36
- import "../chunk-4SIWBWKZ.js";
36
+ import "../chunk-RSITF24B.js";
37
37
  import {
38
38
  clearRegistry,
39
39
  createRegistry,
@@ -24,7 +24,7 @@ import {
24
24
  MediaFolderSchema,
25
25
  MediaItemSchema,
26
26
  VariantSchema
27
- } from "../chunk-4SIWBWKZ.js";
27
+ } from "../chunk-RSITF24B.js";
28
28
  import "../chunk-JSBRDJBE.js";
29
29
  export {
30
30
  BAKED_MEDIA_KEYS,
@@ -3,7 +3,7 @@ import {
3
3
  AudienceNameSchema,
4
4
  MediaGridOptionsSchema,
5
5
  slugifyAudienceName
6
- } from "../chunk-MK4POMLZ.js";
6
+ } from "../chunk-QB5Q23G2.js";
7
7
  import {
8
8
  AudienceSchema,
9
9
  RoleSchema,
@@ -40,7 +40,7 @@ import {
40
40
  TextLineSchema,
41
41
  VariantSchema,
42
42
  normalizeSiteIndex
43
- } from "../chunk-4SIWBWKZ.js";
43
+ } from "../chunk-RSITF24B.js";
44
44
  import "../chunk-VKAGMEKE.js";
45
45
  import "../chunk-NSCT3AMV.js";
46
46
  import "../chunk-JSBRDJBE.js";
@@ -179,6 +179,12 @@ export declare const SiteConfigSchema: z.ZodObject<{
179
179
  light: "light";
180
180
  dark: "dark";
181
181
  }>>;
182
+ cornerRadius: z.ZodDefault<z.ZodEnum<{
183
+ none: "none";
184
+ small: "small";
185
+ medium: "medium";
186
+ large: "large";
187
+ }>>;
182
188
  headingFont: z.ZodDefault<z.ZodString>;
183
189
  bodyFont: z.ZodDefault<z.ZodString>;
184
190
  uppercaseHeadings: z.ZodDefault<z.ZodBoolean>;
@@ -1 +1 @@
1
- {"version":3,"file":"site-config.d.ts","sourceRoot":"","sources":["../../src/schemas/site-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,eAAO,MAAM,iBAAiB;;;;;;;;;iBAI5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAO5D,eAAO,MAAM,cAAc,0DAA2D,CAAC;AAEvF,eAAO,MAAM,gBAAgB;;;EAA+B,CAAC;AAE7D,eAAO,MAAM,UAAU;;;;;;;;;;;;iBASrB,CAAC;AAEH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AA0C9C,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6CtB,CAAC;AAEL,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAyE,CAAC;AAElG,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAE7D,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,CAE1D;AAMD,eAAO,MAAM,iBAAiB;;;;;iBAM5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,mBAAmB;;;;;;;;;;;iBAwB5B,CAAC;AACL,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAyB3B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
1
+ {"version":3,"file":"site-config.d.ts","sourceRoot":"","sources":["../../src/schemas/site-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,eAAO,MAAM,iBAAiB;;;;;;;;;iBAI5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAO5D,eAAO,MAAM,cAAc,0DAA2D,CAAC;AAEvF,eAAO,MAAM,gBAAgB;;;EAA+B,CAAC;AAE7D,eAAO,MAAM,UAAU;;;;;;;;;;;;iBASrB,CAAC;AAEH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AA0C9C,QAAA,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6CtB,CAAC;AAEL,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAyE,CAAC;AAElG,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAE7D,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,CAE1D;AAMD,eAAO,MAAM,iBAAiB;;;;;iBAM5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,mBAAmB;;;;;;;;;;;iBAwB5B,CAAC;AACL,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4B3B,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drawnagency/primitives",
3
- "version": "0.1.78",
3
+ "version": "0.1.79",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./package.json": "./package.json",
@@ -125,7 +125,7 @@ function ColorsView({
125
125
  const hex = color.spaces[0]?.hex;
126
126
  const contrast = getContrastClass(hex);
127
127
  return (
128
- <div key={i} className="overflow-hidden rounded-md border border-base-200">
128
+ <div key={i} className="overflow-hidden rounded-outer border border-base-200">
129
129
  <div className={cn("relative flex min-h-[80px] items-end p-3", contrast)} style={{ backgroundColor: hex || "#ccc" }}>
130
130
  {color.name && <span className="text-sm font-bold">{color.name}</span>}
131
131
  {copiedIndex === i && (
@@ -267,7 +267,7 @@ function ColorSwatchEditable({
267
267
  };
268
268
 
269
269
  return (
270
- <div className="overflow-hidden rounded-md border border-base-200">
270
+ <div className="overflow-hidden rounded-outer border border-base-200">
271
271
  <div className={cn("flex min-h-[80px] items-end p-3", contrast)} style={{ backgroundColor: hex || "#ccc" }}>
272
272
  <EditablePlainText
273
273
  tag="span"
@@ -39,8 +39,8 @@ const MD_STYLES =
39
39
  "[&_p:not(:first-child)]:mt-2 [&_ul]:mt-1 [&_ul]:list-disc [&_ul]:pl-4 " +
40
40
  "[&_ol]:mt-1 [&_ol]:list-decimal [&_ol]:pl-4 [&_li:not(:first-child)]:mt-1 " +
41
41
  "[&_a]:underline [&_a]:underline-offset-2 [&_a]:text-primary " +
42
- "[&_code]:rounded [&_code]:bg-base-200 [&_code]:px-1 [&_code]:font-mono [&_code]:text-[0.8em] " +
43
- "[&_pre]:mt-2 [&_pre]:overflow-x-auto [&_pre]:rounded [&_pre]:bg-base-200 [&_pre]:p-2 " +
42
+ "[&_code]:rounded-inner [&_code]:bg-base-200 [&_code]:px-1 [&_code]:font-mono [&_code]:text-[0.8em] " +
43
+ "[&_pre]:mt-2 [&_pre]:overflow-x-auto [&_pre]:rounded-inner [&_pre]:bg-base-200 [&_pre]:p-2 " +
44
44
  "[&_h1]:mt-2 [&_h1]:font-semibold [&_h2]:mt-2 [&_h2]:font-semibold " +
45
45
  "[&_h3]:mt-2 [&_h3]:font-semibold [&_h4]:mt-2 [&_h4]:font-semibold " +
46
46
  "[&_blockquote]:mt-2 [&_blockquote]:border-l-2 [&_blockquote]:border-base-200 [&_blockquote]:pl-2";
@@ -209,13 +209,13 @@ export default function ChatPanel({ open, onClose, siteName, tasks, isEditor, dr
209
209
  return (
210
210
  <div role="dialog" aria-label={`Chat with ${siteName}`}
211
211
  className={cn(
212
- "fixed z-40 flex h-[28rem] w-80 flex-col rounded-lg border border-base-200 bg-base shadow-xl",
212
+ "fixed z-40 flex h-[28rem] w-80 flex-col rounded-outer border border-base-200 bg-base shadow-xl",
213
213
  variant === "editor" ? "bottom-4 fab-panel-left max-w-[calc(100vw-5.25rem)]" : "bottom-20 right-4",
214
214
  )}>
215
215
 
216
216
  <div className="flex items-center justify-between gap-2 border-b border-base-200 px-3 py-2">
217
217
  <span className="text-sm font-medium text-base-contrast">Portal Assistant</span>
218
- <IconButton icon={<RemoveIcon size={18} />} label="Close chat" onClick={onClose} className="rounded-md hover:bg-base-accent" />
218
+ <IconButton icon={<RemoveIcon size={18} />} label="Close chat" onClick={onClose} className="rounded-inner hover:bg-base-accent" />
219
219
  </div>
220
220
  {tasks.length > 0 && (
221
221
  <div className="border-b border-base-200 px-3 py-2">
@@ -233,11 +233,11 @@ export default function ChatPanel({ open, onClose, siteName, tasks, isEditor, dr
233
233
  m.role === "assistant" && mdReady && m.content ? (
234
234
  <div
235
235
  key={i}
236
- className={cn("max-w-[85%] rounded-lg bg-base-accent px-3 py-2 text-sm text-base-contrast", MD_STYLES)}
236
+ className={cn("max-w-[85%] rounded-outer bg-base-accent px-3 py-2 text-sm text-base-contrast", MD_STYLES)}
237
237
  dangerouslySetInnerHTML={{ __html: assistantHtml(m.content) }}
238
238
  />
239
239
  ) : (
240
- <div key={i} className={cn("max-w-[85%] whitespace-pre-wrap rounded-lg px-3 py-2 text-sm",
240
+ <div key={i} className={cn("max-w-[85%] whitespace-pre-wrap rounded-outer px-3 py-2 text-sm",
241
241
  m.role === "user" ? "ml-auto bg-primary text-primary-contrast" : "bg-base-accent text-base-contrast")}>
242
242
  {m.content || (busy && i === messages.length - 1 ? "…" : m.content)}
243
243
  </div>
@@ -254,10 +254,10 @@ export default function ChatPanel({ open, onClose, siteName, tasks, isEditor, dr
254
254
  onKeyDown={onComposerKeyDown}
255
255
  placeholder={`Ask about ${siteName}…`}
256
256
  maxLength={4000}
257
- className="max-h-[5.625rem] min-w-0 flex-1 resize-none overflow-y-auto rounded border border-base-200 bg-base px-2 py-1 text-sm text-base-contrast focus:outline-none focus:bg-[color-mix(in_srgb,var(--color-base),var(--color-base-contrast)_5%)]"
257
+ className="max-h-[5.625rem] min-w-0 flex-1 resize-none overflow-y-auto rounded-inner border border-base-200 bg-base px-2 py-1 text-sm text-base-contrast focus:outline-none focus:bg-[color-mix(in_srgb,var(--color-base),var(--color-base-contrast)_5%)]"
258
258
  />
259
259
  <button type="submit" aria-label="Send" disabled={busy}
260
- className="rounded bg-primary px-3 py-1 text-sm text-primary-contrast disabled:opacity-50">→</button>
260
+ className="rounded-inner bg-primary px-3 py-1 text-sm text-primary-contrast disabled:opacity-50">→</button>
261
261
  </form>
262
262
  {isEditor && <p className="border-t border-base-200 px-3 py-1 text-[10px] text-base-contrast-light">Editor view — answers ground on published content.</p>}
263
263
  </div>
@@ -93,7 +93,7 @@ export function ResolvedMedia({
93
93
  )}
94
94
  </>
95
95
  ) : (
96
- <div className="flex aspect-video h-full w-full flex-col items-center justify-center gap-1 rounded bg-base-accent text-base-contrast-light/50">
96
+ <div className="flex aspect-video h-full w-full flex-col items-center justify-center gap-1 rounded-outer bg-base-accent text-base-contrast-light/50">
97
97
  <ImageIcon size={24} />
98
98
  <span className="text-sm">No Image</span>
99
99
  </div>
@@ -12,7 +12,7 @@ interface Props {
12
12
  }
13
13
 
14
14
  export default function Button({ text, link, download, onChange }: Props) {
15
- const base = "inline-block rounded-md px-6 py-3 font-bold transition-colors";
15
+ const base = "inline-block rounded-outer px-6 py-3 font-bold transition-colors";
16
16
  const variant = "border-2 border-primary text-primary hover:bg-primary hover:text-primary-contrast";
17
17
 
18
18
  if (onChange) {
@@ -77,7 +77,7 @@ export function MediaBlock({ refValue, options, link, isEditMode, onRefChange }:
77
77
  <div
78
78
  data-testid="media-open-surface"
79
79
  className={cn(
80
- "overflow-hidden rounded-md",
80
+ "overflow-hidden rounded-outer",
81
81
  showBorder && "border border-base-200",
82
82
  options.square && "aspect-square",
83
83
  onImageClick && "cursor-pointer",
@@ -89,7 +89,7 @@ export default function Navigation({ siteNav: initialNav, siteName, darkMode, la
89
89
  <li key={pid}>
90
90
  <button
91
91
  onClick={() => handleHeadingNav(parent.href)}
92
- className={cn("cursor-pointer w-full rounded px-2 py-1 text-left text-sm transition-colors",
92
+ className={cn("cursor-pointer w-full rounded-inner px-2 py-1 text-left text-sm transition-colors",
93
93
  activeParentId === pid ? "font-bold text-primary" : "text-base-contrast-light hover:text-primary",
94
94
  !isEditMode && parent.status && parent.status !== "live" && "opacity-50")}
95
95
  >
@@ -102,7 +102,7 @@ export default function Navigation({ siteNav: initialNav, siteName, darkMode, la
102
102
  return (
103
103
  <li key={cid}>
104
104
  <button onClick={() => handleHeadingNav(child.href)}
105
- className={cn("cursor-pointer w-full rounded px-2 py-1 text-left text-sm transition-colors",
105
+ className={cn("cursor-pointer w-full rounded-inner px-2 py-1 text-left text-sm transition-colors",
106
106
  activeChildId === cid ? "font-bold text-primary" : "text-base-contrast-light hover:text-primary",
107
107
  !isEditMode && child.status && child.status !== "live" && "opacity-50")}>
108
108
  {child.label}
@@ -150,7 +150,7 @@ export default function Navigation({ siteNav: initialNav, siteName, darkMode, la
150
150
  {asButton ? (
151
151
  <button
152
152
  onClick={() => handlePageClick(page.id)}
153
- className={cn("cursor-pointer w-full rounded px-3 py-2 text-left text-sm font-bold transition-colors",
153
+ className={cn("cursor-pointer w-full rounded-inner px-3 py-2 text-left text-sm font-bold transition-colors",
154
154
  page.isActive ? "text-primary" : "text-base-contrast hover:text-primary")}
155
155
  >
156
156
  {page.title}
@@ -158,7 +158,7 @@ export default function Navigation({ siteNav: initialNav, siteName, darkMode, la
158
158
  ) : (
159
159
  <a
160
160
  href={page.href}
161
- className={cn("block w-full rounded px-3 py-2 text-left text-sm font-bold transition-colors",
161
+ className={cn("block w-full rounded-inner px-3 py-2 text-left text-sm font-bold transition-colors",
162
162
  page.isActive ? "text-primary" : "text-base-contrast hover:text-primary")}
163
163
  >
164
164
  {page.title}
@@ -179,7 +179,7 @@ export default function Navigation({ siteNav: initialNav, siteName, darkMode, la
179
179
  type="button"
180
180
  aria-expanded={isOpen}
181
181
  onClick={() => setOpenGroups((g) => ({ ...g, [label]: !isOpen }))}
182
- className="flex w-full cursor-pointer items-center justify-between rounded px-3 py-1 text-xs font-semibold uppercase tracking-wide text-base-contrast/70 transition-colors hover:text-primary"
182
+ className="flex w-full cursor-pointer items-center justify-between rounded-inner px-3 py-1 text-xs font-semibold uppercase tracking-wide text-base-contrast/70 transition-colors hover:text-primary"
183
183
  >
184
184
  <span>{`${label} (${pages.length})`}</span>
185
185
  <ChevronRight size={14} aria-hidden="true" className={cn("transition-transform", isOpen && "rotate-90")} />
@@ -59,15 +59,15 @@ export function EditorModal({ isOpen, onClose, title, blocking = false, size = "
59
59
  aria-modal="true"
60
60
  aria-labelledby={titleId}
61
61
  className={cn(
62
- "mx-4 w-full rounded-lg bg-base shadow-lg",
62
+ "mx-4 flex w-full flex-col rounded-lg bg-base shadow-lg",
63
63
  size === "large"
64
- ? "max-w-[1400px] max-h-[900px] h-[90vh] flex flex-col"
64
+ ? "max-w-[1400px] max-h-[900px] h-[90vh]"
65
65
  : size === "settings"
66
- ? "max-w-lg flex flex-col min-h-[32rem] max-h-[calc(100vh-4rem)]"
67
- : "max-w-md",
66
+ ? "max-w-lg min-h-[min(32rem,calc(100vh-4rem))] max-h-[calc(100vh-4rem)]"
67
+ : "max-w-md max-h-[calc(100vh-4rem)]",
68
68
  )}
69
69
  >
70
- <div className="flex items-center justify-between border-b border-base-200 px-6 py-4">
70
+ <div className="flex shrink-0 items-center justify-between border-b border-base-200 px-6 py-4">
71
71
  <h3 id={titleId} className="text-lg font-semibold text-base-contrast">{title}</h3>
72
72
  {!blocking && (
73
73
  <IconButton
@@ -81,8 +81,8 @@ export function EditorModal({ isOpen, onClose, title, blocking = false, size = "
81
81
  </div>
82
82
  <div className={cn(
83
83
  !noPadding && "px-6 py-4",
84
- size === "large" && "flex-1 overflow-y-auto",
85
- size === "settings" && "flex-1 flex flex-col overflow-hidden",
84
+ "flex-1 overflow-y-auto",
85
+ size === "settings" && "flex flex-col",
86
86
  )}>
87
87
  {children}
88
88
  </div>
@@ -28,6 +28,7 @@ import { SectionSkeleton } from "./SectionSkeleton";
28
28
  import { SectionTypePicker } from "./SectionTypePicker";
29
29
  import { ensureSectionsRegistered } from "../sections/register";
30
30
  import { getSection, getAllSections, getSchema } from "../../lib/registry";
31
+ import { cornerRadiusValue } from "../../lib/corner-radius";
31
32
  import { childInsertableTypes, insertChildAt } from "../../lib/container-ops";
32
33
  import { buildInsertMenuOptions, resolveInsertedContent } from "../../lib/insert-menu";
33
34
 
@@ -825,6 +826,7 @@ export default function EditorShell({
825
826
  root.style.setProperty("--heading-text-transform", config.uppercaseHeadings ? "uppercase" : "none");
826
827
  root.style.setProperty("--subheading-text-transform", config.uppercaseSubheadings ? "uppercase" : "none");
827
828
  root.style.setProperty("--nav-text-transform", config.uppercaseNavHeadings ? "uppercase" : "none");
829
+ root.style.setProperty("--radius-outer", cornerRadiusValue(config.cornerRadius));
828
830
 
829
831
  if (config.googleFontsUrl) {
830
832
  if (fontLinkRef.current?.href !== config.googleFontsUrl) {
@@ -853,6 +855,7 @@ export default function EditorShell({
853
855
  localStorage.setItem("portal-dark-mode", config.darkMode);
854
856
  localStorage.setItem("portal-primary-color", config.primaryColor);
855
857
  localStorage.setItem("portal-primary-contrast", config.primaryContrast);
858
+ localStorage.setItem("portal-corner-radius", cornerRadiusValue(config.cornerRadius));
856
859
  darkModeEvent.dispatch(config.darkMode);
857
860
  // The nav title lives in a separate island that mounts with a build-time
858
861
  // siteName prop. Push the live (possibly draft) name so editing it in Site
@@ -21,6 +21,13 @@ const darkModeOptions = [
21
21
  { label: "Optional (viewer toggle)", value: "optional" },
22
22
  ];
23
23
 
24
+ const cornerRadiusOptions = [
25
+ { label: "None (square)", value: "none" },
26
+ { label: "Small", value: "small" },
27
+ { label: "Medium", value: "medium" },
28
+ { label: "Large", value: "large" },
29
+ ];
30
+
24
31
  const FAVICON_TYPES = ["image/svg+xml", "image/png"];
25
32
  const FAVICON_MAX_BYTES = 100 * 1024;
26
33
 
@@ -154,6 +161,18 @@ export function SiteSettingsDisplay({ siteConfig, onChange }: Props) {
154
161
  options={darkModeOptions}
155
162
  />
156
163
 
164
+ <div>
165
+ <Select
166
+ label="Corner radius"
167
+ value={siteConfig.cornerRadius}
168
+ onChange={(value) => update({ cornerRadius: value as SiteConfig["cornerRadius"] })}
169
+ options={cornerRadiusOptions}
170
+ />
171
+ <p className="mt-1 text-xs text-base-contrast/70">
172
+ Rounding of cards, media frames, buttons, and panels across the site.
173
+ </p>
174
+ </div>
175
+
157
176
  <FontPicker
158
177
  label="Heading font"
159
178
  value={siteConfig.headingFont}
@@ -0,0 +1,22 @@
1
+ // Corner-radius design token. The site-level `cornerRadius` setting maps to a
2
+ // CSS length for `--radius-outer`; `--radius-inner` derives from it in
3
+ // core/styles/base.css (concentric rule: outer minus the standard 0.25rem
4
+ // gap, floored at 0). Browser-safe: no node imports, no env access.
5
+
6
+ export const CORNER_RADIUS_OPTIONS = ["none", "small", "medium", "large"] as const;
7
+
8
+ export type CornerRadius = (typeof CORNER_RADIUS_OPTIONS)[number];
9
+
10
+ // "medium" matches the pre-token look (Tailwind's rounded-md), so existing
11
+ // sites render unchanged when they take this update.
12
+ export const CORNER_RADIUS_VALUES: Record<CornerRadius, string> = {
13
+ none: "0px",
14
+ small: "0.25rem",
15
+ medium: "0.375rem",
16
+ large: "0.75rem",
17
+ };
18
+
19
+ /** CSS length for `--radius-outer`; unknown/missing values fall back to medium. */
20
+ export function cornerRadiusValue(radius?: string | null): string {
21
+ return CORNER_RADIUS_VALUES[radius as CornerRadius] ?? CORNER_RADIUS_VALUES.medium;
22
+ }
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { MediaConfigSchema } from "./media";
3
3
  import { HexColorSchema, FontNameSchema } from "./shared";
4
+ import { CORNER_RADIUS_OPTIONS } from "../lib/corner-radius";
4
5
 
5
6
  const StatusSchema = z.enum(["draft", "live", "archived", "published"]).transform(
6
7
  (val) => val === "published" ? "live" as const : val,
@@ -177,6 +178,9 @@ export const SiteConfigSchema = z.object({
177
178
  primaryColor: HexColorSchema.default("#009ca6"),
178
179
  primaryContrast: HexColorSchema.default("#f0f0f0"),
179
180
  darkMode: z.enum(["light", "dark", "optional"]).default("light"),
181
+ // Maps to the --radius-outer design token (see lib/corner-radius.ts);
182
+ // defaults so pre-existing site-config.json files keep parsing.
183
+ cornerRadius: z.enum(CORNER_RADIUS_OPTIONS).default("medium"),
180
184
  headingFont: FontNameSchema.default("system-ui"),
181
185
  bodyFont: FontNameSchema.default("system-ui"),
182
186
  uppercaseHeadings: z.boolean().default(true),