@bergetai/ui 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,7 +49,7 @@ Components are organized by category:
49
49
 
50
50
  - **actions** - Interactive controls (Button)
51
51
  - **branding** - Brand identity assets (Logotype, Symbol)
52
- - **data** - Content presentation (CodeBlock, FeatureCards, HeroBlock, List, StatCard)
52
+ - **data** - Content presentation (CodeBlock, FeatureCards, List, StatCard)
53
53
  - **display** - Visual elements (Badge, Card, Icon, Typography)
54
54
  - **feedback** - Status and messaging (Alert, SectionHeader)
55
55
  - **forms** - Form field primitives (Checkbox, Input, Label, Select, Textarea)
package/dist/index.cjs CHANGED
@@ -99,7 +99,6 @@ __export(src_exports, {
99
99
  FieldTitle: () => FieldTitle,
100
100
  FogIllustration: () => FogIllustration,
101
101
  Grid: () => Grid,
102
- HeroBlock: () => HeroBlock,
103
102
  Icon: () => Icon,
104
103
  Input: () => Input2,
105
104
  Item: () => Item2,
@@ -426,21 +425,72 @@ function Button({
426
425
 
427
426
  // src/components/button/Button.tsx
428
427
  var import_jsx_runtime4 = require("react/jsx-runtime");
428
+ var interactionClasses = cn(
429
+ // Outline-based focus indicator; neutralise the primitive's ring (the
430
+ // ring colour class is left — harmless at width 0).
431
+ "focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-berget-button-focus-ring focus-visible:ring-0",
432
+ // Neutralise the primitive's disabled fade; variants apply their own tokens.
433
+ "disabled:pointer-events-none disabled:opacity-100 disabled:cursor-not-allowed",
434
+ // No press movement: same compound selector as the primitive base's 1px
435
+ // active translate so tailwind-merge strips it down to 0.
436
+ "active:not-aria-[haspopup]:translate-y-0"
437
+ );
438
+ var disabledClasses = "disabled:text-berget-button-disabled-fg disabled:shadow-none";
429
439
  function brandVariantClasses(variant) {
430
440
  switch (variant) {
431
441
  case "primary":
432
- return "bg-berget-button-primary-bg text-berget-button-primary-fg shadow-berget-lg hover:bg-berget-button-primary-hover hover:shadow-berget-lg";
442
+ return cn(
443
+ // Flat tinted-glass fill; the alpha carries the state, so no shadow lift.
444
+ "bg-berget-button-primary-bg text-berget-button-primary-fg",
445
+ "hover:bg-berget-button-primary-hover",
446
+ // Pin the foreground on hover — the underlying primitive ghost adds
447
+ // hover:text-foreground, which would override the primary fg token.
448
+ "hover:text-berget-button-primary-fg",
449
+ "active:bg-berget-button-primary-active",
450
+ // Keep the resting (transparent) border on focus — the outline is the indicator.
451
+ "focus-visible:border-transparent",
452
+ disabledClasses,
453
+ "disabled:bg-berget-button-primary-disabled-bg"
454
+ );
433
455
  case "destructive":
434
- return "bg-berget-button-destructive-bg text-berget-button-destructive-fg shadow-berget-sm hover:bg-berget-button-destructive-bg/80 hover:shadow-berget-sm dark:hover:bg-berget-button-destructive-bg/80 dark:hover:text-berget-button-destructive-fg";
435
- case "outline":
436
- return "border-berget-border-interactive bg-transparent text-berget-foreground hover:bg-berget-surface-hover hover:text-berget-foreground hover:border-berget-border-interactive-elevated";
437
- case "ghost":
438
- return "bg-transparent text-berget-foreground hover:bg-berget-brand-granite-800 hover:text-berget-foreground";
456
+ return cn(
457
+ "bg-berget-button-destructive-bg text-berget-button-destructive-fg",
458
+ "hover:bg-berget-button-destructive-hover",
459
+ // Pin the foreground on hover — the underlying primitive ghost adds
460
+ // hover:text-foreground, which would override the destructive fg token.
461
+ "hover:text-berget-button-destructive-hover-fg",
462
+ "active:bg-berget-button-destructive-active",
463
+ "focus-visible:border-transparent",
464
+ disabledClasses,
465
+ "disabled:bg-berget-button-destructive-disabled-bg"
466
+ );
439
467
  case "link":
440
- return "bg-transparent hover:bg-transparent focus:bg-transparent active:bg-transparent text-berget-button-link-fg underline-offset-4 hover:underline";
468
+ return cn(
469
+ "h-auto bg-transparent p-0 text-berget-button-link-fg underline-offset-4 shadow-none",
470
+ "hover:bg-transparent hover:text-berget-button-link-hover-fg",
471
+ // On press, return to the resting foreground (hover fg otherwise sticks).
472
+ "active:text-berget-button-link-fg",
473
+ "focus:bg-transparent",
474
+ // Neutralise the primitive base's focus-visible:border-ring + ring-3,
475
+ // which land on link too (the primitive merges its cva base under
476
+ // every variant): the outline above is the only focus indicator.
477
+ "focus-visible:border-transparent focus-visible:ring-0",
478
+ "focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-berget-button-focus-ring focus-visible:rounded-berget-xs",
479
+ "disabled:text-berget-button-disabled-fg disabled:no-underline",
480
+ "disabled:opacity-100 disabled:cursor-not-allowed"
481
+ );
441
482
  case "default":
442
483
  default:
443
- return "bg-berget-button-default-bg text-berget-button-default-fg shadow-berget-lg hover:bg-berget-button-default-bg/90 hover:shadow-berget-lg";
484
+ return cn(
485
+ // Solid granite-800 fill with a granite-700 border on dark surfaces
486
+ // (ink glass in light theme).
487
+ "bg-berget-button-default-bg border-berget-button-default-border text-berget-button-default-fg",
488
+ "hover:bg-berget-button-default-hover",
489
+ "active:bg-berget-button-default-active",
490
+ "focus-visible:border-transparent",
491
+ disabledClasses,
492
+ "disabled:bg-berget-button-default-disabled-bg"
493
+ );
444
494
  }
445
495
  }
446
496
  function primitiveVariant(variant) {
@@ -467,9 +517,16 @@ function Button2({
467
517
  const isLink = variant === "link";
468
518
  const baseClass = cn(
469
519
  !isLink && buttonVariants({ variant: primitiveVariant(variant), size }),
470
- // Berget brand overrides
471
- !isLink && "rounded-full",
520
+ // Berget brand overrides — full-width buttons use the square radius;
521
+ // everything else stays pill-shaped.
522
+ !isLink && (width === "full" ? "rounded-berget-xs" : "rounded-full"),
523
+ // Em-based padding, inline = 2× block — matches the 8px/16px spacing-scale
524
+ // values at the default text-sm (14px) and scales down/up with smaller or
525
+ // larger button text. h-auto drops the primitive's fixed h-* so the
526
+ // vertical paddings take effect.
527
+ !isLink && !isIcon && "py-[0.57em] px-[1.14em] h-auto",
472
528
  brandVariantClasses(variant),
529
+ interactionClasses,
473
530
  !isLink && width === "full" && "w-full",
474
531
  isIcon && "rounded-full shadow-[0px_1px_3px_rgba(0,0,0,0.1),0px_1px_2px_-1px_rgba(0,0,0,0.1)]",
475
532
  className
@@ -577,7 +634,7 @@ function Card({
577
634
  "data-slot": "card",
578
635
  "data-size": size,
579
636
  className: (0, import_cn2.cn)(
580
- "group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",
637
+ "group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-berget-xs bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",
581
638
  className
582
639
  ),
583
640
  ...props
@@ -646,7 +703,7 @@ function CardFooter({ className, ...props }) {
646
703
 
647
704
  // src/components/card/Card.tsx
648
705
  var import_jsx_runtime7 = require("react/jsx-runtime");
649
- var cardVariants = (0, import_class_variance_authority3.cva)("rounded-berget-sm ring-0", {
706
+ var cardVariants = (0, import_class_variance_authority3.cva)("rounded-berget-xs ring-0", {
650
707
  variants: {
651
708
  variant: {
652
709
  outlined: "bg-transparent border border-berget-border-subtle",
@@ -986,7 +1043,7 @@ var ModelCard = React9.forwardRef(
986
1043
  {
987
1044
  variant: "filled",
988
1045
  padding: "none",
989
- className: "relative flex h-full flex-col bg-berget-card-filled-bg p-5 transition-all hover:bg-[color-mix(in_oklab,var(--berget-brand-granite-100)_5%,var(--berget-card-filled-bg))] hover:ring-2 hover:ring-berget-brand-granite-700 sm:p-6",
1046
+ className: "relative flex h-full flex-col bg-berget-card-filled-bg p-5 transition-all hover:bg-[color-mix(in_oklab,var(--berget-brand-granite-100)_5%,var(--berget-card-filled-bg))] sm:p-6",
990
1047
  children: [
991
1048
  lifecycle && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "absolute top-0 right-0 z-10 overflow-hidden rounded-bl-berget-sm", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
992
1049
  "div",
@@ -4029,41 +4086,6 @@ var FeatureList = React29.forwardRef(
4029
4086
  );
4030
4087
  FeatureList.displayName = "FeatureList";
4031
4088
 
4032
- // src/components/hero-block/HeroBlock.tsx
4033
- var React30 = __toESM(require("react"), 1);
4034
- var import_jsx_runtime45 = require("react/jsx-runtime");
4035
- var HeroBlock = React30.forwardRef(
4036
- ({ className, taglineIcon: TaglineIcon, tagline, title, description, actions, ...props }, ref) => {
4037
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
4038
- "div",
4039
- {
4040
- ref,
4041
- className: cn(
4042
- "relative overflow-hidden min-h-[40dvh] flex items-center py-fluid-2xl",
4043
- className
4044
- ),
4045
- ...props,
4046
- children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "mx-auto text-center max-w-4xl", children: [
4047
- tagline && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
4048
- Badge,
4049
- {
4050
- variant: "default",
4051
- icon: TaglineIcon ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Icon, { icon: TaglineIcon, size: 16 }) : void 0,
4052
- iconGap: 2,
4053
- className: "mb-fluid-md",
4054
- children: tagline
4055
- }
4056
- ),
4057
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Typography, { variant: "h1", className: "mb-fluid-md", children: title }),
4058
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Typography, { variant: "h3", color: "muted", className: "mb-fluid-lg", children: description }),
4059
- actions && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "flex flex-wrap gap-fluid-md justify-center", children: actions })
4060
- ] }) })
4061
- }
4062
- );
4063
- }
4064
- );
4065
- HeroBlock.displayName = "HeroBlock";
4066
-
4067
4089
  // src/components/code-block/CodeBlock.tsx
4068
4090
  var import_react2 = require("react");
4069
4091
  var import_lucide_react15 = require("lucide-react");
@@ -4107,7 +4129,7 @@ function getHighlighter() {
4107
4129
  }
4108
4130
 
4109
4131
  // src/components/code-block/CodeBlock.tsx
4110
- var import_jsx_runtime46 = require("react/jsx-runtime");
4132
+ var import_jsx_runtime45 = require("react/jsx-runtime");
4111
4133
  function CodeBlock({ code, language = "text", title, className }) {
4112
4134
  const [html, setHtml] = (0, import_react2.useState)(null);
4113
4135
  const [copied, setCopied] = (0, import_react2.useState)(false);
@@ -4123,42 +4145,42 @@ function CodeBlock({ code, language = "text", title, className }) {
4123
4145
  setCopied(true);
4124
4146
  setTimeout(() => setCopied(false), 2e3);
4125
4147
  }, [code]);
4126
- const copyButton = /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
4148
+ const copyButton = /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
4127
4149
  "button",
4128
4150
  {
4129
4151
  onClick: handleCopy,
4130
4152
  className: "flex items-center justify-center w-6 h-6 text-berget-muted-foreground hover:text-berget-foreground transition-colors",
4131
4153
  "aria-label": "Copy code",
4132
- children: copied ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react15.Check, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react15.Copy, { className: "w-3.5 h-3.5" })
4154
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react15.Check, { className: "w-3.5 h-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react15.Copy, { className: "w-3.5 h-3.5" })
4133
4155
  }
4134
4156
  );
4135
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
4157
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
4136
4158
  "div",
4137
4159
  {
4138
4160
  className: cn(
4139
- "rounded-berget-sm border bg-berget-codeblock-bg border-berget-border backdrop-blur-[12px] relative overflow-hidden isolate",
4161
+ "rounded-berget-xs border bg-berget-codeblock-bg border-berget-border backdrop-blur-[12px] relative overflow-hidden isolate",
4140
4162
  className
4141
4163
  ),
4142
4164
  children: [
4143
- title && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "!h-10 flex items-center !px-4 !text-xs !leading-normal border-b border-berget-border bg-berget-codeblock-header-bg", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-berget-muted-foreground", children: title }) }),
4144
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "absolute right-2 top-2 z-10", children: copyButton }),
4145
- html ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
4165
+ title && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "!h-10 flex items-center !px-4 !text-xs !leading-normal border-b border-berget-border bg-berget-codeblock-header-bg", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "text-berget-muted-foreground", children: title }) }),
4166
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "absolute right-2 top-2 z-10", children: copyButton }),
4167
+ html ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
4146
4168
  "div",
4147
4169
  {
4148
4170
  className: "[&_.shiki]:!p-4 [&_.shiki]:!m-0 [&_.shiki]:overflow-x-auto [&_.shiki]:!text-sm [&_.shiki]:!leading-relaxed [&_.shiki]:bg-transparent",
4149
4171
  dangerouslySetInnerHTML: { __html: html }
4150
4172
  }
4151
- ) : /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("pre", { className: "!p-4 !m-0 overflow-x-auto !text-sm !leading-relaxed text-berget-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("code", { children: code }) })
4173
+ ) : /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("pre", { className: "!p-4 !m-0 overflow-x-auto !text-sm !leading-relaxed text-berget-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("code", { children: code }) })
4152
4174
  ]
4153
4175
  }
4154
4176
  );
4155
4177
  }
