@handled-ai/design-system 0.18.26 → 0.18.27

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.
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const badgeVariants: (props?: ({
6
- variant?: "link" | "default" | "secondary" | "destructive" | "outline" | "ghost" | null | undefined;
6
+ variant?: "default" | "secondary" | "destructive" | "outline" | "ghost" | "link" | null | undefined;
7
7
  } & class_variance_authority_types.ClassProp) | undefined) => string;
8
8
  declare function Badge({ className, variant, asChild, ...props }: React.ComponentProps<"span"> & VariantProps<typeof badgeVariants> & {
9
9
  asChild?: boolean;
@@ -3,7 +3,7 @@ import * as React from 'react';
3
3
  import { VariantProps } from 'class-variance-authority';
4
4
 
5
5
  declare const buttonVariants: (props?: ({
6
- variant?: "link" | "default" | "secondary" | "destructive" | "outline" | "ghost" | null | undefined;
6
+ variant?: "default" | "secondary" | "destructive" | "outline" | "ghost" | "link" | null | undefined;
7
7
  size?: "default" | "sm" | "lg" | "icon" | null | undefined;
8
8
  } & class_variance_authority_types.ClassProp) | undefined) => string;
9
9
  declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
 
3
- type CasePanelDetailWidth = "comfortable" | "modest" | "full";
3
+ type CasePanelDetailWidth = "comfortable" | "modest" | "compact" | "full";
4
4
  interface CasePanelDetailProps {
5
5
  children: React.ReactNode;
6
6
  /** Reading measure for the detail content column. Defaults to the handoff's comfortable 880px measure. */
@@ -13,6 +13,7 @@ import { cn } from "../lib/utils.js";
13
13
  const detailWidthClasses = {
14
14
  comfortable: "mx-auto w-full max-w-[880px] px-10 pb-[120px] pt-8",
15
15
  modest: "mx-auto w-full max-w-[720px] px-8 pb-[112px] pt-7",
16
+ compact: "mx-auto w-full max-w-[640px] px-10 pb-[112px] pt-7",
16
17
  full: "w-full px-8 pb-[120px] pt-8"
17
18
  };
18
19
  function CasePanelDetail({
@@ -29,9 +30,9 @@ function CasePanelHeader({
29
30
  children,
30
31
  className
31
32
  }) {
32
- return /* @__PURE__ */ jsx("header", { className: cn("mb-7", className), children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-5", children: [
33
+ return /* @__PURE__ */ jsx("header", { className: cn("mb-7", className), children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between gap-6", children: [
33
34
  /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
34
- /* @__PURE__ */ jsx("h1", { className: "m-0 text-[27px] font-bold leading-[1.18] tracking-[-0.02em] text-foreground [text-wrap:balance]", children: title }),
35
+ /* @__PURE__ */ jsx("h1", { className: "m-0 max-w-[560px] text-[27px] font-bold leading-[1.18] tracking-[-0.02em] text-foreground", children: title }),
35
36
  children
36
37
  ] }),
37
38
  action ? /* @__PURE__ */ jsx("div", { className: "flex shrink-0 items-center gap-2", children: action }) : null
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/case-panel-detail.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n ArrowUpRight,\n Check,\n Copy,\n ExternalLink,\n} from \"lucide-react\"\nimport { cn } from \"../lib/utils\"\n\nexport type CasePanelDetailWidth = \"comfortable\" | \"modest\" | \"full\"\n\nexport interface CasePanelDetailProps {\n children: React.ReactNode\n /** Reading measure for the detail content column. Defaults to the handoff's comfortable 880px measure. */\n width?: CasePanelDetailWidth\n /** Accessible label for the detail region. */\n \"aria-label\"?: string\n className?: string\n}\n\nconst detailWidthClasses: Record<CasePanelDetailWidth, string> = {\n comfortable: \"mx-auto w-full max-w-[880px] px-10 pb-[120px] pt-8\",\n modest: \"mx-auto w-full max-w-[720px] px-8 pb-[112px] pt-7\",\n full: \"w-full px-8 pb-[120px] pt-8\",\n}\n\nexport function CasePanelDetail({\n children,\n width = \"comfortable\",\n \"aria-label\": ariaLabel = \"Case detail\",\n className,\n}: CasePanelDetailProps) {\n return (\n <section aria-label={ariaLabel} className={cn(\"min-w-0 bg-background\", className)}>\n <div className={detailWidthClasses[width]}>{children}</div>\n </section>\n )\n}\n\nexport interface CasePanelHeaderProps {\n title: React.ReactNode\n /** Optional action, usually a Quick action trigger. */\n action?: React.ReactNode\n children?: React.ReactNode\n className?: string\n}\n\nexport function CasePanelHeader({\n title,\n action,\n children,\n className,\n}: CasePanelHeaderProps) {\n return (\n <header className={cn(\"mb-7\", className)}>\n <div className=\"flex items-start justify-between gap-5\">\n <div className=\"min-w-0 flex-1\">\n <h1 className=\"m-0 text-[27px] font-bold leading-[1.18] tracking-[-0.02em] text-foreground [text-wrap:balance]\">\n {title}\n </h1>\n {children}\n </div>\n {action ? <div className=\"flex shrink-0 items-center gap-2\">{action}</div> : null}\n </div>\n </header>\n )\n}\n\nexport interface CasePanelIdentityLink {\n id: string\n label: string\n href?: string\n icon?: React.ReactNode\n kind?: \"icon\" | \"text\"\n disabled?: boolean\n target?: React.HTMLAttributeAnchorTarget\n rel?: string\n}\n\nexport interface CasePanelIdentitySublineProps {\n callsign?: string | null\n links?: CasePanelIdentityLink[]\n onCopyCallsign?: (callsign: string) => void\n copyLabel?: string\n copiedLabel?: string\n className?: string\n}\n\nexport function CasePanelIdentitySubline({\n callsign,\n links = [],\n onCopyCallsign,\n copyLabel = \"Copy call sign\",\n copiedLabel = \"Call sign copied\",\n className,\n}: CasePanelIdentitySublineProps) {\n const [copied, setCopied] = React.useState(false)\n const trimmedCallsign = callsign?.trim()\n const normalizedCallsign = trimmedCallsign\n ? trimmedCallsign.startsWith(\"@\")\n ? trimmedCallsign\n : `@${trimmedCallsign}`\n : null\n\n const handleCopy = React.useCallback(() => {\n if (!normalizedCallsign) return\n onCopyCallsign?.(normalizedCallsign)\n setCopied(true)\n window.setTimeout(() => setCopied(false), 1400)\n }, [normalizedCallsign, onCopyCallsign])\n\n return (\n <div className={cn(\"mt-[9px] inline-flex flex-wrap items-center gap-[7px] text-[13px] text-muted-foreground\", className)}>\n {normalizedCallsign ? (\n <>\n <span className=\"font-mono font-medium tracking-[0.01em] text-gray-700\">{normalizedCallsign}</span>\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={copied ? copiedLabel : copyLabel}\n className=\"inline-flex h-[22px] w-[22px] items-center justify-center rounded-md text-gray-400 transition-colors hover:bg-accent hover:text-foreground\"\n >\n {copied ? <Check className=\"h-[13px] w-[13px] text-emerald-700\" aria-hidden=\"true\" /> : <Copy className=\"h-[13px] w-[13px]\" aria-hidden=\"true\" />}\n </button>\n </>\n ) : null}\n {links.length > 0 ? (\n <>\n {normalizedCallsign ? <span aria-hidden=\"true\" className=\"mx-[3px] h-3.5 w-px bg-gray-200\" /> : null}\n <span className=\"inline-flex items-center gap-1.5\">\n {links.map((link) => (\n <CasePanelIdentityLinkButton key={link.id} link={link} />\n ))}\n </span>\n </>\n ) : null}\n </div>\n )\n}\n\nfunction CasePanelIdentityLinkButton({ link }: { link: CasePanelIdentityLink }) {\n const disabled = link.disabled || !link.href\n const iconOnly = link.kind === \"icon\"\n const content = iconOnly ? (\n <>{link.icon ?? <ExternalLink className=\"h-[13px] w-[13px]\" aria-hidden=\"true\" />}</>\n ) : (\n <>\n {link.icon ? <span className=\"inline-flex h-3.5 w-3.5 items-center justify-center\">{link.icon}</span> : null}\n <span>{link.label}</span>\n <ArrowUpRight className=\"h-[11px] w-[11px] text-gray-400\" aria-hidden=\"true\" />\n </>\n )\n\n const className = iconOnly\n ? \"inline-flex h-[26px] w-[26px] items-center justify-center rounded-[7px] border border-border bg-background text-foreground shadow-[0_1px_1.5px_rgba(0,0,0,0.03)] transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-45\"\n : \"inline-flex h-[26px] items-center gap-1.5 rounded-[7px] border border-border bg-background px-2 text-xs font-medium text-foreground shadow-[0_1px_1.5px_rgba(0,0,0,0.03)] transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-45\"\n\n if (disabled) {\n return (\n <button type=\"button\" disabled aria-label={link.label} className={className}>\n {content}\n </button>\n )\n }\n\n return (\n <a\n href={link.href}\n aria-label={link.label}\n target={link.target ?? \"_blank\"}\n rel={link.rel ?? \"noopener noreferrer\"}\n className={className}\n >\n {content}\n </a>\n )\n}\n\nexport interface CasePanelSignalBriefProps {\n children: React.ReactNode\n label?: string\n className?: string\n}\n\nexport function CasePanelSignalBrief({\n children,\n label = \"Signal brief\",\n className,\n}: CasePanelSignalBriefProps) {\n return (\n <section className={cn(\"mt-7\", className)} aria-labelledby=\"case-panel-signal-brief-heading\">\n <div id=\"case-panel-signal-brief-heading\" className=\"mb-2.5 text-[11px] font-semibold uppercase tracking-[0.07em] text-muted-foreground\">\n {label}\n </div>\n <div className=\"text-base leading-[1.6] text-foreground [text-wrap:pretty]\">{children}</div>\n </section>\n )\n}\n\nexport interface CasePanelMetadataRowProps {\n children: React.ReactNode\n label?: string\n className?: string\n}\n\nexport function CasePanelMetadataRow({\n children,\n label = \"Case metadata\",\n className,\n}: CasePanelMetadataRowProps) {\n return (\n <div aria-label={label} className={cn(\"mt-[18px] flex flex-wrap items-center gap-2\", className)}>\n {children}\n </div>\n )\n}\n\nexport interface CasePanelDetailSlotsProps {\n why?: React.ReactNode\n actions?: React.ReactNode\n opportunity?: React.ReactNode\n timeline?: React.ReactNode\n playPanel?: React.ReactNode\n className?: string\n}\n\nexport function CasePanelDetailSlots({\n why,\n actions,\n opportunity,\n timeline,\n playPanel,\n className,\n}: CasePanelDetailSlotsProps) {\n return (\n <div className={cn(\"mt-7 space-y-6\", className)}>\n {why ? <div data-slot=\"why\">{why}</div> : null}\n {actions ? <div data-slot=\"actions\">{actions}</div> : null}\n {opportunity ? <div data-slot=\"opportunity\">{opportunity}</div> : null}\n {timeline ? <div data-slot=\"timeline\">{timeline}</div> : null}\n {playPanel ? <div data-slot=\"play-panel\">{playPanel}</div> : null}\n </div>\n )\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/case-panel-detail.tsx"],"sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport {\n ArrowUpRight,\n Check,\n Copy,\n ExternalLink,\n} from \"lucide-react\"\nimport { cn } from \"../lib/utils\"\n\nexport type CasePanelDetailWidth = \"comfortable\" | \"modest\" | \"compact\" | \"full\"\n\nexport interface CasePanelDetailProps {\n children: React.ReactNode\n /** Reading measure for the detail content column. Defaults to the handoff's comfortable 880px measure. */\n width?: CasePanelDetailWidth\n /** Accessible label for the detail region. */\n \"aria-label\"?: string\n className?: string\n}\n\nconst detailWidthClasses: Record<CasePanelDetailWidth, string> = {\n comfortable: \"mx-auto w-full max-w-[880px] px-10 pb-[120px] pt-8\",\n modest: \"mx-auto w-full max-w-[720px] px-8 pb-[112px] pt-7\",\n compact: \"mx-auto w-full max-w-[640px] px-10 pb-[112px] pt-7\",\n full: \"w-full px-8 pb-[120px] pt-8\",\n}\n\nexport function CasePanelDetail({\n children,\n width = \"comfortable\",\n \"aria-label\": ariaLabel = \"Case detail\",\n className,\n}: CasePanelDetailProps) {\n return (\n <section aria-label={ariaLabel} className={cn(\"min-w-0 bg-background\", className)}>\n <div className={detailWidthClasses[width]}>{children}</div>\n </section>\n )\n}\n\nexport interface CasePanelHeaderProps {\n title: React.ReactNode\n /** Optional action, usually a Quick action trigger. */\n action?: React.ReactNode\n children?: React.ReactNode\n className?: string\n}\n\nexport function CasePanelHeader({\n title,\n action,\n children,\n className,\n}: CasePanelHeaderProps) {\n return (\n <header className={cn(\"mb-7\", className)}>\n <div className=\"flex items-start justify-between gap-6\">\n <div className=\"min-w-0 flex-1\">\n <h1 className=\"m-0 max-w-[560px] text-[27px] font-bold leading-[1.18] tracking-[-0.02em] text-foreground\">\n {title}\n </h1>\n {children}\n </div>\n {action ? <div className=\"flex shrink-0 items-center gap-2\">{action}</div> : null}\n </div>\n </header>\n )\n}\n\nexport interface CasePanelIdentityLink {\n id: string\n label: string\n href?: string\n icon?: React.ReactNode\n kind?: \"icon\" | \"text\"\n disabled?: boolean\n target?: React.HTMLAttributeAnchorTarget\n rel?: string\n}\n\nexport interface CasePanelIdentitySublineProps {\n callsign?: string | null\n links?: CasePanelIdentityLink[]\n onCopyCallsign?: (callsign: string) => void\n copyLabel?: string\n copiedLabel?: string\n className?: string\n}\n\nexport function CasePanelIdentitySubline({\n callsign,\n links = [],\n onCopyCallsign,\n copyLabel = \"Copy call sign\",\n copiedLabel = \"Call sign copied\",\n className,\n}: CasePanelIdentitySublineProps) {\n const [copied, setCopied] = React.useState(false)\n const trimmedCallsign = callsign?.trim()\n const normalizedCallsign = trimmedCallsign\n ? trimmedCallsign.startsWith(\"@\")\n ? trimmedCallsign\n : `@${trimmedCallsign}`\n : null\n\n const handleCopy = React.useCallback(() => {\n if (!normalizedCallsign) return\n onCopyCallsign?.(normalizedCallsign)\n setCopied(true)\n window.setTimeout(() => setCopied(false), 1400)\n }, [normalizedCallsign, onCopyCallsign])\n\n return (\n <div className={cn(\"mt-[9px] inline-flex flex-wrap items-center gap-[7px] text-[13px] text-muted-foreground\", className)}>\n {normalizedCallsign ? (\n <>\n <span className=\"font-mono font-medium tracking-[0.01em] text-gray-700\">{normalizedCallsign}</span>\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={copied ? copiedLabel : copyLabel}\n className=\"inline-flex h-[22px] w-[22px] items-center justify-center rounded-md text-gray-400 transition-colors hover:bg-accent hover:text-foreground\"\n >\n {copied ? <Check className=\"h-[13px] w-[13px] text-emerald-700\" aria-hidden=\"true\" /> : <Copy className=\"h-[13px] w-[13px]\" aria-hidden=\"true\" />}\n </button>\n </>\n ) : null}\n {links.length > 0 ? (\n <>\n {normalizedCallsign ? <span aria-hidden=\"true\" className=\"mx-[3px] h-3.5 w-px bg-gray-200\" /> : null}\n <span className=\"inline-flex items-center gap-1.5\">\n {links.map((link) => (\n <CasePanelIdentityLinkButton key={link.id} link={link} />\n ))}\n </span>\n </>\n ) : null}\n </div>\n )\n}\n\nfunction CasePanelIdentityLinkButton({ link }: { link: CasePanelIdentityLink }) {\n const disabled = link.disabled || !link.href\n const iconOnly = link.kind === \"icon\"\n const content = iconOnly ? (\n <>{link.icon ?? <ExternalLink className=\"h-[13px] w-[13px]\" aria-hidden=\"true\" />}</>\n ) : (\n <>\n {link.icon ? <span className=\"inline-flex h-3.5 w-3.5 items-center justify-center\">{link.icon}</span> : null}\n <span>{link.label}</span>\n <ArrowUpRight className=\"h-[11px] w-[11px] text-gray-400\" aria-hidden=\"true\" />\n </>\n )\n\n const className = iconOnly\n ? \"inline-flex h-[26px] w-[26px] items-center justify-center rounded-[7px] border border-border bg-background text-foreground shadow-[0_1px_1.5px_rgba(0,0,0,0.03)] transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-45\"\n : \"inline-flex h-[26px] items-center gap-1.5 rounded-[7px] border border-border bg-background px-2 text-xs font-medium text-foreground shadow-[0_1px_1.5px_rgba(0,0,0,0.03)] transition-colors hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-45\"\n\n if (disabled) {\n return (\n <button type=\"button\" disabled aria-label={link.label} className={className}>\n {content}\n </button>\n )\n }\n\n return (\n <a\n href={link.href}\n aria-label={link.label}\n target={link.target ?? \"_blank\"}\n rel={link.rel ?? \"noopener noreferrer\"}\n className={className}\n >\n {content}\n </a>\n )\n}\n\nexport interface CasePanelSignalBriefProps {\n children: React.ReactNode\n label?: string\n className?: string\n}\n\nexport function CasePanelSignalBrief({\n children,\n label = \"Signal brief\",\n className,\n}: CasePanelSignalBriefProps) {\n return (\n <section className={cn(\"mt-7\", className)} aria-labelledby=\"case-panel-signal-brief-heading\">\n <div id=\"case-panel-signal-brief-heading\" className=\"mb-2.5 text-[11px] font-semibold uppercase tracking-[0.07em] text-muted-foreground\">\n {label}\n </div>\n <div className=\"text-base leading-[1.6] text-foreground [text-wrap:pretty]\">{children}</div>\n </section>\n )\n}\n\nexport interface CasePanelMetadataRowProps {\n children: React.ReactNode\n label?: string\n className?: string\n}\n\nexport function CasePanelMetadataRow({\n children,\n label = \"Case metadata\",\n className,\n}: CasePanelMetadataRowProps) {\n return (\n <div aria-label={label} className={cn(\"mt-[18px] flex flex-wrap items-center gap-2\", className)}>\n {children}\n </div>\n )\n}\n\nexport interface CasePanelDetailSlotsProps {\n why?: React.ReactNode\n actions?: React.ReactNode\n opportunity?: React.ReactNode\n timeline?: React.ReactNode\n playPanel?: React.ReactNode\n className?: string\n}\n\nexport function CasePanelDetailSlots({\n why,\n actions,\n opportunity,\n timeline,\n playPanel,\n className,\n}: CasePanelDetailSlotsProps) {\n return (\n <div className={cn(\"mt-7 space-y-6\", className)}>\n {why ? <div data-slot=\"why\">{why}</div> : null}\n {actions ? <div data-slot=\"actions\">{actions}</div> : null}\n {opportunity ? <div data-slot=\"opportunity\">{opportunity}</div> : null}\n {timeline ? <div data-slot=\"timeline\">{timeline}</div> : null}\n {playPanel ? <div data-slot=\"play-panel\">{playPanel}</div> : null}\n </div>\n )\n}\n"],"mappings":"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","names":[]}
@@ -12,7 +12,7 @@ import { VariantProps } from 'class-variance-authority';
12
12
  */
13
13
  type PillStatus = "success" | "warning" | "error" | "neutral" | "info";
14
14
  declare const pillVariants: (props?: ({
15
- variant?: "error" | "default" | "secondary" | "destructive" | "outline" | "ghost" | "neutral" | "info" | "success" | "warning" | null | undefined;
15
+ variant?: "default" | "secondary" | "destructive" | "outline" | "ghost" | "error" | "neutral" | "info" | "success" | "warning" | null | undefined;
16
16
  } & class_variance_authority_types.ClassProp) | undefined) => string;
17
17
  interface PillProps extends React.ComponentProps<"span">, VariantProps<typeof pillVariants> {
18
18
  }
@@ -5,7 +5,7 @@ import { Tabs as Tabs$1 } from 'radix-ui';
5
5
 
6
6
  declare function Tabs({ className, orientation, ...props }: React.ComponentProps<typeof Tabs$1.Root>): React.JSX.Element;
7
7
  declare const tabsListVariants: (props?: ({
8
- variant?: "line" | "default" | null | undefined;
8
+ variant?: "default" | "line" | null | undefined;
9
9
  } & class_variance_authority_types.ClassProp) | undefined) => string;
10
10
  declare function TabsList({ className, variant, ...props }: React.ComponentProps<typeof Tabs$1.List> & VariantProps<typeof tabsListVariants>): React.JSX.Element;
11
11
  declare function TabsTrigger({ className, ...props }: React.ComponentProps<typeof Tabs$1.Trigger>): React.JSX.Element;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@handled-ai/design-system",
3
- "version": "0.18.26",
3
+ "version": "0.18.27",
4
4
  "description": "Handled UI component library (shadcn-style, New York)",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@9.12.0",
@@ -131,14 +131,25 @@ describe("CasePanelDetail structure", () => {
131
131
  expect(slots).toEqual(["why", "actions", "opportunity", "timeline", "play-panel"])
132
132
  })
133
133
 
134
- it("supports the modest width variant", () => {
135
- const { container } = render(
134
+ it("supports compact and modest width variants", () => {
135
+ const { container, rerender } = render(
136
+ <CasePanelDetail width="compact">
137
+ <div>Content</div>
138
+ </CasePanelDetail>,
139
+ )
140
+
141
+ let inner = container.querySelector("section > div")
142
+ expect(inner?.className).toContain("max-w-[640px]")
143
+ expect(inner?.className).toContain("px-10")
144
+ expect(inner?.className).not.toContain("max-w-[720px]")
145
+
146
+ rerender(
136
147
  <CasePanelDetail width="modest">
137
148
  <div>Content</div>
138
149
  </CasePanelDetail>,
139
150
  )
140
151
 
141
- const inner = container.querySelector("section > div")
152
+ inner = container.querySelector("section > div")
142
153
  expect(inner?.className).toContain("max-w-[720px]")
143
154
  expect(inner?.className).not.toContain("max-w-[880px]")
144
155
  })
@@ -9,7 +9,7 @@ import {
9
9
  } from "lucide-react"
10
10
  import { cn } from "../lib/utils"
11
11
 
12
- export type CasePanelDetailWidth = "comfortable" | "modest" | "full"
12
+ export type CasePanelDetailWidth = "comfortable" | "modest" | "compact" | "full"
13
13
 
14
14
  export interface CasePanelDetailProps {
15
15
  children: React.ReactNode
@@ -23,6 +23,7 @@ export interface CasePanelDetailProps {
23
23
  const detailWidthClasses: Record<CasePanelDetailWidth, string> = {
24
24
  comfortable: "mx-auto w-full max-w-[880px] px-10 pb-[120px] pt-8",
25
25
  modest: "mx-auto w-full max-w-[720px] px-8 pb-[112px] pt-7",
26
+ compact: "mx-auto w-full max-w-[640px] px-10 pb-[112px] pt-7",
26
27
  full: "w-full px-8 pb-[120px] pt-8",
27
28
  }
28
29
 
@@ -55,9 +56,9 @@ export function CasePanelHeader({
55
56
  }: CasePanelHeaderProps) {
56
57
  return (
57
58
  <header className={cn("mb-7", className)}>
58
- <div className="flex items-start justify-between gap-5">
59
+ <div className="flex items-start justify-between gap-6">
59
60
  <div className="min-w-0 flex-1">
60
- <h1 className="m-0 text-[27px] font-bold leading-[1.18] tracking-[-0.02em] text-foreground [text-wrap:balance]">
61
+ <h1 className="m-0 max-w-[560px] text-[27px] font-bold leading-[1.18] tracking-[-0.02em] text-foreground">
61
62
  {title}
62
63
  </h1>
63
64
  {children}