{"version":3,"sources":["../../src/ui/tokens.ts","../../src/ui/components/Avatar.tsx","../../src/ui/components/Badge.tsx","../../src/ui/typography.tsx","../../src/ui/components/Button.tsx","../../src/ui/components/Breadcrumb.tsx","../../src/ui/components/Card.tsx","../../src/ui/internal/modal.ts","../../src/ui/components/ConfirmDialog.tsx","../../src/ui/components/Drawer.tsx","../../src/ui/primitives.tsx","../../src/ui/components/EmptyState.tsx","../../src/ui/components/ListRow.tsx","../../src/ui/components/PageHeader.tsx","../../src/ui/components/Pagination.tsx","../../src/ui/components/Prose.tsx","../../src/ui/components/SearchField.tsx","../../src/ui/components/SegmentedControl.tsx","../../src/ui/components/Spinner.tsx","../../src/ui/components/StatusDot.tsx","../../src/ui/components/Table.tsx","../../src/ui/components/Tabs.tsx","../../src/ui/layouts/AppFrame.tsx","../../src/ui/layouts/use-container-width.ts","../../src/ui/layouts/ListDetailLayout.tsx","../../src/ui/layouts/PageLayout.tsx","../../src/ui/layouts/SidebarLayout.tsx"],"names":["useState","useEffect","jsx","TONE","ensureStyle","Fragment","STYLE_ID","RULES","useRef","useId","jsxs","createContext","useMemo","useContext","injectBaseReset","Header","Body","Footer","useLayoutEffect"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * The token contract for `@nimblebrain/synapse/ui`.\n *\n * Values are NOT brand hexes — they are `var(--token, fallback)` references to\n * the CSS custom properties the host injects into the app iframe (the MCP\n * ext-apps `hostContext.styles.variables`). Because styling resolves through\n * CSS variables, theme changes (including light↔dark) reflect automatically\n * with no React re-render: the host swaps the `:root` vars and every `var()`\n * re-resolves.\n *\n * The fallbacks are deliberately **unbranded** — system fonts, neutral grays, a\n * generic blue, and generic semantic hues for the status channels. NOT\n * NimbleBrain brand. Brand arrives by injection when the app runs inside the\n * NimbleBrain host; standalone/static renders get a sane\n * unbranded default. This keeps the library host-agnostic.\n * `__tests__/ui/tokens.test.ts` holds the line: every hex in these fallbacks\n * must be in the sanctioned set, same as `theme-defaults.ts`.\n *\n * Components import the static `tokens` object and style with CSS `var()`, so\n * theming (incl. light/dark) resolves in CSS with no re-render.\n */\n\nimport type { CSSProperties } from \"react\";\n\n/** Resolved design tokens as CSS `var()` references with neutral fallbacks. */\nexport const tokens = {\n  // ── Surfaces ──\n  bg: \"var(--color-background-primary, #ffffff)\",\n  bgRaised: \"var(--color-background-secondary, #fafafa)\",\n  bgSubtle: \"var(--color-background-tertiary, #f3f4f6)\",\n\n  // ── Text ──\n  fg: \"var(--color-text-primary, #111827)\",\n  fgMuted: \"var(--color-text-secondary, #6b7280)\",\n  fgFaint: \"var(--color-text-tertiary, #9ca3af)\",\n  accent: \"var(--color-text-accent, #2563eb)\",\n  accentFg: \"var(--nb-color-accent-foreground, #ffffff)\",\n\n  // ── Border / ring ──\n  border: \"var(--color-border-primary, #e5e7eb)\",\n  borderStrong: \"var(--color-border-secondary, #d1d5db)\",\n  ring: \"var(--color-ring-primary, #2563eb)\",\n\n  // ── Status / brand semantics ──\n  danger: \"var(--nb-color-danger, #dc2626)\",\n  dangerFg: \"var(--nb-color-danger-foreground, #ffffff)\",\n  success: \"var(--nb-color-success, #059669)\",\n  warning: \"var(--nb-color-warning, #f59e0b)\",\n  processing: \"var(--nb-color-processing, #7c3aed)\",\n  processingLight: \"var(--nb-color-processing-light, #f3eeff)\",\n  infoLight: \"var(--nb-color-info-light, #eef4ff)\",\n\n  // ── Typography ──\n  fontSans: \"var(--font-sans, system-ui, -apple-system, BlinkMacSystemFont, sans-serif)\",\n  fontMono: \"var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace)\",\n  fontHeading: \"var(--nb-font-heading, system-ui, -apple-system, BlinkMacSystemFont, sans-serif)\",\n  weightNormal: \"var(--font-weight-normal, 400)\",\n  weightMedium: \"var(--font-weight-medium, 500)\",\n  weightSemibold: \"var(--font-weight-semibold, 600)\",\n  weightBold: \"var(--font-weight-bold, 700)\",\n\n  // ── Type scale (size + line-height pairs) ──\n  textXsSize: \"var(--font-text-xs-size, 0.75rem)\",\n  textXsLine: \"var(--font-text-xs-line-height, 1rem)\",\n  textSmSize: \"var(--font-text-sm-size, 0.875rem)\",\n  textSmLine: \"var(--font-text-sm-line-height, 1.25rem)\",\n  textBaseSize: \"var(--font-text-base-size, 1rem)\",\n  textBaseLine: \"var(--font-text-base-line-height, 1.5rem)\",\n  textLgSize: \"var(--font-text-lg-size, 1.125rem)\",\n  textLgLine: \"var(--font-text-lg-line-height, 1.75rem)\",\n  headingSmSize: \"var(--font-heading-sm-size, 1.25rem)\",\n  headingSmLine: \"var(--font-heading-sm-line-height, 1.75rem)\",\n  headingMdSize: \"var(--font-heading-md-size, 1.5rem)\",\n  headingMdLine: \"var(--font-heading-md-line-height, 2rem)\",\n  headingLgSize: \"var(--font-heading-lg-size, 2rem)\",\n  headingLgLine: \"var(--font-heading-lg-line-height, 2.5rem)\",\n\n  // ── Radius / border width ──\n  radiusXs: \"var(--border-radius-xs, 0.25rem)\",\n  radiusSm: \"var(--border-radius-sm, 0.5rem)\",\n  radiusMd: \"var(--border-radius-md, 0.75rem)\",\n  radiusLg: \"var(--border-radius-lg, 1rem)\",\n  radiusXl: \"var(--border-radius-xl, 1.5rem)\",\n  borderWidth: \"var(--border-width-regular, 1px)\",\n\n  // ── Shadows ──\n  shadowHairline: \"var(--shadow-hairline, 0 0 0 1px rgba(0,0,0,0.06))\",\n  shadowSm: \"var(--shadow-sm, 0 1px 2px rgba(0,0,0,0.05))\",\n  shadowMd: \"var(--shadow-md, 0 4px 6px -1px rgba(0,0,0,0.1))\",\n  shadowLg: \"var(--shadow-lg, 0 10px 15px -3px rgba(0,0,0,0.1))\",\n} as const;\n\nexport type Tokens = typeof tokens;\n\n/**\n * A style object that also permits CSS custom properties (`--foo`). React's\n * `CSSProperties` rejects custom-property keys; components that set CSS vars\n * inline (for `:hover`/keyframe plumbing) type their style as this, then pass\n * it to `style` (it down-casts cleanly to `CSSProperties`).\n */\nexport type StyleWithVars = CSSProperties & Record<`--${string}`, string | number>;\n\n/** Body text sizes. */\nexport type TextSize = \"xs\" | \"sm\" | \"base\" | \"lg\";\n/** Heading sizes. */\nexport type HeadingSize = \"sm\" | \"md\" | \"lg\";\n\nconst TEXT_SCALE: Record<TextSize, CSSProperties> = {\n  xs: { fontSize: tokens.textXsSize, lineHeight: tokens.textXsLine },\n  sm: { fontSize: tokens.textSmSize, lineHeight: tokens.textSmLine },\n  base: { fontSize: tokens.textBaseSize, lineHeight: tokens.textBaseLine },\n  lg: { fontSize: tokens.textLgSize, lineHeight: tokens.textLgLine },\n};\n\nconst HEADING_SCALE: Record<HeadingSize, CSSProperties> = {\n  sm: { fontSize: tokens.headingSmSize, lineHeight: tokens.headingSmLine },\n  md: { fontSize: tokens.headingMdSize, lineHeight: tokens.headingMdLine },\n  lg: { fontSize: tokens.headingLgSize, lineHeight: tokens.headingLgLine },\n};\n\n/** `{ fontSize, lineHeight }` for a body-text level. */\nexport function textStyle(size: TextSize): CSSProperties {\n  return TEXT_SCALE[size];\n}\n\n/** `{ fontSize, lineHeight }` for a heading level. */\nexport function headingStyle(size: HeadingSize): CSSProperties {\n  return HEADING_SCALE[size];\n}\n","/**\n * Avatar — a circular identity chip. Renders an image when `src` is given,\n * otherwise initials derived from `name` on a subtle tinted background.\n */\n\nimport { type HTMLAttributes, useEffect, useState } from \"react\";\nimport { tokens } from \"../tokens.js\";\n\n/** Up to two initials from a name (\"Jordan Ratner\" → \"JR\", \"mat\" → \"M\"). */\nfunction initialsOf(name: string): string {\n  const parts = name.trim().split(/\\s+/).filter(Boolean);\n  if (parts.length === 0) return \"?\";\n  const first = parts[0] ?? \"\";\n  if (parts.length === 1) return first.charAt(0).toUpperCase();\n  const last = parts[parts.length - 1] ?? \"\";\n  return (first.charAt(0) + last.charAt(0)).toUpperCase();\n}\n\ninterface AvatarProps extends Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> {\n  /** Name used for initials and the image alt text. */\n  name: string;\n  /** Optional image URL; falls back to initials when absent or on error. */\n  src?: string;\n  /** Diameter in px. Default 28. */\n  size?: number;\n}\n\nexport function Avatar({ name, src, size = 28, style, ...rest }: AvatarProps) {\n  // Fall back to initials if the image fails to load. Reset on `src` change.\n  const [failed, setFailed] = useState(false);\n  // biome-ignore lint/correctness/useExhaustiveDependencies: reset only when src changes\n  useEffect(() => setFailed(false), [src]);\n  const showImage = Boolean(src) && !failed;\n  return (\n    <span\n      style={{\n        display: \"inline-flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        flexShrink: 0,\n        width: size,\n        height: size,\n        borderRadius: \"50%\",\n        overflow: \"hidden\",\n        background: tokens.bgSubtle,\n        color: tokens.fgMuted,\n        fontFamily: tokens.fontSans,\n        fontSize: Math.round(size * 0.4),\n        fontWeight: tokens.weightSemibold,\n        userSelect: \"none\",\n        ...style,\n      }}\n      {...rest}\n    >\n      {showImage ? (\n        <img\n          src={src}\n          alt={name}\n          width={size}\n          height={size}\n          onError={() => setFailed(true)}\n          style={{ width: \"100%\", height: \"100%\", objectFit: \"cover\" }}\n        />\n      ) : (\n        initialsOf(name)\n      )}\n    </span>\n  );\n}\n","/**\n * Badge — a small pill for status and priority labels (e.g. MEDIUM/HIGH,\n * open/resolved). Soft tinted background with a same-hue label.\n */\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { tokens } from \"../tokens.js\";\n\nexport type BadgeTone = \"neutral\" | \"accent\" | \"success\" | \"warning\" | \"danger\" | \"processing\";\n\n/** `{ bg, fg }` per tone. Soft tinted background, same-hue label. The status\n * tones have no `*Light` token so their tint is derived from the fg color. */\nconst TONE: Record<BadgeTone, { bg: string; fg: string }> = {\n  neutral: { bg: tokens.bgSubtle, fg: tokens.fgMuted },\n  accent: { bg: tokens.infoLight, fg: tokens.accent },\n  success: { bg: `color-mix(in oklab, ${tokens.success} 14%, transparent)`, fg: tokens.success },\n  warning: { bg: `color-mix(in oklab, ${tokens.warning} 14%, transparent)`, fg: tokens.warning },\n  danger: { bg: `color-mix(in oklab, ${tokens.danger} 14%, transparent)`, fg: tokens.danger },\n  processing: { bg: tokens.processingLight, fg: tokens.processing },\n};\n\ninterface BadgeProps extends HTMLAttributes<HTMLSpanElement> {\n  tone?: BadgeTone;\n  children?: ReactNode;\n}\n\nexport function Badge({ tone = \"neutral\", style, children, ...rest }: BadgeProps) {\n  const { bg, fg } = TONE[tone];\n  return (\n    <span\n      style={{\n        display: \"inline-flex\",\n        alignItems: \"center\",\n        gap: \"0.25rem\",\n        padding: \"0.1rem 0.45rem\",\n        borderRadius: tokens.radiusXs,\n        background: bg,\n        color: fg,\n        fontFamily: tokens.fontSans,\n        fontSize: tokens.textXsSize,\n        lineHeight: tokens.textXsLine,\n        fontWeight: tokens.weightSemibold,\n        letterSpacing: \"0.02em\",\n        textTransform: \"uppercase\",\n        whiteSpace: \"nowrap\",\n        ...style,\n      }}\n      {...rest}\n    >\n      {children}\n    </span>\n  );\n}\n","/**\n * Typography components bound to the type scale and the sans/heading font\n * slots. `Text` for body copy, `Heading` for display type (uses the heading\n * font — Hanken Grotesk in the NimbleBrain host, `system-ui` elsewhere).\n */\n\nimport type { CSSProperties, ElementType, HTMLAttributes, ReactNode } from \"react\";\nimport { type HeadingSize, headingStyle, type TextSize, textStyle, tokens } from \"./tokens.js\";\n\ntype Tone = \"default\" | \"muted\" | \"faint\" | \"accent\" | \"danger\" | \"success\";\ntype Weight = \"normal\" | \"medium\" | \"semibold\" | \"bold\";\n\nconst TONE: Record<Tone, string> = {\n  default: tokens.fg,\n  muted: tokens.fgMuted,\n  faint: tokens.fgFaint,\n  accent: tokens.accent,\n  danger: tokens.danger,\n  success: tokens.success,\n};\n\nconst WEIGHT: Record<Weight, string> = {\n  normal: tokens.weightNormal,\n  medium: tokens.weightMedium,\n  semibold: tokens.weightSemibold,\n  bold: tokens.weightBold,\n};\n\ninterface TextProps extends Omit<HTMLAttributes<HTMLElement>, \"color\"> {\n  size?: TextSize;\n  weight?: Weight;\n  tone?: Tone;\n  mono?: boolean;\n  /**\n   * Single-line ellipsis truncation.\n   *\n   * Sets `display: block` alongside the ellipsis rules, and that is load-bearing rather\n   * than incidental: `overflow` and `text-overflow` do not apply to a non-replaced INLINE\n   * box, so on the default `<span>` the only declaration that survived was\n   * `white-space: nowrap` — and the prop did the exact opposite of its name, making text\n   * unwrappable instead of clipping it. Inside an auto-layout `<table>` that widened the\n   * column to the full string and pushed every later column off the pane.\n   *\n   * `min-width: 0` comes with it so the box can actually shrink as a flex item; without it\n   * a truncating `Text` inside `Inline`/`Stack` refuses to go below its content width and\n   * pushes its container instead, which is the same bug one layer out.\n   *\n   * A truncating cell in a `Table` also needs its column to declare a `width` — see\n   * `Column.width`. Auto table layout sizes to content, so the ellipsis has nothing to\n   * clip against until some column is pinned.\n   */\n  truncate?: boolean;\n  as?: ElementType;\n  children?: ReactNode;\n}\n\n/** Body text. Defaults to base size, normal weight, primary tone, sans font. */\nexport function Text({\n  size = \"base\",\n  weight = \"normal\",\n  tone = \"default\",\n  mono = false,\n  truncate = false,\n  as: As = \"span\",\n  style,\n  children,\n  ...rest\n}: TextProps) {\n  const truncation: CSSProperties = truncate\n    ? {\n        display: \"block\",\n        minWidth: 0,\n        overflow: \"hidden\",\n        textOverflow: \"ellipsis\",\n        whiteSpace: \"nowrap\",\n      }\n    : {};\n  return (\n    <As\n      style={{\n        margin: 0,\n        fontFamily: mono ? tokens.fontMono : tokens.fontSans,\n        fontWeight: WEIGHT[weight],\n        color: TONE[tone],\n        ...textStyle(size),\n        ...truncation,\n        ...style,\n      }}\n      {...rest}\n    >\n      {children}\n    </As>\n  );\n}\n\ninterface HeadingProps extends Omit<HTMLAttributes<HTMLHeadingElement>, \"color\"> {\n  size?: HeadingSize;\n  weight?: Weight;\n  tone?: Tone;\n  as?: ElementType;\n  children?: ReactNode;\n}\n\n/** Display heading using the heading font slot. Defaults to md, semibold. */\nexport function Heading({\n  size = \"md\",\n  weight = \"semibold\",\n  tone = \"default\",\n  as: As = \"h2\",\n  style,\n  children,\n  ...rest\n}: HeadingProps) {\n  return (\n    <As\n      style={{\n        margin: 0,\n        fontFamily: tokens.fontHeading,\n        fontWeight: WEIGHT[weight],\n        color: TONE[tone],\n        letterSpacing: \"-0.015em\",\n        ...headingStyle(size),\n        ...style,\n      }}\n      {...rest}\n    >\n      {children}\n    </As>\n  );\n}\n","/**\n * Button and TextLink. Pseudo-states (`:hover`/`:active`/`:disabled`) live in a\n * once-injected stylesheet that reads token-driven CSS custom properties set\n * inline — so the base values stay token-driven while hover still works.\n */\n\nimport type { ButtonHTMLAttributes, ReactNode } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\nconst STYLE_ID = \"nb-synapse-button\";\nconst RULES = `\n.nb-btn {\n  --nb-btn-bg: transparent;\n  --nb-btn-bg-hover: transparent;\n  display: inline-flex;\n  align-items: center;\n  justify-content: center;\n  gap: 0.4rem;\n  border: var(--nb-btn-border, none);\n  border-radius: var(--nb-btn-radius);\n  background: var(--nb-btn-bg);\n  color: var(--nb-btn-fg);\n  font-family: var(--nb-btn-font);\n  font-weight: var(--nb-btn-weight);\n  cursor: pointer;\n  transition: background 130ms ease, color 130ms ease, opacity 130ms ease;\n  white-space: nowrap;\n}\n.nb-btn:hover { background: var(--nb-btn-bg-hover); }\n.nb-btn:active { transform: translateY(0.5px); }\n.nb-btn:disabled { opacity: 0.5; cursor: default; }\n.nb-btn:disabled:hover { background: var(--nb-btn-bg); }\n.nb-textlink {\n  border: none;\n  background: none;\n  padding: 0;\n  cursor: pointer;\n  font-family: var(--nb-tl-font);\n  color: var(--nb-tl-fg);\n  transition: color 130ms ease, opacity 130ms ease;\n}\n.nb-textlink:hover { color: var(--nb-tl-fg-hover); }\n.nb-textlink:disabled { opacity: 0.45; cursor: default; }\n`;\n\n/**\n * `danger` is for the verb that destroys something — Delete, Remove, Forget. It is\n * filled like `primary`, so it is never the quiet option beside one, and red so the\n * difference reads before the label does.\n */\ntype Variant = \"primary\" | \"secondary\" | \"ghost\" | \"danger\";\ntype Size = \"sm\" | \"md\";\n\nconst SIZE_PAD: Record<Size, string> = {\n  sm: \"0.3rem 0.6rem\",\n  md: \"0.45rem 0.85rem\",\n};\n\ninterface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n  variant?: Variant;\n  size?: Size;\n  children?: ReactNode;\n}\n\nexport function Button({\n  variant = \"primary\",\n  size = \"md\",\n  style,\n  className,\n  children,\n  ...rest\n}: ButtonProps) {\n  ensureStyle(STYLE_ID, RULES);\n  const vars: Record<`--${string}`, string> = {\n    \"--nb-btn-radius\": tokens.radiusSm,\n    \"--nb-btn-font\": tokens.fontSans,\n    \"--nb-btn-weight\": tokens.weightMedium,\n  };\n  if (variant === \"primary\") {\n    vars[\"--nb-btn-bg\"] = tokens.accent;\n    vars[\"--nb-btn-bg-hover\"] = `color-mix(in oklab, ${tokens.accent} 88%, black)`;\n    vars[\"--nb-btn-fg\"] = tokens.accentFg;\n  } else if (variant === \"danger\") {\n    vars[\"--nb-btn-bg\"] = tokens.danger;\n    vars[\"--nb-btn-bg-hover\"] = `color-mix(in oklab, ${tokens.danger} 88%, black)`;\n    vars[\"--nb-btn-fg\"] = tokens.dangerFg;\n  } else if (variant === \"secondary\") {\n    vars[\"--nb-btn-bg\"] = tokens.bgSubtle;\n    vars[\"--nb-btn-bg-hover\"] = tokens.bgRaised;\n    vars[\"--nb-btn-fg\"] = tokens.fg;\n    vars[\"--nb-btn-border\"] = `${tokens.borderWidth} solid ${tokens.border}`;\n  } else {\n    vars[\"--nb-btn-bg\"] = \"transparent\";\n    vars[\"--nb-btn-bg-hover\"] = tokens.bgSubtle;\n    vars[\"--nb-btn-fg\"] = tokens.fg;\n  }\n  const btnStyle: StyleWithVars = {\n    ...vars,\n    padding: SIZE_PAD[size],\n    fontSize: size === \"sm\" ? tokens.textSmSize : tokens.textBaseSize,\n    lineHeight: size === \"sm\" ? tokens.textSmLine : tokens.textBaseLine,\n    ...style,\n  };\n  return (\n    <button type=\"button\" className={`nb-btn ${className ?? \"\"}`.trim()} style={btnStyle} {...rest}>\n      {children}\n    </button>\n  );\n}\n\ninterface TextLinkProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n  /** Resting tone. Hover always moves toward `accent` (or `danger`). */\n  tone?: \"muted\" | \"default\" | \"danger\";\n  children?: ReactNode;\n}\n\n/** A chrome-less text button — for back / delete / retry affordances. */\nexport function TextLink({ tone = \"muted\", style, className, children, ...rest }: TextLinkProps) {\n  ensureStyle(STYLE_ID, RULES);\n  const resting =\n    tone === \"danger\" ? tokens.danger : tone === \"default\" ? tokens.fg : tokens.fgMuted;\n  const hover = tone === \"danger\" ? tokens.danger : tokens.accent;\n  const linkStyle: StyleWithVars = {\n    \"--nb-tl-font\": tokens.fontSans,\n    \"--nb-tl-fg\": resting,\n    \"--nb-tl-fg-hover\": hover,\n    fontSize: tokens.textXsSize,\n    lineHeight: tokens.textXsLine,\n    letterSpacing: \"0.02em\",\n    ...style,\n  };\n  return (\n    <button\n      type=\"button\"\n      className={`nb-textlink ${className ?? \"\"}`.trim()}\n      style={linkStyle}\n      {...rest}\n    >\n      {children}\n    </button>\n  );\n}\n","/**\n * Breadcrumb — the trail back, and where you are.\n *\n * A hierarchy deeper than two levels cannot be navigated by a back button: \"up one\" and\n * \"up two\" need separate controls, and an app that grows a second one ends up rendering\n * both adjacent, differently labelled, with only one correct at any depth. A trail has no\n * such limit — every level is named, so every jump is the same gesture — and it answers\n * a question a back button never does, which is where the reader currently is.\n *\n * The last crumb renders as text, never as a disabled control. A control that looks\n * clickable and does nothing is worse than no control, and the reader is already there.\n *\n * Steps are BUTTONS, not anchors, and that is deliberate: a Synapse app lives in an iframe\n * with no address of its own, so a crumb changes app state rather than navigating to a URL.\n * There is no href to put on an anchor, and a `<span>` with a click handler is reachable by\n * neither keyboard nor screen reader.\n */\n\nimport type { HTMLAttributes } from \"react\";\nimport { Fragment } from \"react\";\nimport { tokens } from \"../tokens.js\";\nimport { Text } from \"../typography.js\";\nimport { TextLink } from \"./Button.js\";\n\nexport interface Crumb {\n  label: string;\n  /** Omit on the current step. A crumb with no handler renders as plain text. */\n  onClick?: () => void;\n}\n\ninterface BreadcrumbProps extends Omit<HTMLAttributes<HTMLElement>, \"children\"> {\n  crumbs: Crumb[];\n  /** The glyph between steps. */\n  separator?: string;\n}\n\nexport function Breadcrumb({ crumbs, separator = \"›\", style, ...rest }: BreadcrumbProps) {\n  return (\n    <nav\n      aria-label=\"Breadcrumb\"\n      style={{\n        display: \"flex\",\n        alignItems: \"center\",\n        gap: \"0.4rem\",\n        flexWrap: \"wrap\",\n        minWidth: 0,\n        ...style,\n      }}\n      {...rest}\n    >\n      {crumbs.map((crumb, i) => {\n        const last = i === crumbs.length - 1;\n        return (\n          // biome-ignore lint/suspicious/noArrayIndexKey: a crumb's POSITION is its identity — \"the second level\" is what the step means, and two levels can legitimately carry the same label. There is no id to key on, and a trail that changed shape SHOULD remount rather than reconcile a step into a different depth.\n          <Fragment key={`${crumb.label}:${i}`}>\n            {last || !crumb.onClick ? (\n              <Text\n                size=\"xs\"\n                tone={last ? \"muted\" : \"default\"}\n                aria-current={last ? \"page\" : undefined}\n              >\n                {crumb.label}\n              </Text>\n            ) : (\n              <TextLink onClick={crumb.onClick} style={{ fontSize: tokens.textXsSize }}>\n                {crumb.label}\n              </TextLink>\n            )}\n            {last ? null : (\n              <Text size=\"xs\" tone=\"faint\" aria-hidden=\"true\">\n                {separator}\n              </Text>\n            )}\n          </Fragment>\n        );\n      })}\n    </nav>\n  );\n}\n","/**\n * Card — a raised surface with a hairline border. The default container for\n * grouped content (deal cards, task cards, panels). `interactive` adds a hover\n * lift via a once-injected stylesheet (no per-card handlers).\n */\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\nconst STYLE_ID = \"nb-synapse-card\";\nconst RULES = `\n.nb-card--interactive {\n  cursor: pointer;\n  transition: box-shadow 140ms ease, border-color 140ms ease;\n}\n.nb-card--interactive:hover {\n  box-shadow: var(--nb-card-shadow-hover);\n  border-color: var(--nb-card-border-hover);\n}\n`;\n\ninterface CardProps extends HTMLAttributes<HTMLDivElement> {\n  /** Inner padding (CSS length or px number). Default `0.875rem`. */\n  padding?: number | string;\n  /** Lift on hover — for clickable cards. */\n  interactive?: boolean;\n  children?: ReactNode;\n}\n\nexport function Card({\n  padding = \"0.875rem\",\n  interactive = false,\n  style,\n  className,\n  children,\n  ...rest\n}: CardProps) {\n  if (interactive) ensureStyle(STYLE_ID, RULES);\n  const cardStyle: StyleWithVars = {\n    background: tokens.bgRaised,\n    border: `${tokens.borderWidth} solid ${tokens.border}`,\n    borderRadius: tokens.radiusMd,\n    padding,\n    boxShadow: tokens.shadowSm,\n    \"--nb-card-shadow-hover\": tokens.shadowMd,\n    \"--nb-card-border-hover\": tokens.borderStrong,\n    ...style,\n  };\n  return (\n    <div\n      className={interactive ? `nb-card--interactive ${className ?? \"\"}`.trim() : className}\n      style={cardStyle}\n      {...rest}\n    >\n      {children}\n    </div>\n  );\n}\n","/**\n * What `HTMLDialogElement.showModal()` gives for free, hand-rolled for the overlays\n * in this kit (`Drawer`, `ConfirmDialog`).\n *\n * The platform mounts every app in a sandboxed iframe that withholds `allow-modals`,\n * so `showModal()` throws there and white-screens the app; a native `<dialog>` is\n * unusable in the one environment these apps run in. Each overlay is a plain\n * positioned `<div>` instead, and this hook supplies the modal behaviour: focus\n * moved into the panel on open and restored on close, background scroll locked,\n * Tab/Shift+Tab contained while focus is inside the panel, and Escape.\n *\n * Overlays nest — a confirmation raised from inside a drawer is the ordinary case —\n * so the open ones form a stack, and only the innermost answers Escape and Tab. Every\n * overlay listens for Escape on `window`, so without the stack one keypress would\n * close all of them; and a nested panel renders inside its parent's DOM, so its Tab\n * keydown bubbles to the parent's trap, which would otherwise compute a boundary\n * that contains both.\n *\n * Scope: this contains Tab while focus is *inside* the panel — the modal case. It is\n * NOT the full native `inert`: it doesn't recover focus that drops to `<body>` when a\n * focused child unmounts (that fires focusout, not focusin), nor fence off portal'd\n * overlays a consumer opens outside the panel. A document-scoped focus backstop would\n * do neither reliably and would yank focus out of legitimate nested overlays — so\n * full containment is a FocusScope-style owner stack, deferred to #43.\n */\n\nimport { type RefObject, useEffect, useRef } from \"react\";\n\n// A control inside a *closed* <details> (other than its own <summary>) is not\n// reachable, even though its tabIndex is 0 — the collapse is a UA `display:none`\n// on the disclosure content. It's structural (the `open` attribute + DOM\n// position), so it's detectable without layout and belongs in the filter below,\n// alongside `[hidden]` (also a UA `display:none` rule).\nfunction inClosedDetails(el: HTMLElement): boolean {\n  const details = el.closest(\"details:not([open])\");\n  if (!details) return false;\n  const summary = details.querySelector(\"summary\");\n  return !summary || !summary.contains(el);\n}\n\n// Tabbable elements inside the panel, in DOM order — the focus-trap boundary.\n// A broad candidate query filtered by a positive predicate, in place of a\n// `:not(...)` denylist that had to enumerate every non-tabbable case per clause.\n// The filter is the set of non-tabbable cases detectable *without layout*:\n// `tabIndex >= 0` rejects any negative tabindex, `:disabled` inherits through\n// `<fieldset disabled>`, `[hidden]` and closed-<details> collapse are tested on\n// the element and its ancestors. CSS-hidden focusables (`display:none` /\n// `visibility:hidden` set in a stylesheet) need layout to detect, so they're NOT\n// filtered (worst case: one Tab exits).\n//\n// CANDIDATES is an allowlist of mainstream focusables, not `*`: a bare `<a>` (no\n// href) reports tabIndex 0 but isn't focusable, so `*` would admit a phantom\n// boundary — `a[href]` is load-bearing. It is deliberately not exhaustive:\n// media/embeds (`<audio controls>`, `<iframe>`) and `[contenteditable]` are\n// omitted until a consumer needs one, to keep the set honest.\nconst CANDIDATES = \"a[href], button, input, select, textarea, summary, [tabindex]\";\nfunction tabbables(panel: HTMLElement): HTMLElement[] {\n  return Array.from(panel.querySelectorAll<HTMLElement>(CANDIDATES)).filter(\n    (el) =>\n      el.tabIndex >= 0 &&\n      !el.matches(\":disabled\") &&\n      !el.closest(\"[hidden]\") &&\n      !inClosedDetails(el) &&\n      (el as HTMLInputElement).type !== \"hidden\",\n  );\n}\n\n// The open overlays, in the order they opened. Module-level because the questions it\n// answers — \"am I the one on top?\", \"am I the last one open?\" — span every overlay on\n// the page, not one component tree.\ninterface OpenOverlay {\n  panel: HTMLElement | null;\n  /** Where focus goes when this overlay closes. */\n  restoreTo: HTMLElement | null;\n}\nconst openOverlays: OpenOverlay[] = [];\n// The body's overflow from before the first overlay opened. Page-level state is\n// owned by the stack, not by each overlay: the page is locked while any overlay is\n// open, whichever order they opened and closed in.\nlet lockedOverflow = \"\";\n// Escapes an overlay has already acted on, so one keypress closes one overlay.\n// See the window listener for why this is recorded rather than inferred.\nconst handledEscapes = new WeakSet<Event>();\n\n// Innermost means: no open overlay sits inside this one's panel, and none that is\n// not its ancestor opened after it. DOM nesting decides first because open order\n// cannot: when a drawer and the confirmation inside it mount in the same commit,\n// React runs the child's effect before the parent's, so the drawer registers\n// second. Open order decides between overlays that do not nest.\nfunction isInnermost(self: OpenOverlay): boolean {\n  const selfAt = openOverlays.indexOf(self);\n  return openOverlays.every((other, at) => {\n    if (other === self || !other.panel || !self.panel) return true;\n    if (self.panel.contains(other.panel)) return false;\n    if (other.panel.contains(self.panel)) return true;\n    return at < selfAt;\n  });\n}\n\ninterface ModalOptions {\n  /** Called on Escape while this overlay is the innermost one open. */\n  onEscape: () => void;\n  /**\n   * Where focus lands on open. Defaults to the panel itself. Read once, when the\n   * overlay opens, so it may return an element rendered in the same commit.\n   */\n  initialFocus?: () => HTMLElement | null | undefined;\n}\n\nexport function useModal(\n  open: boolean,\n  panelRef: RefObject<HTMLElement | null>,\n  { onEscape, initialFocus }: ModalOptions,\n): void {\n  // Read through refs so a new callback identity each render neither re-subscribes\n  // nor moves this overlay's place in the stack.\n  const escapeRef = useRef(onEscape);\n  escapeRef.current = onEscape;\n  const initialFocusRef = useRef(initialFocus);\n  initialFocusRef.current = initialFocus;\n\n  useEffect(() => {\n    if (!open) return;\n    const panel = panelRef.current;\n    const previouslyFocused = document.activeElement as HTMLElement | null;\n    const entry: OpenOverlay = { panel, restoreTo: previouslyFocused };\n    // An overlay nested in this one that is already open opened in the same commit —\n    // React runs the child's effect first — so it recorded this overlay's opener as\n    // its own, and this one would record the nested overlay's control. Swap: this\n    // overlay returns focus to the opener, the nested one returns it to this panel.\n    //\n    // The swap is with the overlay directly below this one, which is the *outermost*\n    // of the ones nested inside it: the effects ran deepest-first, so each has already\n    // swapped with the one below it, and only the outermost still holds this overlay's\n    // opener. That same deepest-first order puts it last in the stack, so it is the\n    // last match, not the first.\n    const nested = openOverlays.filter((o) => panel && o.panel && panel.contains(o.panel)).at(-1);\n    if (nested) {\n      entry.restoreTo = nested.restoreTo;\n      nested.restoreTo = panel;\n    }\n    const { body } = document;\n    if (openOverlays.length === 0) lockedOverflow = body.style.overflow;\n    openOverlays.push(entry);\n    const innermost = () => isInnermost(entry);\n\n    // Focus already inside the panel is left where it is: it is the nested overlay's\n    // initial focus, from the same commit.\n    if (!(panel && previouslyFocused && panel.contains(previouslyFocused))) {\n      (initialFocusRef.current?.() ?? panel)?.focus();\n    }\n    body.style.overflow = \"hidden\";\n\n    // Escape on `window` rather than the panel, so it works wherever focus sits —\n    // including on <body> after a focused control inside the panel unmounted.\n    //\n    // One Escape closes one overlay. In a browser the nested overlay's listener\n    // can close it and let React commit before this listener runs for the same\n    // keypress, which would leave this overlay innermost and close it too — so\n    // the overlay that acts records the event and the rest stand down.\n    //\n    // Recorded on the event rather than read off `defaultPrevented`, which\n    // answers a different question: \"did anyone cancel this?\" rather than \"did\n    // an overlay act on it?\". The SDK's own key forwarder cancels every Escape\n    // it forwards, on `document`, which a bubbling keydown reaches before\n    // `window` — so an overlay reading `defaultPrevented` finds it already true\n    // for an Escape nothing has handled, and no overlay ever closes. Only the\n    // overlays can answer the question the guard is asking.\n    const onWindowKeyDown = (e: KeyboardEvent) => {\n      if (e.key !== \"Escape\" || handledEscapes.has(e) || !innermost()) return;\n      handledEscapes.add(e);\n      e.preventDefault();\n      escapeRef.current();\n    };\n    window.addEventListener(\"keydown\", onWindowKeyDown);\n\n    const onPanelKeyDown = (e: KeyboardEvent) => {\n      if (e.key !== \"Tab\" || !panel || !innermost()) return;\n      const focusables = tabbables(panel);\n      if (focusables.length === 0) {\n        // Nothing tabbable inside — preventDefault keeps focus on the panel it's\n        // already on (the open step focused it), so Tab can't leave.\n        e.preventDefault();\n        return;\n      }\n      const first = focusables[0];\n      const last = focusables[focusables.length - 1];\n      const active = document.activeElement;\n      if (e.shiftKey && (active === first || active === panel)) {\n        e.preventDefault();\n        last.focus();\n      } else if (!e.shiftKey && active === last) {\n        e.preventDefault();\n        first.focus();\n      }\n    };\n    panel?.addEventListener(\"keydown\", onPanelKeyDown);\n\n    return () => {\n      window.removeEventListener(\"keydown\", onWindowKeyDown);\n      panel?.removeEventListener(\"keydown\", onPanelKeyDown);\n      const at = openOverlays.indexOf(entry);\n      if (at !== -1) openOverlays.splice(at, 1);\n      if (openOverlays.length === 0) body.style.overflow = lockedOverflow;\n      entry.restoreTo?.focus?.();\n    };\n  }, [open, panelRef]);\n}\n","/**\n * ConfirmDialog — ask before doing something, and say what \"it\" is.\n *\n * A destructive action that cannot say what it will take with it is an action nobody\n * consented to, which is why `children` is arbitrary: the caller renders what the\n * action does, and any per-action control it needs, in the body. The dialog returns\n * approve or deny and nothing else. A choice inside the body — a checkbox, a mode —\n * belongs to the caller: it owns the state, renders the control in `children`, and\n * reads it in its own `onConfirm`. A primitive that returned a payload would be a\n * form, and it would grow one field per caller.\n *\n * **The action's outcome is reported here.** `onConfirm` may return a promise. While\n * it runs, both buttons are disabled, Confirm shows `pendingLabel`, and no dismissal\n * path — Escape, the scrim, Cancel — closes the dialog, because closing over a running\n * action would leave its outcome with nowhere to be reported. If it resolves, the\n * dialog asks to close (`onOpenChange(false)`). If it throws, the dialog stays open\n * with the error's message shown above the buttons, so the failure lands where the\n * user can retry or cancel rather than behind a dialog that has already gone.\n *\n * **Where focus lands.** On a `destructive` dialog, focus opens on Cancel, so a\n * reflexive Enter declines rather than deletes. Otherwise it opens on Confirm, the\n * decision the dialog is asking about.\n *\n * A plain positioned `<div>`, not a native `<dialog>` (the app iframe sandbox cannot\n * open one — see `internal/modal.ts`). It renders in place and `position: fixed`\n * lifts it out of layout, so it can be declared beside the control that opens it,\n * including inside a `Drawer`: the modal behaviour is shared with `Drawer` and knows\n * the innermost overlay owns Escape and Tab.\n */\n\nimport { type ReactNode, useEffect, useId, useRef, useState } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { useModal } from \"../internal/modal.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\nimport { Button } from \"./Button.js\";\n\nconst STYLE_ID = \"nb-synapse-confirm-dialog\";\nconst RULES = `\n/* border-box on both, because the kit cannot assume the host resets it: under\n   content-box a full-width panel is its padding wider than a phone screen. */\n.nb-confirm-scrim {\n  box-sizing: border-box;\n  position: fixed; inset: 0; z-index: 1010;\n  display: flex; align-items: center; justify-content: center;\n  padding: 1rem;\n  background: rgba(0, 0, 0, 0.4);\n  animation: nb-confirm-fade 160ms ease;\n}\n.nb-confirm {\n  box-sizing: border-box;\n  width: 100%; max-width: 28rem; max-height: 100%;\n  overflow-y: auto;\n  outline: none;\n  animation: nb-confirm-in 160ms cubic-bezier(0.2, 0, 0, 1);\n}\n.nb-confirm__actions {\n  display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 0.5rem;\n}\n@keyframes nb-confirm-fade { from { opacity: 0; } }\n@keyframes nb-confirm-in { from { opacity: 0; transform: translateY(4px); } }\n@media (pointer: coarse) {\n  .nb-confirm__actions .nb-btn { min-height: 44px; }\n}\n`;\n\ninterface ConfirmDialogProps {\n  open: boolean;\n  /** Every dismissal path — Escape, the scrim, Cancel — calls this with `false`. */\n  onOpenChange: (open: boolean) => void;\n  /** Names the dialog (`aria-labelledby`). */\n  title: ReactNode;\n  /** One line under the title. Becomes the dialog's accessible description. */\n  description?: ReactNode;\n  /** What the action will do, and any control that shapes it. */\n  children?: ReactNode;\n  confirmLabel?: string;\n  cancelLabel?: string;\n  /** Confirm's label while `onConfirm` is in flight. Defaults to `confirmLabel`. */\n  pendingLabel?: string;\n  /** Render Confirm as a `danger` button, and open with focus on Cancel. */\n  destructive?: boolean;\n  /** Resolve to close. Throw to stay open with the error's message shown. */\n  onConfirm: () => void | Promise<void>;\n}\n\nexport function ConfirmDialog({\n  open,\n  onOpenChange,\n  title,\n  description,\n  children,\n  confirmLabel = \"Confirm\",\n  cancelLabel = \"Cancel\",\n  pendingLabel,\n  destructive = false,\n  onConfirm,\n}: ConfirmDialogProps) {\n  ensureStyle(STYLE_ID, RULES);\n  const panelRef = useRef<HTMLDivElement>(null);\n  const titleId = useId();\n  const descriptionId = useId();\n  const [pending, setPending] = useState(false);\n  const [error, setError] = useState<string | null>(null);\n\n  // A reopen starts clean: an error from the previous open describes a run the\n  // user has already dismissed.\n  useEffect(() => {\n    if (open) {\n      setError(null);\n      setPending(false);\n    }\n  }, [open]);\n\n  const dismiss = () => {\n    if (!pending) onOpenChange(false);\n  };\n\n  const focusTarget = () =>\n    panelRef.current?.querySelector<HTMLElement>(\n      destructive ? \"[data-nb-confirm-cancel]\" : \"[data-nb-confirm-confirm]\",\n    );\n\n  useModal(open, panelRef, { onEscape: dismiss, initialFocus: focusTarget });\n\n  // Disabling the focused button while the action ran can drop focus to <body>,\n  // outside the panel's Tab trap. A failure hands it back to the same place the\n  // dialog opened on, with the error now above it.\n  // biome-ignore lint/correctness/useExhaustiveDependencies: keyed on the failure alone; focusTarget reads a ref.\n  useEffect(() => {\n    if (error) focusTarget()?.focus();\n  }, [error]);\n\n  const confirm = async () => {\n    if (pending) return;\n    setPending(true);\n    setError(null);\n    try {\n      await onConfirm();\n      setPending(false);\n      onOpenChange(false);\n    } catch (err) {\n      // An empty message (`new Error(res.statusText)` over HTTP/2, where statusText\n      // is always \"\") must still show that it failed.\n      const message = err instanceof Error ? err.message : String(err);\n      setError(message || \"That didn't go through. Try again.\");\n      setPending(false);\n    }\n  };\n\n  if (!open) return null;\n\n  const panelStyle: StyleWithVars = {\n    padding: \"1.25rem\",\n    borderRadius: tokens.radiusMd,\n    border: `${tokens.borderWidth} solid ${tokens.border}`,\n    background: tokens.bg,\n    color: tokens.fg,\n    boxShadow: tokens.shadowLg,\n    fontFamily: tokens.fontSans,\n  };\n\n  return (\n    // biome-ignore lint/a11y/useKeyWithClickEvents: scrim click is a bonus mouse affordance; Escape and Cancel are the keyboard dismissal paths.\n    // biome-ignore lint/a11y/noStaticElementInteractions: the scrim is a decorative dismissal backdrop; the panel below owns the alertdialog role/semantics.\n    <div\n      className=\"nb-confirm-scrim\"\n      onClick={(e) => {\n        // A click whose target is the scrim itself (not the panel) dismisses.\n        if (e.target === e.currentTarget) dismiss();\n      }}\n    >\n      <div\n        ref={panelRef}\n        role=\"alertdialog\"\n        aria-modal=\"true\"\n        aria-labelledby={titleId}\n        aria-describedby={description != null ? descriptionId : undefined}\n        aria-busy={pending || undefined}\n        tabIndex={-1}\n        className=\"nb-confirm\"\n        style={panelStyle}\n      >\n        <h2\n          id={titleId}\n          style={{\n            margin: 0,\n            fontFamily: tokens.fontSans,\n            fontSize: tokens.textBaseSize,\n            lineHeight: tokens.textBaseLine,\n            fontWeight: tokens.weightSemibold,\n            color: tokens.fg,\n          }}\n        >\n          {title}\n        </h2>\n        {description != null ? (\n          <p\n            id={descriptionId}\n            style={{\n              margin: \"0.25rem 0 0\",\n              fontSize: tokens.textSmSize,\n              lineHeight: tokens.textSmLine,\n              color: tokens.fgMuted,\n            }}\n          >\n            {description}\n          </p>\n        ) : null}\n\n        {children != null ? (\n          <div\n            style={{\n              marginTop: \"1rem\",\n              fontSize: tokens.textSmSize,\n              lineHeight: tokens.textSmLine,\n            }}\n          >\n            {children}\n          </div>\n        ) : null}\n\n        {error ? (\n          <p\n            role=\"alert\"\n            style={{\n              margin: \"0.75rem 0 0\",\n              fontSize: tokens.textSmSize,\n              lineHeight: tokens.textSmLine,\n              color: tokens.danger,\n            }}\n          >\n            {error}\n          </p>\n        ) : null}\n\n        <div className=\"nb-confirm__actions\" style={{ marginTop: \"1.25rem\" }}>\n          <Button\n            variant=\"secondary\"\n            size=\"sm\"\n            data-nb-confirm-cancel=\"\"\n            disabled={pending}\n            onClick={dismiss}\n          >\n            {cancelLabel}\n          </Button>\n          <Button\n            variant={destructive ? \"danger\" : \"primary\"}\n            size=\"sm\"\n            data-nb-confirm-confirm=\"\"\n            disabled={pending}\n            onClick={() => void confirm()}\n          >\n            {pending ? (pendingLabel ?? confirmLabel) : confirmLabel}\n          </Button>\n        </div>\n      </div>\n    </div>\n  );\n}\n","/**\n * Drawer — an off-canvas overlay panel that slides in from an edge, over a\n * scrim. The general overlay the apps need (e.g. CRM's detail panel).\n *\n * A plain positioned `<div>` overlay — **not** a native `<dialog>`, which the app\n * iframe sandbox cannot open (see `internal/modal.ts`). The scrim is drawn here;\n * the modal behaviour — focus into the panel on open and back on close, the Tab\n * trap, background scroll lock, and Escape — comes from `useModal`, shared with\n * `ConfirmDialog` so a confirmation raised inside a drawer stacks correctly. Controlled via\n * `open`/`onClose` (renders nothing when closed). Escape routes through `onEscape`\n * (defaults to `onClose`); clicking the scrim calls `onClose`. The slide-in is a\n * CSS keyframe on the panel.\n *\n * Compose with the `Header` / `Body` / `Footer` slots, or pass plain children.\n * `Header` owns the standard affordances — `title` (a real heading, wired as\n * the dialog's accessible name), an optional `onBack` button, an `actions`\n * slot, and the close button — so consumers don't re-roll them. The icon\n * buttons grow to a 44px hit target under `@media (pointer: coarse)`, keyed to\n * input modality rather than viewport width.\n *\n * `side` is `right` (default), `left`, or `bottom` (a bottom sheet — full width,\n * content height capped at 92%). A multi-level \"panel stack\" (push/pop) is an\n * app concern built on top of this.\n */\n\nimport {\n  createContext,\n  type HTMLAttributes,\n  type ReactNode,\n  useContext,\n  useEffect,\n  useId,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { useModal } from \"../internal/modal.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\ntype Side = \"left\" | \"right\" | \"bottom\";\n\nconst STYLE_ID = \"nb-synapse-drawer\";\nconst RULES = `\n.nb-drawer-scrim {\n  position: fixed; inset: 0; z-index: 1000;\n  display: flex; background: rgba(0, 0, 0, 0.32);\n  animation: nb-drawer-fade 200ms ease;\n}\n.nb-drawer-scrim--right { justify-content: flex-end; }\n.nb-drawer-scrim--left { justify-content: flex-start; }\n.nb-drawer-scrim--bottom { align-items: flex-end; }\n.nb-drawer {\n  margin: 0; padding: 0; border: none; max-width: 92%;\n  height: 100%; max-height: 100%; display: flex; flex-direction: column;\n  outline: none;\n}\n.nb-drawer--bottom { width: 100%; max-width: 100%; height: auto; max-height: 92%; }\n.nb-drawer--right { animation: nb-drawer-in-right 240ms cubic-bezier(0.2, 0, 0, 1); }\n.nb-drawer--left { animation: nb-drawer-in-left 240ms cubic-bezier(0.2, 0, 0, 1); }\n.nb-drawer--bottom { animation: nb-drawer-in-bottom 240ms cubic-bezier(0.2, 0, 0, 1); }\n@keyframes nb-drawer-in-right { from { transform: translateX(100%); } }\n@keyframes nb-drawer-in-left { from { transform: translateX(-100%); } }\n@keyframes nb-drawer-in-bottom { from { transform: translateY(100%); } }\n@keyframes nb-drawer-fade { from { opacity: 0; } }\n.nb-drawer-iconbtn { width: 28px; height: 28px; }\n@media (pointer: coarse) {\n  .nb-drawer-iconbtn { min-width: 44px; min-height: 44px; }\n}\n`;\n\ninterface DrawerContextValue {\n  labelId: string;\n  setHasTitle: (has: boolean) => void;\n}\n\nconst DrawerContext = createContext<DrawerContextValue | null>(null);\n\ninterface DrawerProps extends Omit<HTMLAttributes<HTMLDivElement>, \"onClick\"> {\n  open: boolean;\n  /** Called by the scrim and the Header close button. */\n  onClose: () => void;\n  /** Called on Escape. Defaults to `onClose` — override to do something else\n   * (e.g. pop one level of a panel stack before closing). */\n  onEscape?: () => void;\n  side?: Side;\n  /** Panel width (ignored for `side=\"bottom\"`, which is full width). Default 480. */\n  width?: number | string;\n  children?: ReactNode;\n}\n\nfunction DrawerRoot({\n  open,\n  onClose,\n  onEscape,\n  side = \"right\",\n  width = 480,\n  style,\n  children,\n  ...rest\n}: DrawerProps) {\n  ensureStyle(STYLE_ID, RULES);\n  const panelRef = useRef<HTMLDivElement>(null);\n  const labelId = useId();\n  // A `Header` with a `title` registers itself here so the panel can name\n  // itself via `aria-labelledby` (preferred over a consumer-passed aria-label).\n  const [hasTitle, setHasTitle] = useState(false);\n\n  useModal(open, panelRef, { onEscape: onEscape ?? onClose });\n\n  const ctxValue = useMemo<DrawerContextValue>(() => ({ labelId, setHasTitle }), [labelId]);\n\n  if (!open) return null;\n\n  const isBottom = side === \"bottom\";\n  const panelStyle: StyleWithVars = {\n    ...(isBottom ? { width: \"100%\", maxWidth: \"100%\" } : { width }),\n    background: tokens.bg,\n    color: tokens.fg,\n    boxShadow: tokens.shadowLg,\n    outline: \"none\",\n    ...(side === \"right\"\n      ? { borderLeft: `${tokens.borderWidth} solid ${tokens.border}` }\n      : side === \"left\"\n        ? { borderRight: `${tokens.borderWidth} solid ${tokens.border}` }\n        : { borderTop: `${tokens.borderWidth} solid ${tokens.border}` }),\n    ...style,\n  };\n\n  return (\n    <DrawerContext.Provider value={ctxValue}>\n      {/* biome-ignore lint/a11y/useKeyWithClickEvents: scrim click is a bonus mouse affordance; Escape (the window keydown above) and the Header close button are the keyboard dismissal paths. */}\n      {/* biome-ignore lint/a11y/noStaticElementInteractions: the scrim is a decorative dismissal backdrop; the panel below owns the dialog role/semantics. */}\n      <div\n        className={`nb-drawer-scrim nb-drawer-scrim--${side}`}\n        onClick={(e) => {\n          // A click whose target is the scrim itself (not the panel) dismisses.\n          if (e.target === e.currentTarget) onClose();\n        }}\n      >\n        <div\n          ref={panelRef}\n          role=\"dialog\"\n          aria-modal=\"true\"\n          aria-labelledby={hasTitle ? labelId : undefined}\n          tabIndex={-1}\n          className={`nb-drawer nb-drawer--${side}`}\n          style={panelStyle}\n          {...rest}\n        >\n          {children}\n        </div>\n      </div>\n    </DrawerContext.Provider>\n  );\n}\n\ninterface HeaderProps extends Omit<HTMLAttributes<HTMLElement>, \"title\"> {\n  /**\n   * Heading text — rendered as an `<h2>` and wired as the drawer's accessible\n   * name. Renders **instead of** `children` (pass one or the other, not both).\n   */\n  title?: ReactNode;\n  /** Show a leading back button (e.g. pop one level of a panel stack). */\n  onBack?: () => void;\n  /** Trailing controls placed before the close button. */\n  actions?: ReactNode;\n  /** Show a close button that calls this. */\n  onClose?: () => void;\n  children?: ReactNode;\n}\n\nfunction Header({ title, onBack, actions, onClose, style, children, ...rest }: HeaderProps) {\n  const ctx = useContext(DrawerContext);\n  const hasTitle = title != null;\n\n  // Register the title's presence so the dialog can name itself via this h2.\n  useEffect(() => {\n    if (!ctx || !hasTitle) return;\n    ctx.setHasTitle(true);\n    return () => ctx.setHasTitle(false);\n  }, [ctx, hasTitle]);\n\n  return (\n    <header\n      style={{\n        flexShrink: 0,\n        display: \"flex\",\n        alignItems: \"center\",\n        gap: \"0.75rem\",\n        padding: \"0.875rem 1rem\",\n        borderBottom: `${tokens.borderWidth} solid ${tokens.border}`,\n        fontFamily: tokens.fontSans,\n        fontWeight: tokens.weightSemibold,\n        color: tokens.fg,\n        ...style,\n      }}\n      {...rest}\n    >\n      {onBack ? (\n        <IconButton label=\"Back\" onClick={onBack}>\n          <path\n            d=\"M10 3L5 8l5 5\"\n            stroke=\"currentColor\"\n            strokeWidth=\"1.5\"\n            fill=\"none\"\n            strokeLinecap=\"round\"\n            strokeLinejoin=\"round\"\n          />\n        </IconButton>\n      ) : null}\n      {hasTitle ? (\n        <h2\n          id={ctx?.labelId}\n          style={{\n            flex: 1,\n            minWidth: 0,\n            margin: 0,\n            fontFamily: tokens.fontSans,\n            fontSize: tokens.textBaseSize,\n            lineHeight: tokens.textBaseLine,\n            fontWeight: tokens.weightSemibold,\n            color: tokens.fg,\n            whiteSpace: \"nowrap\",\n            overflow: \"hidden\",\n            textOverflow: \"ellipsis\",\n          }}\n        >\n          {title}\n        </h2>\n      ) : (\n        <div style={{ flex: 1, minWidth: 0 }}>{children}</div>\n      )}\n      {actions ? (\n        <div style={{ display: \"flex\", alignItems: \"center\", gap: \"0.4rem\", flexShrink: 0 }}>\n          {actions}\n        </div>\n      ) : null}\n      {onClose ? (\n        <IconButton label=\"Close\" onClick={onClose}>\n          <path\n            d=\"M4 4l8 8M12 4l-8 8\"\n            stroke=\"currentColor\"\n            strokeWidth=\"1.5\"\n            strokeLinecap=\"round\"\n          />\n        </IconButton>\n      ) : null}\n    </header>\n  );\n}\n\n/** Shared 28px (→44px on coarse pointers) icon button for the header affordances. */\nfunction IconButton({\n  label,\n  onClick,\n  children,\n}: {\n  label: string;\n  onClick: () => void;\n  children: ReactNode;\n}) {\n  return (\n    <button\n      type=\"button\"\n      aria-label={label}\n      onClick={onClick}\n      className=\"nb-drawer-iconbtn\"\n      style={{\n        flexShrink: 0,\n        display: \"inline-flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        border: \"none\",\n        background: \"transparent\",\n        color: tokens.fgMuted,\n        cursor: \"pointer\",\n        borderRadius: tokens.radiusSm,\n      }}\n    >\n      <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" aria-hidden=\"true\">\n        {children}\n      </svg>\n    </button>\n  );\n}\n\nfunction Body({ style, children, ...rest }: HTMLAttributes<HTMLDivElement>) {\n  return (\n    <div style={{ flex: 1, minHeight: 0, overflowY: \"auto\", padding: \"1rem\", ...style }} {...rest}>\n      {children}\n    </div>\n  );\n}\n\nfunction Footer({ style, children, ...rest }: HTMLAttributes<HTMLElement>) {\n  return (\n    <footer\n      style={{\n        flexShrink: 0,\n        padding: \"0.75rem 1rem\",\n        borderTop: `${tokens.borderWidth} solid ${tokens.border}`,\n        ...style,\n      }}\n      {...rest}\n    >\n      {children}\n    </footer>\n  );\n}\n\n/** `Drawer` with `.Header`, `.Body`, `.Footer` slots. */\nexport const Drawer = Object.assign(DrawerRoot, { Header, Body, Footer });\n","/**\n * Layout primitives — the composition atoms. `Stack` (vertical) and `Inline`\n * (horizontal) replace ad-hoc `display:flex` style objects; `Spacer` and\n * `Divider` cover the two other recurring layout needs. Deliberately minimal\n * (no `Box`, no grid system) — the layout scaffolds handle page structure.\n */\n\nimport type { CSSProperties, HTMLAttributes, ReactNode } from \"react\";\nimport { tokens } from \"./tokens.js\";\n\ntype Align = \"start\" | \"center\" | \"end\" | \"stretch\" | \"baseline\";\ntype Justify = \"start\" | \"center\" | \"end\" | \"between\" | \"around\";\n\nconst ALIGN: Record<Align, CSSProperties[\"alignItems\"]> = {\n  start: \"flex-start\",\n  center: \"center\",\n  end: \"flex-end\",\n  stretch: \"stretch\",\n  baseline: \"baseline\",\n};\n\nconst JUSTIFY: Record<Justify, CSSProperties[\"justifyContent\"]> = {\n  start: \"flex-start\",\n  center: \"center\",\n  end: \"flex-end\",\n  between: \"space-between\",\n  around: \"space-around\",\n};\n\ninterface FlexProps extends HTMLAttributes<HTMLDivElement> {\n  gap?: number | string;\n  align?: Align;\n  justify?: Justify;\n  wrap?: boolean;\n  children?: ReactNode;\n}\n\nfunction flexStyle(\n  direction: \"row\" | \"column\",\n  { gap, align, justify, wrap }: FlexProps,\n): CSSProperties {\n  return {\n    display: \"flex\",\n    flexDirection: direction,\n    gap,\n    alignItems: align ? ALIGN[align] : undefined,\n    justifyContent: justify ? JUSTIFY[justify] : undefined,\n    flexWrap: wrap ? \"wrap\" : undefined,\n  };\n}\n\n/** Vertical flex container with `gap`. Defaults to `align: stretch`. */\nexport function Stack({ gap, align, justify, wrap, style, children, ...rest }: FlexProps) {\n  return (\n    <div style={{ ...flexStyle(\"column\", { gap, align, justify, wrap }), ...style }} {...rest}>\n      {children}\n    </div>\n  );\n}\n\n/** Horizontal flex container with `gap`. Defaults to `align: center`. */\nexport function Inline({\n  gap,\n  align = \"center\",\n  justify,\n  wrap,\n  style,\n  children,\n  ...rest\n}: FlexProps) {\n  return (\n    <div style={{ ...flexStyle(\"row\", { gap, align, justify, wrap }), ...style }} {...rest}>\n      {children}\n    </div>\n  );\n}\n\n/** Flexible gap that pushes siblings apart inside a `Stack`/`Inline`. */\nexport function Spacer({ style, ...rest }: HTMLAttributes<HTMLDivElement>) {\n  return <div style={{ flex: 1, ...style }} {...rest} />;\n}\n\ninterface DividerProps extends HTMLAttributes<HTMLDivElement> {\n  orientation?: \"horizontal\" | \"vertical\";\n}\n\n/** A hairline rule using the border token. Horizontal by default. Decorative\n * (`aria-hidden`) — it's a visual divider, not a focusable/valued separator. */\nexport function Divider({ orientation = \"horizontal\", style, ...rest }: DividerProps) {\n  const isVertical = orientation === \"vertical\";\n  return (\n    <div\n      aria-hidden=\"true\"\n      style={{\n        flexShrink: 0,\n        background: tokens.border,\n        ...(isVertical\n          ? { width: tokens.borderWidth, alignSelf: \"stretch\" }\n          : { height: tokens.borderWidth, width: \"100%\" }),\n        ...style,\n      }}\n      {...rest}\n    />\n  );\n}\n","/**\n * EmptyState — centered placeholder for empty lists/views. Optional icon,\n * title, description, and an action slot (e.g. a Button).\n */\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { Stack } from \"../primitives.js\";\nimport { tokens } from \"../tokens.js\";\nimport { Heading, Text } from \"../typography.js\";\n\ninterface EmptyStateProps extends Omit<HTMLAttributes<HTMLDivElement>, \"title\"> {\n  icon?: ReactNode;\n  title?: ReactNode;\n  description?: ReactNode;\n  action?: ReactNode;\n}\n\nexport function EmptyState({ icon, title, description, action, style, ...rest }: EmptyStateProps) {\n  return (\n    <Stack\n      align=\"center\"\n      gap=\"0.5rem\"\n      style={{\n        textAlign: \"center\",\n        padding: \"4rem 1.5rem\",\n        color: tokens.fgMuted,\n        ...style,\n      }}\n      {...rest}\n    >\n      {icon ? <div style={{ color: tokens.fgFaint, marginBottom: \"0.25rem\" }}>{icon}</div> : null}\n      {title ? <Heading size=\"sm\">{title}</Heading> : null}\n      {description ? (\n        <Text size=\"sm\" tone=\"muted\" style={{ maxWidth: 360 }}>\n          {description}\n        </Text>\n      ) : null}\n      {action ? <div style={{ marginTop: \"0.75rem\" }}>{action}</div> : null}\n    </Stack>\n  );\n}\n","/**\n * ListRow — the recurring list item: an optional leading slot (status dot,\n * avatar), a title with optional meta line, and a trailing slot (timestamp,\n * actions). Rounded hover tint, flat at rest — the pattern Research,\n * Conversations, and the Collateral sidebar each re-rolled.\n */\n\nimport type { HTMLAttributes, KeyboardEvent, ReactNode } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\nconst STYLE_ID = \"nb-synapse-listrow\";\nconst RULES = `\n.nb-listrow { transition: background 140ms ease; }\n.nb-listrow--interactive { cursor: pointer; }\n.nb-listrow--interactive:hover { background: var(--nb-listrow-hover); }\n`;\n\ninterface ListRowProps extends Omit<HTMLAttributes<HTMLDivElement>, \"title\"> {\n  title: ReactNode;\n  /** Secondary line under the title. */\n  meta?: ReactNode;\n  /** Leading slot — e.g. a StatusDot or Avatar. */\n  leading?: ReactNode;\n  /** Trailing slot — e.g. a timestamp or actions. */\n  trailing?: ReactNode;\n  /** Enables pointer cursor + hover tint. */\n  interactive?: boolean;\n}\n\nexport function ListRow({\n  title,\n  meta,\n  leading,\n  trailing,\n  interactive = false,\n  style,\n  className,\n  ...rest\n}: ListRowProps) {\n  ensureStyle(STYLE_ID, RULES);\n  const rowStyle: StyleWithVars = {\n    \"--nb-listrow-hover\": tokens.bgSubtle,\n    display: \"grid\",\n    gridTemplateColumns: `${leading ? \"auto \" : \"\"}minmax(0, 1fr)${trailing ? \" auto\" : \"\"}`,\n    columnGap: \"0.75rem\",\n    alignItems: \"baseline\",\n    padding: \"0.65rem 0.75rem\",\n    borderRadius: tokens.radiusSm,\n    ...style,\n  };\n  // When interactive, make the row keyboard-operable (matches Table's rows):\n  // role=\"button\" + tabIndex, and Enter/Space synthesize the click that drives\n  // the consumer's onClick (passed via ...rest). Placed before ...rest so a\n  // consumer can still override any of these explicitly.\n  const interactiveProps = interactive\n    ? {\n        role: \"button\",\n        tabIndex: 0,\n        onKeyDown: (e: KeyboardEvent<HTMLDivElement>) => {\n          if (e.key === \"Enter\" || e.key === \" \") {\n            e.preventDefault();\n            e.currentTarget.click();\n          }\n        },\n      }\n    : {};\n  return (\n    <div\n      className={`nb-listrow ${interactive ? \"nb-listrow--interactive\" : \"\"} ${className ?? \"\"}`.trim()}\n      style={rowStyle}\n      {...interactiveProps}\n      {...rest}\n    >\n      {leading ? <div style={{ alignSelf: \"center\", display: \"flex\" }}>{leading}</div> : null}\n      <div style={{ minWidth: 0 }}>\n        <div\n          style={{\n            fontFamily: tokens.fontSans,\n            fontSize: tokens.textBaseSize,\n            lineHeight: tokens.textBaseLine,\n            fontWeight: tokens.weightMedium,\n            color: tokens.fg,\n            overflow: \"hidden\",\n            textOverflow: \"ellipsis\",\n            whiteSpace: \"nowrap\",\n          }}\n        >\n          {title}\n        </div>\n        {meta ? (\n          <div\n            style={{\n              marginTop: \"0.15rem\",\n              fontFamily: tokens.fontSans,\n              fontSize: tokens.textXsSize,\n              lineHeight: tokens.textXsLine,\n              color: tokens.fgMuted,\n              overflow: \"hidden\",\n              textOverflow: \"ellipsis\",\n              whiteSpace: \"nowrap\",\n            }}\n          >\n            {meta}\n          </div>\n        ) : null}\n      </div>\n      {trailing ? (\n        <div\n          style={{\n            alignSelf: \"center\",\n            display: \"inline-flex\",\n            alignItems: \"center\",\n            gap: \"0.5rem\",\n            fontSize: tokens.textXsSize,\n            color: tokens.fgMuted,\n            whiteSpace: \"nowrap\",\n          }}\n        >\n          {trailing}\n        </div>\n      ) : null}\n    </div>\n  );\n}\n","/**\n * PageHeader — the top of a page: where you are, what this is, and what you can do to it.\n *\n * One component rather than each screen assembling its own, because the parts have to keep\n * one order and one rhythm for a multi-screen app to read as one app. It is also what makes\n * a full-width screen legible as a LEVEL in a hierarchy rather than as a page that happens\n * to be open — the trail above the title is doing that work, not decoration.\n *\n * The order is fixed and the reasons are not interchangeable: the trail comes first because\n * orientation precedes identity; actions sit on the title's row because they act on the\n * thing the title names; the description comes last because it is the only part a reader\n * can skip.\n *\n * **The description is clamped to two lines.** Descriptions here are frequently\n * agent-authored and of no bounded length, and an unbounded paragraph at the top of every\n * screen pushes the content the reader came for below the fold. Two lines is enough to\n * identify the thing and not enough to become the page. Callers with genuinely short,\n * curated copy can raise it; the default protects the common case rather than the tidy one.\n *\n * `status` and `actions` are ReactNode slots, not typed vocabularies. A page header has no\n * business knowing what states a caller's entity can be in or which of its verbs are primary —\n * that knowledge belongs to the app, and a kit that encoded it would need extending for every\n * app that arrived with a different one.\n *\n * **There is no slot for an app's top-level destinations, and that is the design.** They are\n * facets of the app exactly as a record's tabs are facets of the record, so they go in a `Tabs`\n * bar under this header — the same shape at every level, with only the tab bar's contents\n * changing as you descend. Giving them a slot up here put two right-aligned clusters on top of\n * each other, destinations above actions, and made the quieter of the two the more important\n * one. An embedded app has one column and cannot afford a corner that dense.\n */\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport type { StyleWithVars } from \"../tokens.js\";\nimport { Heading, Text } from \"../typography.js\";\nimport { Breadcrumb, type Crumb } from \"./Breadcrumb.js\";\n\nconst STYLE_ID = \"nb-synapse-page-header\";\n// The clamp lives in a stylesheet rule rather than an inline style, following the same\n// pattern Table/Tabs/SegmentedControl use. Two reasons beyond consistency: `display:\n// -webkit-box` and `-webkit-line-clamp` are a matched pair that only works together, so they\n// belong in one place a caller cannot half-override with `style`; and the line count stays\n// parameterized through a custom property, which is how every other knob in this kit travels.\nconst RULES = `\n.nb-page-header__desc {\n  display: -webkit-box;\n  -webkit-box-orient: vertical;\n  -webkit-line-clamp: var(--nb-ph-desc-lines, 2);\n  line-clamp: var(--nb-ph-desc-lines, 2);\n  overflow: hidden;\n}\n`;\n\ninterface PageHeaderProps extends Omit<HTMLAttributes<HTMLElement>, \"title\"> {\n  /** The trail. Omit on a top-level page, which has nothing above it to name. */\n  crumbs?: Crumb[];\n  title: ReactNode;\n  /** Sits beside the title — typically a `Badge`. */\n  status?: ReactNode;\n  /** Sits at the far end of the title's row. Buttons, a menu. */\n  actions?: ReactNode;\n  description?: ReactNode;\n  /** Lines the description is clamped to before ellipsis. `0` removes the clamp. */\n  descriptionLines?: number;\n}\n\nexport function PageHeader({\n  crumbs,\n  title,\n  status,\n  actions,\n  description,\n  descriptionLines = 2,\n  style,\n  ...rest\n}: PageHeaderProps) {\n  ensureStyle(STYLE_ID, RULES);\n  const descVars: StyleWithVars =\n    descriptionLines > 0 ? { \"--nb-ph-desc-lines\": String(descriptionLines) } : {};\n  return (\n    <header\n      style={{ display: \"flex\", flexDirection: \"column\", gap: \"0.5rem\", minWidth: 0, ...style }}\n      {...rest}\n    >\n      {crumbs && crumbs.length > 0 ? <Breadcrumb crumbs={crumbs} /> : null}\n\n      <div\n        style={{\n          display: \"flex\",\n          alignItems: \"center\",\n          justifyContent: \"space-between\",\n          gap: \"1rem\",\n          flexWrap: \"wrap\",\n          minWidth: 0,\n        }}\n      >\n        <div\n          style={{\n            display: \"flex\",\n            alignItems: \"center\",\n            gap: \"0.6rem\",\n            flexWrap: \"wrap\",\n            minWidth: 0,\n          }}\n        >\n          <Heading size=\"md\">{title}</Heading>\n          {status}\n        </div>\n        {/* Rendered only when given. An empty actions box still occupies its row and pulls\n            the title off centre, which reads as a control that failed to load. */}\n        {actions ? (\n          <div style={{ display: \"flex\", alignItems: \"center\", gap: \"0.5rem\", flexShrink: 0 }}>\n            {actions}\n          </div>\n        ) : null}\n      </div>\n\n      {description ? (\n        <Text\n          size=\"sm\"\n          tone=\"muted\"\n          className={descriptionLines > 0 ? \"nb-page-header__desc\" : undefined}\n          // A measure, clamped or not. The clamp needs a width to resolve line boxes\n          // against, and unclamped prose past ~72 characters a line is hard to track back\n          // to the next line's start whatever its length.\n          style={{ maxWidth: \"72ch\", ...descVars }}\n        >\n          {description}\n        </Text>\n      ) : null}\n    </header>\n  );\n}\n","/**\n * Pagination — chrome-less prev/next text links with a \"page X of Y\" counter.\n * 1-based `page`. Buttons disable at the ends.\n */\n\nimport type { HTMLAttributes } from \"react\";\nimport { Inline } from \"../primitives.js\";\nimport { tokens } from \"../tokens.js\";\nimport { TextLink } from \"./Button.js\";\n\ninterface PaginationProps extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n  /** Current page, 1-based. */\n  page: number;\n  /** Total number of pages. */\n  pageCount: number;\n  onChange: (page: number) => void;\n}\n\nexport function Pagination({ page, pageCount, onChange, style, ...rest }: PaginationProps) {\n  const total = Math.max(1, pageCount);\n  const atStart = page <= 1;\n  const atEnd = page >= total;\n  return (\n    <Inline\n      justify=\"between\"\n      style={{\n        fontFamily: tokens.fontSans,\n        fontSize: tokens.textXsSize,\n        color: tokens.fgMuted,\n        letterSpacing: \"0.02em\",\n        ...style,\n      }}\n      {...rest}\n    >\n      <span style={{ fontVariantNumeric: \"tabular-nums\" }}>\n        Page {page} of {total}\n      </span>\n      <Inline gap=\"1rem\">\n        <TextLink disabled={atStart} onClick={() => onChange(page - 1)}>\n          ← Prev\n        </TextLink>\n        <TextLink disabled={atEnd} onClick={() => onChange(page + 1)}>\n          Next →\n        </TextLink>\n      </Inline>\n    </Inline>\n  );\n}\n","/**\n * Prose — a token-styled container for rendered rich text. It applies the\n * NimbleBrain reading typography (ported from the Research app's markdown\n * element map) to whatever HTML it wraps, via a once-injected scoped\n * stylesheet — so it stays dependency-free.\n *\n * Pass pre-rendered nodes as `children`, or a trusted HTML string as `html`.\n * Bring your own markdown parser (`marked`, `react-markdown`, …) upstream; this\n * owns the *styling*, not the parsing — keeping the SDK free of a parser dep.\n */\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { tokens } from \"../tokens.js\";\n\nconst STYLE_ID = \"nb-synapse-prose\";\nconst RULES = `\n.nb-prose {\n  font-family: ${tokens.fontSans};\n  font-size: ${tokens.textBaseSize};\n  line-height: 1.7;\n  color: ${tokens.fg};\n}\n.nb-prose > :first-child { margin-top: 0; }\n.nb-prose > :last-child { margin-bottom: 0; }\n.nb-prose h1, .nb-prose h2 { font-family: ${tokens.fontHeading}; letter-spacing: -0.015em; color: ${tokens.fg}; }\n.nb-prose h1 { font-size: ${tokens.headingMdSize}; line-height: ${tokens.headingMdLine}; margin: 2rem 0 0.75rem; }\n.nb-prose h2 { font-size: ${tokens.headingSmSize}; line-height: ${tokens.headingSmLine}; margin: 1.75rem 0 0.5rem; }\n.nb-prose h3 { font-size: ${tokens.textBaseSize}; font-weight: ${tokens.weightSemibold}; margin: 1.5rem 0 0.35rem; color: ${tokens.fg}; }\n.nb-prose p { margin: 0 0 1rem; }\n.nb-prose ul, .nb-prose ol { margin: 0 0 1rem; padding-left: 1.25rem; }\n.nb-prose li { margin: 0.25rem 0; }\n.nb-prose a { color: ${tokens.accent}; text-decoration: underline; text-underline-offset: 2px; }\n.nb-prose blockquote { margin: 0 0 1rem; padding-left: 1rem; border-left: 2px solid ${tokens.accent}; color: ${tokens.fgMuted}; font-style: italic; }\n.nb-prose code { font-family: ${tokens.fontMono}; font-size: 0.88em; padding: 0.08rem 0.32rem; border-radius: ${tokens.radiusXs}; background: ${tokens.bgSubtle}; }\n.nb-prose pre { font-family: ${tokens.fontMono}; font-size: ${tokens.textSmSize}; line-height: 1.55; margin: 0 0 1.25rem; padding: 0.875rem 1rem; background: ${tokens.bgSubtle}; border-radius: ${tokens.radiusSm}; overflow-x: auto; }\n.nb-prose pre code { padding: 0; background: none; }\n.nb-prose hr { border: none; border-top: 1px solid ${tokens.border}; margin: 2rem 0; }\n.nb-prose strong { font-weight: ${tokens.weightSemibold}; }\n`;\n\ninterface ProseProps\n  extends Omit<HTMLAttributes<HTMLDivElement>, \"children\" | \"dangerouslySetInnerHTML\"> {\n  /** Trusted, pre-sanitized HTML string. */\n  html?: string;\n  children?: ReactNode;\n}\n\nexport function Prose({ html, children, className, ...rest }: ProseProps) {\n  ensureStyle(STYLE_ID, RULES);\n  const cls = `nb-prose ${className ?? \"\"}`.trim();\n  if (html !== undefined) {\n    // biome-ignore lint/security/noDangerouslySetInnerHtml: caller supplies trusted, pre-sanitized HTML by contract.\n    return <div className={cls} dangerouslySetInnerHTML={{ __html: html }} {...rest} />;\n  }\n  return (\n    <div className={cls} {...rest}>\n      {children}\n    </div>\n  );\n}\n","/**\n * SearchField — a text input in two postures: `underline` (invisible at rest,\n * reveals an underline on focus — the Research editorial style) and `boxed`\n * (a bordered field). Focus styling lives in a once-injected stylesheet.\n */\n\nimport type { InputHTMLAttributes } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\nconst STYLE_ID = \"nb-synapse-searchfield\";\nconst RULES = `\n.nb-search { font-family: var(--nb-search-font); color: var(--nb-search-fg); outline: none; }\n.nb-search::placeholder { color: var(--nb-search-placeholder); }\n.nb-search--underline {\n  border: none;\n  border-bottom: 1px solid transparent;\n  background: transparent;\n  padding: 0.3rem 0.1rem;\n  transition: border-color 160ms ease;\n}\n.nb-search--underline:focus { border-bottom-color: var(--nb-search-accent); }\n.nb-search--boxed {\n  border: 1px solid var(--nb-search-border);\n  border-radius: var(--nb-search-radius);\n  background: var(--nb-search-bg);\n  padding: 0.4rem 0.6rem;\n  transition: border-color 160ms ease, box-shadow 160ms ease;\n}\n.nb-search--boxed:focus {\n  border-color: var(--nb-search-accent);\n  box-shadow: 0 0 0 3px color-mix(in oklab, var(--nb-search-accent) 18%, transparent);\n}\n`;\n\ninterface SearchFieldProps extends InputHTMLAttributes<HTMLInputElement> {\n  variant?: \"underline\" | \"boxed\";\n}\n\nexport function SearchField({\n  variant = \"underline\",\n  style,\n  className,\n  type = \"search\",\n  ...rest\n}: SearchFieldProps) {\n  ensureStyle(STYLE_ID, RULES);\n  const fieldStyle: StyleWithVars = {\n    \"--nb-search-font\": tokens.fontSans,\n    \"--nb-search-fg\": tokens.fg,\n    \"--nb-search-placeholder\": tokens.fgFaint,\n    \"--nb-search-accent\": tokens.accent,\n    \"--nb-search-border\": tokens.border,\n    \"--nb-search-bg\": tokens.bgSubtle,\n    \"--nb-search-radius\": tokens.radiusSm,\n    fontSize: tokens.textSmSize,\n    lineHeight: tokens.textSmLine,\n    ...style,\n  };\n  return (\n    <input\n      type={type}\n      className={`nb-search nb-search--${variant} ${className ?? \"\"}`.trim()}\n      style={fieldStyle}\n      {...rest}\n    />\n  );\n}\n","/**\n * SegmentedControl — the view-toggle pattern (Board/Table, All/Today/Week).\n * A small set of mutually-exclusive options; the active one gets a raised pill.\n */\n\nimport type { HTMLAttributes } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\nconst STYLE_ID = \"nb-synapse-segmented\";\nconst RULES = `\n.nb-seg {\n  display: inline-flex;\n  gap: 2px;\n  padding: 2px;\n  border-radius: var(--nb-seg-radius);\n  background: var(--nb-seg-track);\n}\n.nb-seg__btn {\n  border: none;\n  background: transparent;\n  color: var(--nb-seg-fg);\n  font-family: var(--nb-seg-font);\n  font-weight: var(--nb-seg-weight);\n  padding: 0.25rem 0.7rem;\n  border-radius: calc(var(--nb-seg-radius) - 2px);\n  cursor: pointer;\n  transition: color 130ms ease, background 130ms ease;\n  white-space: nowrap;\n}\n.nb-seg__btn:hover:not([aria-pressed=\"true\"]) { color: var(--nb-seg-fg-strong); }\n.nb-seg__btn[aria-pressed=\"true\"] {\n  background: var(--nb-seg-active-bg);\n  color: var(--nb-seg-fg-strong);\n  box-shadow: var(--nb-seg-active-shadow);\n}\n`;\n\ninterface Option<T extends string> {\n  label: string;\n  value: T;\n}\n\ninterface SegmentedControlProps<T extends string>\n  extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n  options: Option<T>[];\n  value: T;\n  onChange: (value: T) => void;\n}\n\nexport function SegmentedControl<T extends string>({\n  options,\n  value,\n  onChange,\n  style,\n  className,\n  ...rest\n}: SegmentedControlProps<T>) {\n  ensureStyle(STYLE_ID, RULES);\n  const trackStyle: StyleWithVars = {\n    \"--nb-seg-radius\": tokens.radiusSm,\n    \"--nb-seg-track\": tokens.bgSubtle,\n    \"--nb-seg-fg\": tokens.fgMuted,\n    \"--nb-seg-fg-strong\": tokens.fg,\n    \"--nb-seg-font\": tokens.fontSans,\n    \"--nb-seg-weight\": tokens.weightMedium,\n    \"--nb-seg-active-bg\": tokens.bgRaised,\n    \"--nb-seg-active-shadow\": tokens.shadowSm,\n    fontSize: tokens.textSmSize,\n    lineHeight: tokens.textSmLine,\n    ...style,\n  };\n  return (\n    // biome-ignore lint/a11y/useSemanticElements: role=\"group\" with aria-label is the correct grouping for a set of toggle buttons; <fieldset> would impose form semantics this control doesn't have.\n    <div className={`nb-seg ${className ?? \"\"}`.trim()} role=\"group\" style={trackStyle} {...rest}>\n      {options.map((opt) => (\n        <button\n          key={opt.value}\n          type=\"button\"\n          className=\"nb-seg__btn\"\n          aria-pressed={opt.value === value}\n          onClick={() => onChange(opt.value)}\n        >\n          {opt.label}\n        </button>\n      ))}\n    </div>\n  );\n}\n","/**\n * Spinner — a minimal rotating indicator for inline/button loading states.\n */\n\nimport type { HTMLAttributes } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\nconst STYLE_ID = \"nb-synapse-spinner\";\nconst RULES = `\n@keyframes nb-spin { to { transform: rotate(360deg); } }\n.nb-spinner { animation: nb-spin 0.7s linear infinite; }\n@media (prefers-reduced-motion: reduce) { .nb-spinner { animation-duration: 1.6s; } }\n`;\n\ninterface SpinnerProps extends HTMLAttributes<HTMLSpanElement> {\n  /** Diameter in px. Default 16. */\n  size?: number;\n  /** Arc color. Defaults to the accent token. */\n  color?: string;\n}\n\nexport function Spinner({ size = 16, color, style, className, ...rest }: SpinnerProps) {\n  ensureStyle(STYLE_ID, RULES);\n  const spinnerStyle: StyleWithVars = {\n    display: \"inline-block\",\n    flexShrink: 0,\n    width: size,\n    height: size,\n    borderRadius: \"50%\",\n    border: `2px solid ${tokens.border}`,\n    borderTopColor: color ?? tokens.accent,\n    boxSizing: \"border-box\",\n    ...style,\n  };\n  return (\n    <span\n      className={`nb-spinner ${className ?? \"\"}`.trim()}\n      role=\"status\"\n      aria-label=\"Loading\"\n      style={spinnerStyle}\n      {...rest}\n    />\n  );\n}\n","/**\n * StatusDot — a small colored dot for run/task status. The `working` state\n * gets a living ripple-pulse (ported from the Research app), gated on\n * `prefers-reduced-motion`. Same component in list rows and detail headers so\n * status reads identically everywhere.\n */\n\nimport type { HTMLAttributes } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\nexport type Status = \"working\" | \"completed\" | \"failed\" | \"idle\";\n\nconst COLOR: Record<Status, string> = {\n  working: tokens.accent,\n  completed: tokens.success,\n  failed: tokens.danger,\n  idle: tokens.fgFaint,\n};\n\nconst STYLE_ID = \"nb-synapse-statusdot\";\nconst KEYFRAMES = `\n@keyframes nb-statusdot-pulse {\n  0%   { box-shadow: 0 0 0 0 var(--nb-statusdot-ring); transform: scale(1); }\n  70%  { box-shadow: 0 0 0 7px transparent; transform: scale(1.15); }\n  100% { box-shadow: 0 0 0 0 transparent; transform: scale(1); }\n}\n.nb-statusdot--working {\n  animation: nb-statusdot-pulse 1.6s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n}\n@media (prefers-reduced-motion: reduce) {\n  .nb-statusdot--working { animation: none; box-shadow: 0 0 0 2px var(--nb-statusdot-ring); }\n}\n`;\n\ninterface StatusDotProps extends Omit<HTMLAttributes<HTMLSpanElement>, \"color\"> {\n  status?: Status;\n  /** Override the dot color (any CSS color / token). */\n  color?: string;\n  /** Diameter in px. Default 8. */\n  size?: number;\n}\n\nexport function StatusDot({\n  status = \"idle\",\n  color,\n  size = 8,\n  style,\n  className,\n  ...rest\n}: StatusDotProps) {\n  ensureStyle(STYLE_ID, KEYFRAMES);\n  const dotColor = color ?? COLOR[status];\n  const working = status === \"working\";\n  const dotStyle: StyleWithVars = {\n    display: \"inline-block\",\n    flexShrink: 0,\n    width: size,\n    height: size,\n    borderRadius: \"50%\",\n    background: dotColor,\n    // Ring color for the pulse keyframe — a faded copy of the dot color.\n    \"--nb-statusdot-ring\": `color-mix(in oklab, ${dotColor} 45%, transparent)`,\n    ...style,\n  };\n  return (\n    <span\n      className={working ? `nb-statusdot--working ${className ?? \"\"}`.trim() : className}\n      style={dotStyle}\n      {...rest}\n    />\n  );\n}\n","/**\n * Table — a token-styled data table with declarative columns. For the tabular\n * list surfaces (CRM contacts/deals) that simple `ListRow`s don't fit. Renders\n * a real `<table>` for semantics; header is sticky; rows hover-tint and can be\n * clickable. Sorting / selection / virtualization are deliberately out of v1 —\n * compose `Pagination` for paging.\n *\n * **A column that truncates must declare a `width`.** The default is CSS auto\n * table layout, which sizes every column to its content — so a long cell has no\n * width to be clipped against and instead widens the table past its container,\n * carrying the later columns off the pane. Declaring a width on ANY column\n * switches the table to fixed layout, which is what gives a truncating cell\n * something to overflow. This is the whole reason `width` exists on `Column`,\n * and it is easy to leave off because nothing fails loudly when you do: the\n * table renders, the text is there, and the columns you cannot see are simply\n * past the right edge.\n *\n * Horizontal scrolling is opt-in via `minWidth` — the width below which the\n * table scrolls rather than crushing. It is not the default because it costs\n * the sticky header: an `overflow-x` container captures the stickiness that\n * `position: sticky` resolves against the page's own scroller, and CSS gives no\n * way to scroll one axis while leaving the other visible. A table that fits does\n * not need it; a genuinely wide one is worth the trade, and the caller is the\n * one who knows which it is.\n */\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\ntype Align = \"left\" | \"right\" | \"center\";\n\nexport interface Column<T> {\n  /** Stable column id. */\n  key: string;\n  header: ReactNode;\n  /** Cell content for a row. */\n  render: (row: T, index: number) => ReactNode;\n  align?: Align;\n  /**\n   * Column width (`\"40%\"`, `220`, `\"12rem\"`). Declaring one on any column switches\n   * the table to `table-layout: fixed`, and columns without a width then divide the\n   * remainder equally. Required on any column whose cell truncates — see the note on\n   * the module above.\n   */\n  width?: number | string;\n}\n\ninterface TableProps<T> extends Omit<HTMLAttributes<HTMLTableElement>, \"children\"> {\n  data: T[];\n  columns: Column<T>[];\n  /** Stable key per row. */\n  rowKey: (row: T, index: number) => string | number;\n  onRowClick?: (row: T, index: number) => void;\n  /** Shown when `data` is empty. */\n  empty?: ReactNode;\n  /**\n   * The narrowest this table stays readable, and the switch that turns scrolling on.\n   *\n   * A fixed-layout table has no lower bound of its own, so seven columns in a 400px pane\n   * become seven clipped headers and a badge overflowing its cell. Below this width the\n   * table scrolls inside its own container instead of crushing — and setting the floor is\n   * the only way to ask for that, because a scroller with no floor has no defined moment to\n   * engage: under fixed layout the table always fits its container, and under auto layout it\n   * engages at whatever width the content happens to reach.\n   *\n   * The cost is the sticky header. An `overflow-x` container captures the stickiness\n   * `position: sticky` resolves against the page's own scroller, and CSS gives no way to\n   * scroll one axis while leaving the other visible — so a table without a floor keeps its\n   * sticky header, and one with a floor trades it.\n   */\n  minWidth?: number | string;\n}\n\nconst STYLE_ID = \"nb-synapse-table\";\nconst RULES = `\n.nb-table { width: 100%; border-collapse: collapse; font-family: var(--nb-table-font); }\n.nb-table th, .nb-table td {\n  padding: 0.55rem 0.75rem;\n  border-bottom: var(--nb-table-border);\n  font-size: var(--nb-table-size); line-height: var(--nb-table-line);\n}\n.nb-table thead th {\n  position: sticky; top: 0; z-index: 1;\n  background: var(--nb-table-head-bg);\n  color: var(--nb-table-muted);\n  font-weight: var(--nb-table-semibold);\n  font-size: var(--nb-table-xs); text-align: left;\n  text-transform: uppercase; letter-spacing: 0.04em;\n}\n.nb-table tbody td { color: var(--nb-table-fg); }\n.nb-table tbody tr.nb-table__row--clickable { cursor: pointer; }\n.nb-table tbody tr.nb-table__row--clickable:hover { background: var(--nb-table-hover); }\n`;\n\nexport function Table<T>({\n  data,\n  columns,\n  rowKey,\n  onRowClick,\n  empty,\n  minWidth,\n  style,\n  className,\n  ...rest\n}: TableProps<T>) {\n  ensureStyle(STYLE_ID, RULES);\n\n  const vars: Record<`--${string}`, string> = {\n    \"--nb-table-font\": tokens.fontSans,\n    \"--nb-table-fg\": tokens.fg,\n    \"--nb-table-muted\": tokens.fgMuted,\n    \"--nb-table-head-bg\": tokens.bg,\n    \"--nb-table-hover\": tokens.bgSubtle,\n    \"--nb-table-border\": `${tokens.borderWidth} solid ${tokens.border}`,\n    \"--nb-table-size\": tokens.textSmSize,\n    \"--nb-table-line\": tokens.textSmLine,\n    \"--nb-table-xs\": tokens.textXsSize,\n    \"--nb-table-semibold\": tokens.weightSemibold,\n  };\n\n  if (data.length === 0 && empty !== undefined) {\n    return <>{empty}</>;\n  }\n\n  // Any declared width means the caller has an opinion about proportions, and auto layout\n  // would ignore it in favour of content — so one width switches the whole table to fixed.\n  // Derived rather than a separate prop: a `width` that silently did nothing is the trap\n  // this replaces, not a second knob to remember alongside it.\n  const fixed = columns.some((col) => col.width !== undefined);\n  const tableStyle: StyleWithVars = {\n    ...vars,\n    ...(fixed ? { tableLayout: \"fixed\" as const } : {}),\n    ...(minWidth !== undefined ? { minWidth } : {}),\n    ...style,\n  };\n\n  const table = (\n    <table className={`nb-table ${className ?? \"\"}`.trim()} style={tableStyle} {...rest}>\n      <thead>\n        <tr>\n          {columns.map((col) => (\n            <th\n              key={col.key}\n              scope=\"col\"\n              style={{ width: col.width, textAlign: col.align ?? \"left\" }}\n            >\n              {col.header}\n            </th>\n          ))}\n        </tr>\n      </thead>\n      <tbody>\n        {data.map((row, i) => {\n          const clickable = Boolean(onRowClick);\n          return (\n            <tr\n              key={rowKey(row, i)}\n              className={clickable ? \"nb-table__row--clickable\" : undefined}\n              tabIndex={clickable ? 0 : undefined}\n              onClick={clickable ? () => onRowClick?.(row, i) : undefined}\n              onKeyDown={\n                clickable\n                  ? (e) => {\n                      if (e.key === \"Enter\" || e.key === \" \") {\n                        e.preventDefault();\n                        onRowClick?.(row, i);\n                      }\n                    }\n                  : undefined\n              }\n            >\n              {columns.map((col) => (\n                <td key={col.key} style={{ textAlign: col.align ?? \"left\" }}>\n                  {col.render(row, i)}\n                </td>\n              ))}\n            </tr>\n          );\n        })}\n      </tbody>\n    </table>\n  );\n\n  if (minWidth === undefined) return table;\n  // `tabIndex={0}` is not decoration. A scroll container that is neither focusable nor holds\n  // a focusable descendant cannot be scrolled by keyboard at all (WCAG 2.1.1; axe's\n  // `scrollable-region-focusable`), and a read-only table has no focusable descendants —\n  // rows take a tabIndex only when `onRowClick` is set. Without this, every column past the\n  // right edge is reachable with a pointer and by nothing else.\n  //\n  // `role=\"region\"` only when the caller named the table, because a region without an\n  // accessible name is its own violation. The name is mirrored from the caller's own\n  // `aria-label` rather than taken as a new prop: the label already reaches the table\n  // through `rest`, and inventing a second way to say the same thing under review is how a\n  // kit grows two spellings of one idea.\n  const label = (rest as { \"aria-label\"?: string })[\"aria-label\"];\n  // Role and name travel together or not at all — an `aria-label` on a roleless element names\n  // nothing, and a `region` without a name is its own violation.\n  const named = label ? ({ role: \"region\", \"aria-label\": label } as const) : {};\n  return (\n    <div\n      // biome-ignore lint/a11y/noNoninteractiveTabindex: the two requirements point opposite ways here, and a scroll container is the case this rule does not model. axe's `scrollable-region-focusable` REQUIRES the tabIndex, because a container that is neither focusable nor holds a focusable descendant cannot be scrolled by keyboard at all (WCAG 2.1.1) — and a read-only table has no focusable descendants, since rows take a tabIndex only when `onRowClick` is set. Removing this makes every column past the right edge pointer-only.\n      tabIndex={0}\n      {...named}\n      // `max-width: 100%` as well as `overflow-x`, because a flex or grid item's default\n      // `min-width: auto` lets it grow to its content and the scroller never engages — the\n      // container would widen instead, which is the failure this exists to stop.\n      style={{ overflowX: \"auto\", maxWidth: \"100%\" }}\n    >\n      {table}\n    </div>\n  );\n}\n","/**\n * Tabs — facets of ONE entity, rendered as an underlined bar.\n *\n * **Why this exists beside `SegmentedControl`, which is also a row of exclusive choices.**\n * They are the same control mechanically and different jobs, and an app that uses one\n * component for both stacks two or three identical pill rows down the page — app\n * navigation, then entity facets, then a list filter, all wearing one costume. The reader\n * cannot tell which row changes what, and the screen reads as noise rather than hierarchy.\n * So the distinction is carried in the FORM: tabs are an underlined bar that belongs to the\n * thing above them, pills are a raised track that belongs to the thing below them.\n *\n * The rule that decides which to reach for:\n *\n *   - **Tabs** change which FACET of one chosen entity is shown. They add no selection, so\n *     they add no level — the entity is the same before and after.\n *   - **SegmentedControl** narrows or reshapes a SET. A status filter over a list, a\n *     board/table toggle.\n *\n * Full ARIA tab semantics (`role=\"tablist\"`, roving focus, arrow keys) because a tab bar is\n * a documented pattern a screen reader user already knows, and half of it — buttons with no\n * relationship declared between them — is worse than plain buttons, which at least do not\n * promise a structure that is not there.\n */\n\nimport { type HTMLAttributes, type KeyboardEvent, useRef } from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\n\nconst STYLE_ID = \"nb-synapse-tabs\";\nconst RULES = `\n.nb-tabs {\n  display: flex;\n  align-items: stretch;\n  gap: var(--nb-tabs-gap);\n  border-bottom: var(--nb-tabs-rule);\n  overflow-x: auto;\n  scrollbar-width: none;\n}\n.nb-tabs::-webkit-scrollbar { display: none; }\n.nb-tabs__tab {\n  border: none;\n  background: transparent;\n  color: var(--nb-tabs-fg);\n  font-family: var(--nb-tabs-font);\n  font-weight: var(--nb-tabs-weight);\n  font-size: var(--nb-tabs-size);\n  line-height: var(--nb-tabs-line);\n  padding: 0.4rem 0.15rem 0.55rem;\n  cursor: pointer;\n  white-space: nowrap;\n  position: relative;\n  transition: color 130ms ease;\n}\n.nb-tabs__tab::after {\n  content: \"\";\n  position: absolute;\n  /* bottom 0, not -1px. overflow-x auto makes the computed overflow-y auto as well, and\n     clipping happens at the PADDING box - so a negative offset put 1px of the 2px accent\n     outside it: the underline rendered half-height and left 1px of phantom overflow. */\n  left: 0; right: 0; bottom: 0;\n  height: 2px;\n  border-radius: 2px 2px 0 0;\n  background: transparent;\n  transition: background 130ms ease;\n}\n.nb-tabs__tab:hover { color: var(--nb-tabs-fg-strong); }\n.nb-tabs__tab[aria-selected=\"true\"] {\n  color: var(--nb-tabs-fg-strong);\n  font-weight: var(--nb-tabs-weight-active);\n}\n.nb-tabs__tab[aria-selected=\"true\"]::after { background: var(--nb-tabs-accent); }\n.nb-tabs__tab:focus-visible {\n  outline: 2px solid var(--nb-tabs-ring);\n  outline-offset: -2px;\n  border-radius: var(--nb-tabs-radius);\n}\n`;\n\ninterface Tab<T extends string> {\n  label: string;\n  value: T;\n  /** A small trailing count. Rendered muted, and omitted entirely when undefined. */\n  count?: number;\n}\n\ninterface TabsProps<T extends string> extends Omit<HTMLAttributes<HTMLDivElement>, \"onChange\"> {\n  tabs: Tab<T>[];\n  value: T;\n  onChange: (value: T) => void;\n  /** Accessible name for the tab set — what these are facets OF. */\n  label?: string;\n}\n\nexport function Tabs<T extends string>({\n  tabs,\n  value,\n  onChange,\n  label,\n  style,\n  className,\n  onKeyDown: callerKeyDown,\n  ...rest\n}: TabsProps<T>) {\n  ensureStyle(STYLE_ID, RULES);\n  const barRef = useRef<HTMLDivElement>(null);\n\n  const barStyle: StyleWithVars = {\n    \"--nb-tabs-gap\": \"1.25rem\",\n    \"--nb-tabs-rule\": `${tokens.borderWidth} solid ${tokens.border}`,\n    \"--nb-tabs-fg\": tokens.fgMuted,\n    \"--nb-tabs-fg-strong\": tokens.fg,\n    \"--nb-tabs-accent\": tokens.accent,\n    \"--nb-tabs-ring\": tokens.ring,\n    \"--nb-tabs-font\": tokens.fontSans,\n    \"--nb-tabs-weight\": tokens.weightMedium,\n    \"--nb-tabs-weight-active\": tokens.weightSemibold,\n    \"--nb-tabs-size\": tokens.textSmSize,\n    \"--nb-tabs-line\": tokens.textSmLine,\n    \"--nb-tabs-radius\": tokens.radiusXs,\n    ...style,\n  };\n\n  // Arrow keys move FOCUS, and selection follows it.\n  //\n  // Moving selection alone was the bug this replaces: the roving tabindex handed tabIndex=0\n  // to the newly selected tab while the browser's focus stayed on the previous one, so the\n  // focus ring sat on an unselected tab, a screen reader announced nothing (AT announces\n  // focus, not aria-selected), and tabbing out and back landed somewhere else. The APG tabs\n  // pattern specifies that arrows move focus with activation following it, and half of a\n  // pattern a reader already knows is worse than none of it.\n  //\n  // Focused imperatively off the bar's own DOM rather than through an effect keyed on value:\n  // the buttons are already rendered so the target exists now, and an effect would also\n  // steal focus when a PARENT changed the value - a tab bar grabbing focus because something\n  // else navigated.\n  //\n  // The caller's own handler runs FIRST and can suppress navigation with preventDefault().\n  // `onKeyDown` is part of this component's public prop type, so accepting one and never\n  // calling it is the same silent lie as letting it replace the contract outright - the two\n  // failures a caller cannot tell apart from the type. Opting out is now something they do\n  // on purpose, in one visible line.\n  const onKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n    callerKeyDown?.(e);\n    if (e.defaultPrevented) return;\n    const at = tabs.findIndex((t) => t.value === value);\n    if (at < 0) return;\n    let to: number;\n    if (e.key === \"ArrowRight\") to = (at + 1) % tabs.length;\n    else if (e.key === \"ArrowLeft\") to = (at - 1 + tabs.length) % tabs.length;\n    else if (e.key === \"Home\") to = 0;\n    else if (e.key === \"End\") to = tabs.length - 1;\n    else return;\n    e.preventDefault();\n    // Arrows wrap, because a bar with a dead end makes the reader reverse direction to reach\n    // the tab one step past the one they are on. Home and End are absolute and do not - so\n    // they are the two keys that can land on the tab already held, and a change event for a\n    // value that did not change is one a caller has to defend against (a refetch, a route\n    // push, an analytics event). Focus still moves, because the key was still pressed.\n    if (to !== at) onChange(tabs[to].value);\n    barRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"tab\"]')[to]?.focus();\n  };\n\n  return (\n    <div\n      // `rest` FIRST, so nothing a caller passes can overwrite what makes this a tablist.\n      // `role` and `aria-label` are the contract the pattern rests on; a caller who could\n      // replace them would have a bar announcing something it does not implement.\n      {...rest}\n      ref={barRef}\n      role=\"tablist\"\n      aria-label={label}\n      className={`nb-tabs ${className ?? \"\"}`.trim()}\n      style={barStyle}\n      onKeyDown={onKeyDown}\n    >\n      {tabs.map((tab) => {\n        const selected = tab.value === value;\n        return (\n          <button\n            key={tab.value}\n            type=\"button\"\n            role=\"tab\"\n            aria-selected={selected}\n            // Roving tabindex: one stop for the whole bar, then arrows within it.\n            tabIndex={selected ? 0 : -1}\n            className=\"nb-tabs__tab\"\n            onClick={() => onChange(tab.value)}\n          >\n            {tab.label}\n            {tab.count !== undefined ? (\n              <span style={{ marginLeft: \"0.35rem\", color: tokens.fgFaint }}>{tab.count}</span>\n            ) : null}\n          </button>\n        );\n      })}\n    </div>\n  );\n}\n","/**\n * AppFrame — the universal app chrome: a fixed header, a scrollable body, and\n * an optional fixed footer, filling the iframe pane. Every Synapse app uses it;\n * a body layout (SidebarLayout, ListView, …) goes inside `AppFrame.Body`.\n *\n * The shell fills the pane with `height: 100%`, which needs a definite-height\n * ancestor chain (`#root` → `body` → `html`) — something a bare app document\n * does not supply on its own. So AppFrame establishes that chain itself on\n * render via `injectBaseReset()`; without it the shell would collapse to\n * content height. Apps wanting the chain before first paint can also\n * `import \"@nimblebrain/synapse/ui/base\"` in their entry.\n *\n * The `contentWidth` knob is a personality lever: `reading` centers header,\n * body, and footer in a ~760px column (Conversations, Research), while `full`\n * uses the whole pane (CRM, dashboards). Header/body/footer share the same\n * column so the composition reads as one page.\n *\n * **There is deliberately no chrome slot here.** A Synapse app does not own its\n * window: the host spends the left edge on a rail and the right on chat, so an\n * app-level bar is a third chrome layer whose rule lands a few pixels off the\n * chat panel's — two near-parallel lines that read as a mistake and that no\n * amount of styling reconciles. Top-level destinations go in a tab bar under\n * the page header instead; see `PageLayout`.\n */\n\nimport {\n  type CSSProperties,\n  createContext,\n  type HTMLAttributes,\n  type ReactNode,\n  useContext,\n} from \"react\";\nimport { injectBaseReset } from \"../internal/base-reset.js\";\nimport { tokens } from \"../tokens.js\";\n\ntype ContentWidth = \"reading\" | \"full\";\nconst READING_MAX = 760;\nconst ContentWidthCtx = createContext<ContentWidth>(\"full\");\n\nfunction columnStyle(width: ContentWidth): CSSProperties {\n  return width === \"reading\" ? { maxWidth: READING_MAX, marginInline: \"auto\", width: \"100%\" } : {};\n}\n\ninterface AppFrameProps extends HTMLAttributes<HTMLDivElement> {\n  contentWidth?: ContentWidth;\n  children?: ReactNode;\n}\n\nfunction AppFrameRoot({ contentWidth = \"full\", style, children, ...rest }: AppFrameProps) {\n  // The shell's `height: 100%` only resolves against a definite-height ancestor\n  // chain; supply it (same render-time pattern as the components' `ensureStyle`).\n  injectBaseReset();\n  return (\n    <ContentWidthCtx.Provider value={contentWidth}>\n      <div\n        style={{\n          display: \"flex\",\n          flexDirection: \"column\",\n          height: \"100%\",\n          minHeight: 0,\n          background: tokens.bg,\n          color: tokens.fg,\n          fontFamily: tokens.fontSans,\n          ...style,\n        }}\n        {...rest}\n      >\n        {children}\n      </div>\n    </ContentWidthCtx.Provider>\n  );\n}\n\nfunction Header({ style, children, ...rest }: HTMLAttributes<HTMLElement>) {\n  const width = useContext(ContentWidthCtx);\n  return (\n    <header style={{ flexShrink: 0, padding: \"1.25rem 1.5rem 0.75rem\", ...style }} {...rest}>\n      <div style={columnStyle(width)}>{children}</div>\n    </header>\n  );\n}\n\ninterface BodyProps extends HTMLAttributes<HTMLDivElement> {\n  /**\n   * Host a full-bleed body layout (SidebarLayout, BoardLayout) edge-to-edge:\n   * no padding, no reading column, and the body itself doesn't scroll — the\n   * layout's panes manage their own scroll. Leave off for plain content\n   * (lists, forms), which get the padded reading/full column.\n   */\n  bleed?: boolean;\n}\n\nfunction Body({ bleed = false, style, children, ...rest }: BodyProps) {\n  const width = useContext(ContentWidthCtx);\n  if (bleed) {\n    return (\n      <div\n        style={{\n          flex: 1,\n          minHeight: 0,\n          display: \"flex\",\n          flexDirection: \"column\",\n          overflow: \"hidden\",\n          ...style,\n        }}\n        {...rest}\n      >\n        {children}\n      </div>\n    );\n  }\n  return (\n    <div style={{ flex: 1, minHeight: 0, overflowY: \"auto\", ...style }} {...rest}>\n      <div style={{ ...columnStyle(width), padding: \"0.75rem 1.5rem 1.5rem\" }}>{children}</div>\n    </div>\n  );\n}\n\nfunction Footer({ style, children, ...rest }: HTMLAttributes<HTMLElement>) {\n  const width = useContext(ContentWidthCtx);\n  return (\n    <footer\n      style={{\n        flexShrink: 0,\n        padding: \"0.75rem 1.5rem\",\n        borderTop: `${tokens.borderWidth} solid ${tokens.border}`,\n        ...style,\n      }}\n      {...rest}\n    >\n      <div style={columnStyle(width)}>{children}</div>\n    </footer>\n  );\n}\n\n/** `AppFrame` with `.Header`, `.Body`, `.Footer` slots. */\nexport const AppFrame = Object.assign(AppFrameRoot, { Header, Body, Footer });\n","/**\n * `useBreakpoint` — responsive hook keyed to an element's OWN width, not the\n * device viewport. Synapse apps render in an iframe pane whose width the host\n * controls (fullscreen, split, or a narrow sidebar), so layouts must react to\n * the space they're actually given.\n *\n * Attach the returned `ref` to the element whose width drives the decision.\n * Width is measured synchronously on mount (no first-frame flash) and kept live\n * via `ResizeObserver`. SSR/test-safe: without a DOM/`ResizeObserver` it simply\n * reports `isNarrow: false`.\n */\n\nimport { type RefObject, useLayoutEffect, useRef, useState } from \"react\";\n\nexport function useBreakpoint<T extends HTMLElement = HTMLDivElement>(\n  breakpoint: number,\n): { ref: RefObject<T | null>; isNarrow: boolean } {\n  const ref = useRef<T>(null);\n  const [width, setWidth] = useState<number | null>(null);\n\n  useLayoutEffect(() => {\n    const el = ref.current;\n    if (!el) return;\n    // Synchronous initial measure — runs before paint, so the first painted\n    // frame already reflects the real width. Border-box, matching the observer\n    // below (so there's no jump on the first resize if the element has padding).\n    setWidth(el.getBoundingClientRect().width);\n    if (typeof ResizeObserver === \"undefined\") return;\n    const ro = new ResizeObserver((entries) => {\n      const entry = entries[0];\n      const w = entry?.borderBoxSize?.[0]?.inlineSize ?? entry?.contentRect.width;\n      if (typeof w === \"number\") setWidth(w);\n    });\n    ro.observe(el);\n    return () => ro.disconnect();\n  }, []);\n\n  return { ref, isNarrow: width !== null && width < breakpoint };\n}\n","/**\n * ListDetailLayout — a master list beside a detail pane (CRM contacts → record,\n * Research runs → report, conversations → thread). Responsive to the layout's\n * own width: side-by-side when wide; below `breakpoint` it shows one at a time —\n * the list, or the detail when something is `selected`, with a `Back`\n * affordance to return.\n *\n * `selected` is driven by the app's own selection state. Place\n * `<ListDetailLayout.Back />` at the top of `Detail`; it renders only on a\n * narrow pane and calls `onBack`.\n */\n\nimport { createContext, type HTMLAttributes, type ReactNode, useContext } from \"react\";\nimport { TextLink } from \"../components/Button.js\";\nimport { tokens } from \"../tokens.js\";\nimport { useBreakpoint } from \"./use-container-width.js\";\n\ninterface ListDetailState {\n  collapsed: boolean;\n  selected: boolean;\n  listWidth: number | string;\n  onBack?: () => void;\n}\n\nconst ListDetailCtx = createContext<ListDetailState | null>(null);\n\n/** Read the list/detail responsive state — for custom back affordances. */\nexport function useListDetail(): ListDetailState {\n  const ctx = useContext(ListDetailCtx);\n  if (!ctx) throw new Error(\"useListDetail must be used within <ListDetailLayout>\");\n  return ctx;\n}\n\ninterface ListDetailLayoutProps extends HTMLAttributes<HTMLDivElement> {\n  /** Is a detail open? Drives which pane shows on a narrow layout. */\n  selected?: boolean;\n  /** Called by `Back` (and custom triggers) to return to the list when narrow. */\n  onBack?: () => void;\n  /** Master list width when side-by-side. Default 320. */\n  listWidth?: number | string;\n  /** Collapse to one-at-a-time below this layout width (px). Default 720. */\n  breakpoint?: number;\n  children?: ReactNode;\n}\n\nfunction ListDetailLayoutRoot({\n  selected = false,\n  onBack,\n  listWidth = 320,\n  breakpoint = 720,\n  style,\n  children,\n  ...rest\n}: ListDetailLayoutProps) {\n  const { ref, isNarrow } = useBreakpoint<HTMLDivElement>(breakpoint);\n  return (\n    <ListDetailCtx.Provider value={{ collapsed: isNarrow, selected, listWidth, onBack }}>\n      <div\n        ref={ref}\n        style={{ display: \"flex\", flexDirection: \"row\", height: \"100%\", minHeight: 0, ...style }}\n        {...rest}\n      >\n        {children}\n      </div>\n    </ListDetailCtx.Provider>\n  );\n}\n\nfunction List({ style, children, ...rest }: HTMLAttributes<HTMLElement>) {\n  const { collapsed, selected, listWidth } = useListDetail();\n  if (collapsed && selected) return null; // detail has the stage\n  const border = `${tokens.borderWidth} solid ${tokens.border}`;\n  return (\n    <section\n      style={{\n        // Clip horizontally, scroll vertically. A too-wide child (e.g. an\n        // auto-layout <table> that won't shrink below its content) would\n        // otherwise spill out of this fixed-width rail and paint over the\n        // detail pane. `minWidth: 0` lets the rail participate in flex\n        // sizing without being forced wider by its content.\n        overflow: \"hidden auto\",\n        ...(collapsed\n          ? { flex: 1, minWidth: 0 }\n          : { width: listWidth, minWidth: 0, flexShrink: 0, borderRight: border }),\n        ...style,\n      }}\n      {...rest}\n    >\n      {children}\n    </section>\n  );\n}\n\nfunction Detail({ style, children, ...rest }: HTMLAttributes<HTMLDivElement>) {\n  const { collapsed, selected } = useListDetail();\n  if (collapsed && !selected) return null; // list has the stage\n  return (\n    <div style={{ flex: 1, minWidth: 0, minHeight: 0, overflowY: \"auto\", ...style }} {...rest}>\n      {children}\n    </div>\n  );\n}\n\ninterface BackProps {\n  children?: ReactNode;\n  style?: React.CSSProperties;\n}\n\n/** \"← Back\" affordance — renders only on a narrow pane with a detail open. */\nfunction Back({ children, style }: BackProps) {\n  const { collapsed, selected, onBack } = useListDetail();\n  if (!collapsed || !selected) return null;\n  return (\n    <TextLink onClick={() => onBack?.()} style={{ marginBottom: \"0.5rem\", ...style }}>\n      {children ?? \"← Back\"}\n    </TextLink>\n  );\n}\n\n/** `ListDetailLayout` with `.List`, `.Detail`, and `.Back` slots. */\nexport const ListDetailLayout = Object.assign(ListDetailLayoutRoot, { List, Detail, Back });\n","/**\n * PageLayout — one screen of a Synapse app, assembled in the one order that works.\n *\n * A header naming what you are looking at, a tab bar of that thing's facets, an optional\n * toolbar over the content, then the content. Every level of an app is this shape, and the\n * only thing descending changes is whose facets the tab bar holds: at the root the header\n * names the app and the tabs are its sections; a level down a trail appears above the header,\n * the header names the record, and the tabs are the record's own.\n *\n * **Why this is a component when the kit says thin compositions stay recipes.** That rule\n * measures mechanical complexity, and by it this is a recipe — it is a vertical stack in a\n * fixed order. But the reason to own it is not that assembling it is hard; it is that\n * assembling it DIFFERENTLY is a defect rather than a preference, and a recipe written down\n * in prose does not stop that. The failures are real ones, all found in a shipped app: two\n * tab bars stacked until the reader could not tell which row changed what; an app-level\n * chrome bar whose rule landed a few pixels off the host's chat panel; an unbounded\n * agent-authored description pushing the content below the fold. Each is an ordering or\n * composition mistake that a component makes unavailable and a convention only discourages.\n *\n * So the amended rule: a layout becomes a component when it is complex to build OR when\n * getting its arrangement wrong is a bug. This is the second kind.\n *\n * **What it deliberately does not have is a chrome slot.** A Synapse app does not own its\n * window — the host spends the left edge on a rail and the right on a chat panel — so an\n * app-level bar is a third chrome layer, and its rule cannot agree with the chat panel's.\n * Everything here is page content, which is the only thing on screen the app unambiguously\n * owns.\n *\n * Compose it inside `AppFrame.Body`; it manages its own vertical rhythm and nothing else.\n */\n\nimport type { HTMLAttributes, ReactNode } from \"react\";\nimport type { Crumb } from \"../components/Breadcrumb.js\";\nimport { PageHeader } from \"../components/PageHeader.js\";\n\ninterface PageLayoutProps extends Omit<HTMLAttributes<HTMLElement>, \"title\"> {\n  /** The trail. Omit at the top level, which has nothing above it to name. */\n  crumbs?: Crumb[];\n  title: ReactNode;\n  /** Beside the title — typically a `Badge`. */\n  status?: ReactNode;\n  /** The far end of the title's row. */\n  actions?: ReactNode;\n  description?: ReactNode;\n  /** Lines the description is clamped to. `0` removes the clamp. */\n  descriptionLines?: number;\n  /**\n   * ONE tab bar, of the facets of whatever the title names. A `Tabs`.\n   *\n   * A slot rather than typed props because `Tabs` already has an API worth having, and\n   * wrapping it here would mean maintaining a second copy of it that drifts. What the layout\n   * owns is the bar's POSITION — under the header, above the content — which is the part\n   * apps get wrong.\n   */\n  tabs?: ReactNode;\n  /**\n   * Controls that narrow the content below: a search field, a status filter, a view toggle.\n   *\n   * Distinct from `tabs` on purpose. A tab changes which facet of one entity is shown; a\n   * toolbar reshapes a set within that facet. Rendering them as one row is how an app ends up\n   * with two identical-looking control strips whose difference nobody can see.\n   */\n  toolbar?: ReactNode;\n  children?: ReactNode;\n}\n\nexport function PageLayout({\n  crumbs,\n  title,\n  status,\n  actions,\n  description,\n  descriptionLines,\n  tabs,\n  toolbar,\n  children,\n  style,\n  ...rest\n}: PageLayoutProps) {\n  return (\n    // A `<section>`, not a `<div>`, and it is the header below that makes it load-bearing.\n    // `<header>` maps to the `banner` landmark UNLESS it descends from sectioning content, so\n    // a page inside a page — a `PageLayout` in a pane of one — produced TWO banners, both\n    // claiming to head the document. That is the same defect as the app-chrome bar this\n    // layout exists without, one layer down and invisible on screen: it shows up only in the\n    // landmark list a screen-reader user navigates by.\n    //\n    // Scoping it here rather than asking callers to wrap is the point. A consuming app hit\n    // this, diagnosed it, and wrapped its own instance — correct, and not a thing every app\n    // should have to rediscover. An embedded app is not the document anyway: the host owns\n    // the real banner, and what this renders is a section of the host's page.\n    <section\n      style={{ display: \"flex\", flexDirection: \"column\", gap: \"1.1rem\", minWidth: 0, ...style }}\n      {...rest}\n    >\n      <PageHeader\n        crumbs={crumbs}\n        title={title}\n        status={status}\n        actions={actions}\n        description={description}\n        descriptionLines={descriptionLines}\n      />\n      {tabs}\n      {/* The toolbar sits closer to the content it filters than to the tabs above it, so the\n          gap is tightened here rather than inheriting the stack's rhythm. A control that looks\n          equally attached to both is a control whose scope the reader has to guess. */}\n      {toolbar ? (\n        <div\n          style={{\n            display: \"flex\",\n            alignItems: \"center\",\n            gap: \"0.5rem\",\n            flexWrap: \"wrap\",\n            minWidth: 0,\n            marginBottom: \"-0.35rem\",\n          }}\n        >\n          {toolbar}\n        </div>\n      ) : null}\n      {children}\n    </section>\n  );\n}\n","/**\n * SidebarLayout — the responsive two-column layout for inside an app pane: a\n * nav/list rail plus main content. It reacts to the layout's OWN width (not the\n * device), and below `breakpoint` collapses one of two ways:\n *\n *  - `reflow` (default) — the rail moves to a horizontal strip on top and the\n *    content goes full-width. Best for short navs (a settings page's sections).\n *  - `drawer` — the rail becomes an off-canvas overlay opened by a `Trigger`.\n *    Best for long lists (a document browser) where reflowing would be absurd.\n *\n * Place nav items as flat children of `Sidebar`; it controls direction\n * (column when expanded, row when reflowed). For `drawer`, place a\n * `<SidebarLayout.Trigger />` *inside* the layout (e.g. a toolbar in `Main`) —\n * in v1 the open-state context lives on `SidebarLayout`, so the trigger must be\n * within it, NOT in a sibling `AppFrame.Header`. Or read state via `useSidebar()`.\n * (Header placement would need a hoisted provider — a deliberate later refinement.)\n */\n\nimport {\n  type ButtonHTMLAttributes,\n  type CSSProperties,\n  createContext,\n  type HTMLAttributes,\n  type ReactNode,\n  useContext,\n  useEffect,\n  useState,\n} from \"react\";\nimport { ensureStyle } from \"../internal/inject-style.js\";\nimport { type StyleWithVars, tokens } from \"../tokens.js\";\nimport { useBreakpoint } from \"./use-container-width.js\";\n\ntype CollapseMode = \"reflow\" | \"drawer\";\ntype Side = \"left\" | \"right\";\n\ninterface SidebarState {\n  collapsed: boolean;\n  mode: CollapseMode;\n  side: Side;\n  width: number | string;\n  open: boolean;\n  setOpen: (open: boolean) => void;\n}\n\nconst SidebarCtx = createContext<SidebarState | null>(null);\n\n/** Read the sidebar's responsive state — for custom triggers or nav re-orientation. */\nexport function useSidebar(): SidebarState {\n  const ctx = useContext(SidebarCtx);\n  if (!ctx) throw new Error(\"useSidebar must be used within <SidebarLayout>\");\n  return ctx;\n}\n\nconst STYLE_ID = \"nb-synapse-sidebarlayout\";\n// Distinct class names from the Drawer component (which owns `.nb-drawer`).\nconst RULES = `\n.nb-sidebar-drawer { transition: transform 220ms cubic-bezier(0.2, 0, 0, 1); }\n.nb-sidebar-scrim { animation: nb-sidebar-fade 180ms ease; }\n@keyframes nb-sidebar-fade { from { opacity: 0; } to { opacity: 1; } }\n@media (prefers-reduced-motion: reduce) {\n  .nb-sidebar-drawer { transition: none; }\n  .nb-sidebar-scrim { animation: none; }\n}\n`;\n\ninterface SidebarLayoutProps extends HTMLAttributes<HTMLDivElement> {\n  side?: Side;\n  /** Expanded rail / drawer width. Default 240. */\n  width?: number | string;\n  /** Collapse below this pane width (px). Default 640. */\n  breakpoint?: number;\n  collapseMode?: CollapseMode;\n  children?: ReactNode;\n}\n\nfunction SidebarLayoutRoot({\n  side = \"left\",\n  width = 240,\n  breakpoint = 640,\n  collapseMode = \"reflow\",\n  style,\n  children,\n  ...rest\n}: SidebarLayoutProps) {\n  const { ref, isNarrow } = useBreakpoint<HTMLDivElement>(breakpoint);\n  const [open, setOpen] = useState(false);\n\n  // Close the drawer on Escape.\n  useEffect(() => {\n    if (!open) return;\n    const onKey = (e: KeyboardEvent) => {\n      if (e.key === \"Escape\") setOpen(false);\n    };\n    window.addEventListener(\"keydown\", onKey);\n    return () => window.removeEventListener(\"keydown\", onKey);\n  }, [open]);\n\n  // Collapsing back to expanded should drop any open drawer state.\n  useEffect(() => {\n    if (!isNarrow && open) setOpen(false);\n  }, [isNarrow, open]);\n\n  const reflowed = isNarrow && collapseMode === \"reflow\";\n  const rootStyle: CSSProperties = {\n    position: \"relative\",\n    display: \"flex\",\n    flexDirection: reflowed ? \"column\" : side === \"right\" ? \"row-reverse\" : \"row\",\n    height: \"100%\",\n    minHeight: 0,\n    ...style,\n  };\n\n  return (\n    <SidebarCtx.Provider\n      value={{ collapsed: isNarrow, mode: collapseMode, side, width, open, setOpen }}\n    >\n      <div ref={ref} style={rootStyle} {...rest}>\n        {children}\n      </div>\n    </SidebarCtx.Provider>\n  );\n}\n\nfunction Sidebar({ style, children, ...rest }: HTMLAttributes<HTMLElement>) {\n  const { collapsed, mode, side, width, open, setOpen } = useSidebar();\n  ensureStyle(STYLE_ID, RULES);\n\n  // Expanded: a fixed-width rail beside the content.\n  if (!collapsed) {\n    const border = `${tokens.borderWidth} solid ${tokens.border}`;\n    return (\n      <aside\n        style={{\n          width,\n          flexShrink: 0,\n          overflowY: \"auto\",\n          display: \"flex\",\n          flexDirection: \"column\",\n          gap: \"0.125rem\",\n          padding: \"0.5rem 0.5rem\",\n          ...(side === \"right\" ? { borderLeft: border } : { borderRight: border }),\n          ...style,\n        }}\n        {...rest}\n      >\n        {children}\n      </aside>\n    );\n  }\n\n  // Reflowed: a horizontal strip on top, content below.\n  if (mode === \"reflow\") {\n    return (\n      <aside\n        style={{\n          display: \"flex\",\n          flexDirection: \"row\",\n          alignItems: \"center\",\n          gap: \"0.25rem\",\n          width: \"100%\",\n          overflowX: \"auto\",\n          padding: \"0.5rem 0.75rem\",\n          borderBottom: `${tokens.borderWidth} solid ${tokens.border}`,\n          ...style,\n        }}\n        {...rest}\n      >\n        {children}\n      </aside>\n    );\n  }\n\n  // Drawer: off-canvas overlay + scrim.\n  const closed = side === \"right\" ? \"translateX(100%)\" : \"translateX(-100%)\";\n  const drawerStyle: StyleWithVars = {\n    position: \"absolute\",\n    top: 0,\n    bottom: 0,\n    [side]: 0,\n    width,\n    maxWidth: \"85%\",\n    overflowY: \"auto\",\n    background: tokens.bgRaised,\n    boxShadow: tokens.shadowLg,\n    transform: open ? \"translateX(0)\" : closed,\n    zIndex: 11,\n    ...(side === \"right\"\n      ? { borderLeft: `${tokens.borderWidth} solid ${tokens.border}` }\n      : { borderRight: `${tokens.borderWidth} solid ${tokens.border}` }),\n    ...style,\n  };\n  return (\n    <>\n      {open ? (\n        <button\n          type=\"button\"\n          aria-label=\"Close sidebar\"\n          className=\"nb-sidebar-scrim\"\n          onClick={() => setOpen(false)}\n          style={{\n            position: \"absolute\",\n            inset: 0,\n            border: \"none\",\n            padding: 0,\n            cursor: \"pointer\",\n            background: \"rgba(0,0,0,0.32)\",\n            zIndex: 10,\n          }}\n        />\n      ) : null}\n      {/* `inert` when closed removes the off-canvas rail from the tab order and\n          the a11y tree (vs `aria-hidden`, which leaves focusables reachable). */}\n      <aside className=\"nb-sidebar-drawer\" inert={!open} style={drawerStyle} {...rest}>\n        {children}\n      </aside>\n    </>\n  );\n}\n\nfunction Main({ style, children, ...rest }: HTMLAttributes<HTMLDivElement>) {\n  return (\n    <div style={{ flex: 1, minWidth: 0, minHeight: 0, overflowY: \"auto\", ...style }} {...rest}>\n      {children}\n    </div>\n  );\n}\n\ninterface TriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n  /** Override the default hamburger glyph. */\n  children?: ReactNode;\n}\n\n/**\n * Hamburger that opens the drawer. Renders only when collapsed in `drawer`\n * mode, and only when it can see a `SidebarLayout` context — so it's safe to\n * place anywhere inside the layout subtree (it no-ops elsewhere). Note: in v1\n * the context lives on `SidebarLayout` itself, so the trigger must sit inside\n * it (e.g. a toolbar in `Main`), not in a sibling `AppFrame.Header`.\n */\nfunction Trigger({ children, style, onClick, ...rest }: TriggerProps) {\n  const ctx = useContext(SidebarCtx);\n  if (!ctx?.collapsed || ctx.mode !== \"drawer\") return null;\n  const { open, setOpen } = ctx;\n  return (\n    <button\n      type=\"button\"\n      aria-label=\"Toggle sidebar\"\n      aria-expanded={open}\n      onClick={(e) => {\n        setOpen(!open);\n        onClick?.(e);\n      }}\n      style={{\n        display: \"inline-flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        width: 32,\n        height: 32,\n        border: \"none\",\n        background: \"transparent\",\n        color: tokens.fg,\n        cursor: \"pointer\",\n        borderRadius: tokens.radiusSm,\n        ...style,\n      }}\n      {...rest}\n    >\n      {children ?? (\n        <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" aria-hidden=\"true\">\n          <path\n            d=\"M2 4.5h14M2 9h14M2 13.5h14\"\n            stroke=\"currentColor\"\n            strokeWidth=\"1.5\"\n            strokeLinecap=\"round\"\n          />\n        </svg>\n      )}\n    </button>\n  );\n}\n\n/** `SidebarLayout` with `.Sidebar`, `.Main`, and `.Trigger` slots. */\nexport const SidebarLayout = Object.assign(SidebarLayoutRoot, { Sidebar, Main, Trigger });\n"]}