4156
4178
 
4157
4179
  // src/components/window-frame/WindowFrame.tsx
4158
- var React31 = __toESM(require("react"), 1);
4180
+ var React30 = __toESM(require("react"), 1);
4159
4181
  var import_react3 = require("react");
4160
- var import_jsx_runtime47 = require("react/jsx-runtime");
4161
- var WindowFrame = React31.forwardRef(
4182
+ var import_jsx_runtime46 = require("react/jsx-runtime");
4183
+ var WindowFrame = React30.forwardRef(
4162
4184
  ({ title = "window", tabs, activeTab, onTabChange, children, className, ...props }, ref) => {
4163
4185
  const [internalActive, setInternalActive] = (0, import_react3.useState)(tabs?.[0]?.id ?? "");
4164
4186
  const currentTab = activeTab ?? internalActive;
@@ -4169,7 +4191,7 @@ var WindowFrame = React31.forwardRef(
4169
4191
  setInternalActive(id);
4170
4192
  }
4171
4193
  };
4172
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
4194
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
4173
4195
  "div",
4174
4196
  {
4175
4197
  ref,
@@ -4179,13 +4201,13 @@ var WindowFrame = React31.forwardRef(
4179
4201
  ),
4180
4202
  ...props,
4181
4203
  children: [
4182
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2 px-4 py-3 border-b border-berget-brand-granite-700 bg-berget-brand-granite-900", children: [
4183
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-2 flex-shrink-0", children: [
4184
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "w-3 h-3 rounded-full bg-berget-brand-muscaria-400" }),
4185
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "w-3 h-3 rounded-full bg-berget-brand-chanterelle-200" }),
4186
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "w-3 h-3 rounded-full bg-berget-brand-moss-400" })
4204
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-2 px-4 py-3 border-b border-berget-brand-granite-700 bg-berget-brand-granite-900", children: [
4205
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-2 flex-shrink-0", children: [
4206
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "w-3 h-3 rounded-full bg-berget-brand-muscaria-400" }),
4207
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "w-3 h-3 rounded-full bg-berget-brand-chanterelle-200" }),
4208
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "w-3 h-3 rounded-full bg-berget-brand-moss-400" })
4187
4209
  ] }),
4188
- tabs && tabs.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "ml-4 flex items-center gap-1", children: tabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
4210
+ tabs && tabs.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "ml-4 flex items-center gap-1", children: tabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
4189
4211
  "button",
4190
4212
  {
4191
4213
  type: "button",
@@ -4197,9 +4219,9 @@ var WindowFrame = React31.forwardRef(
4197
4219
  children: tab.label
4198
4220
  },
4199
4221
  tab.id
4200
- )) }) : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "ml-4 text-sm font-mono text-berget-brand-moss-400", children: title })
4222
+ )) }) : /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "ml-4 text-sm font-mono text-berget-brand-moss-400", children: title })
4201
4223
  ] }),
4202
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { children })
4224
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { children })
4203
4225
  ]
4204
4226
  }
4205
4227
  );
@@ -4209,7 +4231,7 @@ WindowFrame.displayName = "WindowFrame";
4209
4231
 
4210
4232
  // src/components/fog-illustration/FogIllustration.tsx
4211
4233
  var import_react4 = require("react");
4212
- var import_jsx_runtime48 = require("react/jsx-runtime");
4234
+ var import_jsx_runtime47 = require("react/jsx-runtime");
4213
4235
  var FOG_BRAND_PALETTE = {
4214
4236
  ink: "#171a1a",
4215
4237
  milk: "#f7f5ed",
@@ -4522,7 +4544,7 @@ var FogIllustration = ({ palette, speed = 1, className }) => {
4522
4544
  gl.deleteFramebuffer(fbo);
4523
4545
  };
4524
4546
  }, []);
4525
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("canvas", { ref, "aria-hidden": "true", className: cn("size-full", className) });
4547
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("canvas", { ref, "aria-hidden": "true", className: cn("size-full", className) });
4526
4548
  };
4527
4549
  // Annotate the CommonJS export names for ESM import in node:
4528
4550
  0 && (module.exports = {
@@ -4595,7 +4617,6 @@ var FogIllustration = ({ palette, speed = 1, className }) => {
4595
4617
  FieldTitle,
4596
4618
  FogIllustration,
4597
4619
  Grid,
4598
- HeroBlock,
4599
4620
  Icon,
4600
4621
  Input,
4601
4622
  Item,