@octaviaflow/core 3.1.0-beta.118 → 3.1.0-beta.120

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/chunk-FM34SY5X.js +3691 -0
  2. package/dist/chunk-FM34SY5X.js.map +1 -0
  3. package/dist/chunk-JHIV4QHZ.js +3707 -0
  4. package/dist/chunk-JHIV4QHZ.js.map +1 -0
  5. package/dist/chunk-OQAB7DBO.js +3715 -0
  6. package/dist/chunk-OQAB7DBO.js.map +1 -0
  7. package/dist/chunk-ZHTMPKJN.js +3704 -0
  8. package/dist/chunk-ZHTMPKJN.js.map +1 -0
  9. package/dist/components/AssistantConversation/AssistantConversation.d.ts +7 -1
  10. package/dist/components/AssistantConversation/AssistantConversation.d.ts.map +1 -1
  11. package/dist/components/AssistantConversation/assistant.fixtures.d.ts +2 -0
  12. package/dist/components/AssistantConversation/assistant.fixtures.d.ts.map +1 -1
  13. package/dist/components/AssistantConversation/citations.d.ts +3 -0
  14. package/dist/components/AssistantConversation/citations.d.ts.map +1 -0
  15. package/dist/components/AssistantConversation/index.d.ts +2 -1
  16. package/dist/components/AssistantConversation/index.d.ts.map +1 -1
  17. package/dist/components/AssistantDock/AssistantDock.d.ts +6 -2
  18. package/dist/components/AssistantDock/AssistantDock.d.ts.map +1 -1
  19. package/dist/components/AssistantHistory/AssistantHistory.d.ts +26 -0
  20. package/dist/components/AssistantHistory/AssistantHistory.d.ts.map +1 -0
  21. package/dist/components/AssistantHistory/index.d.ts +2 -0
  22. package/dist/components/AssistantHistory/index.d.ts.map +1 -0
  23. package/dist/components/ChatToolTrace/ChatToolTrace.d.ts +3 -0
  24. package/dist/components/ChatToolTrace/ChatToolTrace.d.ts.map +1 -1
  25. package/dist/index.cjs +3968 -3858
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.ts +3 -2
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +3547 -3463
  30. package/dist/index.js.map +1 -1
  31. package/dist/marketing.cjs +58 -34
  32. package/dist/marketing.cjs.map +1 -1
  33. package/dist/marketing.js +1 -1
  34. package/dist/styles.css +1 -1
  35. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Card/Card.tsx","../src/components/Avatar/Avatar.tsx","../src/components/BlogCard/BlogCard.tsx","../src/components/ChatBubble/ChatBubble.tsx","../src/components/ChatComposer/ChatComposer.tsx","../src/components/ChatLinkPreview/ChatLinkPreview.tsx","../src/components/TruncatedText/TruncatedText.tsx","../src/components/ChatDocPreview/ChatDocPreview.tsx","../src/components/Radio/RadioGroup.tsx","../src/components/Radio/Radio.tsx","../src/components/ChatInputRequest/ChatInputRequest.tsx","../src/components/ChatFeedback/ChatFeedback.tsx","../src/components/ChatScrollToBottom/ChatScrollToBottom.tsx","../src/components/ChatThread/ChatThread.tsx","../src/components/ChatPanel/ChatPanel.tsx","../src/components/AssistantAura/AssistantAura.tsx","../src/components/AssistantOrb/AssistantOrb.tsx","../src/components/ChatSources/ChatSources.tsx","../src/components/ChatSuggestions/ChatSuggestions.tsx","../src/components/ChatThinking/ChatThinking.tsx","../src/components/ChatToolTrace/ChatToolTrace.tsx","../src/components/ChatVideoPreview/ChatVideoPreview.tsx","../src/components/AssistantConversation/AssistantConversation.tsx","../src/components/CountUp/CountUp.tsx","../src/hooks/useTextareaCommands.ts","../src/hooks/useTextareaSelection.ts","../src/hooks/useTextareaTools.tsx","../src/components/Textarea/Textarea.tsx","../src/components/TestimonialCard/TestimonialCard.tsx","../src/components/AssistantConversation/assistantGlyphs.tsx"],"sourcesContent":["\"use client\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport {\n type ComponentPropsWithoutRef,\n type ElementType,\n forwardRef,\n type KeyboardEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Slot } from \"../../utils/Slot\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type CardVariant = \"default\" | \"elevated\" | \"outlined\" | \"subtle\" | \"selected\";\nexport type CardPadding = \"none\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\nexport type CardRadius = \"none\" | \"sm\" | \"md\" | \"lg\";\n\nexport interface CardProps\n extends Omit<\n ComponentPropsWithoutRef<\"div\">,\n \"onDrag\" | \"onDragStart\" | \"onDragEnd\" | \"onAnimationStart\"\n > {\n variant?: CardVariant;\n padding?: CardPadding;\n radius?: CardRadius;\n /** Apply hover affordance (lift + tint) without making the card clickable.\n * For purely-visual surfaces that respond to mouse-over. */\n hoverable?: boolean;\n /** Disable a clickable card. Adds `aria-disabled` and suppresses interaction. */\n disabled?: boolean;\n /** Loading skeleton — replaces the card chrome with a shimmer block of\n * the same height. */\n loading?: boolean;\n /** Render Card's styling onto a custom child element (Radix-style Slot).\n *\n * <Card asChild variant=\"elevated\">\n * <NextLink href=\"/blog/post-1\">{...}</NextLink>\n * </Card>\n *\n * When set, Card does NOT wrap the child in motion.div — the consumer's\n * element fully owns content. Use without asChild for the built-in\n * hover / tap motion + keyboard activation. */\n asChild?: boolean;\n children?: ReactNode;\n}\n\n/* ---------------------------------------------------------------------------\n * Card root\n * ------------------------------------------------------------------------- */\n\nexport const Card = forwardRef<HTMLDivElement, CardProps>(function Card(\n {\n variant = \"default\",\n padding = \"md\",\n radius = \"md\",\n hoverable = false,\n disabled = false,\n loading = false,\n asChild = false,\n onClick,\n onKeyDown,\n className,\n children,\n ...rest\n },\n ref,\n) {\n const reducedMotion = useReducedMotion();\n const isInteractive = Boolean(onClick) && !disabled && !loading;\n\n // Keyboard activation for clickable cards. Without this, Enter/Space on a\n // focused card-as-button does nothing — a broken a11y contract that the\n // previous shape silently shipped.\n const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(e);\n if (e.defaultPrevented) return;\n if (!isInteractive) return;\n if ((e.key === \"Enter\" || e.key === \" \") && !e.repeat) {\n e.preventDefault();\n onClick?.(e as unknown as Parameters<NonNullable<typeof onClick>>[0]);\n }\n };\n\n const rootClassName = cn(\n \"ods-card\",\n `ods-card--${variant}`,\n `ods-card--pad-${padding}`,\n `ods-card--radius-${radius}`,\n (hoverable || isInteractive) && !loading && !disabled && \"ods-card--hoverable\",\n isInteractive && \"ods-card--clickable\",\n disabled && \"ods-card--disabled\",\n loading && \"ods-card--loading\",\n className,\n );\n\n // asChild — project Card's chrome onto the consumer's element.\n if (asChild) {\n return (\n <Slot\n {...(rest as ComponentPropsWithoutRef<ElementType>)}\n ref={ref as Ref<HTMLElement>}\n className={rootClassName}\n onClick={isInteractive ? onClick : undefined}\n onKeyDown={isInteractive ? handleKeyDown : onKeyDown}\n aria-disabled={disabled || undefined}\n >\n {children as ReactElement}\n </Slot>\n );\n }\n\n // Loading skeleton — same height-ish slot so layout doesn't jump.\n if (loading) {\n return (\n <div {...rest} ref={ref} className={rootClassName} aria-busy=\"true\" aria-label=\"Loading\">\n <div className=\"ods-card__skeleton\" data-ods-animate=\"shimmer\" />\n </div>\n );\n }\n\n return (\n <motion.div\n {...(rest as any)}\n ref={ref}\n onClick={isInteractive ? onClick : undefined}\n onKeyDown={isInteractive ? handleKeyDown : onKeyDown}\n className={rootClassName}\n whileHover={\n (hoverable || isInteractive) && !reducedMotion\n ? { y: -2, transition: { duration: 0.15 } }\n : undefined\n }\n whileTap={isInteractive && !reducedMotion ? { scale: 0.99 } : undefined}\n role={isInteractive ? \"button\" : rest.role}\n tabIndex={isInteractive ? (rest.tabIndex ?? 0) : rest.tabIndex}\n aria-disabled={disabled || undefined}\n >\n {children}\n </motion.div>\n );\n}) as React.ForwardRefExoticComponent<CardProps & React.RefAttributes<HTMLDivElement>> & {\n Header: typeof CardHeader;\n Body: typeof CardBody;\n Footer: typeof CardFooter;\n Title: typeof CardTitle;\n Description: typeof CardDescription;\n};\n\nCard.displayName = \"Card\";\n\n/* ---------------------------------------------------------------------------\n * Subcomponents — `Card.Header`, `Card.Body`, `Card.Footer`, `Card.Title`,\n * `Card.Description`. Optional building blocks for the \"title + content +\n * actions\" pattern. Compose freely — none of them are required.\n * ------------------------------------------------------------------------- */\n\nexport interface CardSectionProps extends ComponentPropsWithoutRef<\"div\"> {\n children?: ReactNode;\n}\n\nexport const CardHeader = forwardRef<HTMLDivElement, CardSectionProps>(function CardHeader(\n { className, children, ...rest },\n ref,\n) {\n return (\n <div {...rest} ref={ref} className={cn(\"ods-card__header\", className)}>\n {children}\n </div>\n );\n});\nCardHeader.displayName = \"Card.Header\";\n\nexport const CardBody = forwardRef<HTMLDivElement, CardSectionProps>(function CardBody(\n { className, children, ...rest },\n ref,\n) {\n return (\n <div {...rest} ref={ref} className={cn(\"ods-card__body\", className)}>\n {children}\n </div>\n );\n});\nCardBody.displayName = \"Card.Body\";\n\nexport const CardFooter = forwardRef<HTMLDivElement, CardSectionProps>(function CardFooter(\n { className, children, ...rest },\n ref,\n) {\n return (\n <div {...rest} ref={ref} className={cn(\"ods-card__footer\", className)}>\n {children}\n </div>\n );\n});\nCardFooter.displayName = \"Card.Footer\";\n\nexport interface CardTitleProps extends ComponentPropsWithoutRef<\"h3\"> {\n /** Override the heading level. Defaults to `<h3>`. */\n as?: \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\";\n children?: ReactNode;\n}\n\nexport const CardTitle = forwardRef<HTMLHeadingElement, CardTitleProps>(function CardTitle(\n { as: Comp = \"h3\", className, children, ...rest },\n ref,\n) {\n return (\n <Comp\n {...(rest as ComponentPropsWithoutRef<typeof Comp>)}\n ref={ref}\n className={cn(\"ods-card__title\", className)}\n >\n {children}\n </Comp>\n );\n});\nCardTitle.displayName = \"Card.Title\";\n\nexport interface CardDescriptionProps extends ComponentPropsWithoutRef<\"p\"> {\n children?: ReactNode;\n}\n\nexport const CardDescription = forwardRef<HTMLParagraphElement, CardDescriptionProps>(\n function CardDescription({ className, children, ...rest }, ref) {\n return (\n <p {...rest} ref={ref} className={cn(\"ods-card__description\", className)}>\n {children}\n </p>\n );\n },\n);\nCardDescription.displayName = \"Card.Description\";\n\n// Dot-notation API: `Card.Header`, `Card.Body`, etc.\nCard.Header = CardHeader;\nCard.Body = CardBody;\nCard.Footer = CardFooter;\nCard.Title = CardTitle;\nCard.Description = CardDescription;\n","\"use client\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type KeyboardEvent,\n type ReactNode,\n useCallback,\n useMemo,\n useState,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type AvatarSize = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\nexport type AvatarShape = \"circle\" | \"square\";\n/** Presence indicator. `online` pulses gently; reduced-motion is respected. */\nexport type AvatarStatus = \"online\" | \"offline\" | \"busy\" | \"away\";\n\nexport interface AvatarProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"color\" | \"children\" | \"onClick\" | \"onKeyDown\"> {\n /** Image URL. If loading fails, falls back to `initials` (then `icon`, then `?`). */\n src?: string;\n /** Accessible name for the avatar. Used as the `<img>` alt AND as the\n * wrapping element's accessible name. If you only pass `initials`,\n * this is recommended so AT announces \"Jane Doe avatar\" not \"J D\". */\n alt?: string;\n /** Initials to render when there is no image. Auto-uppercased and\n * truncated to 2 characters so passing a full name stays sane. */\n initials?: string;\n /** Optional icon slot — rendered when neither `src` nor `initials` is\n * available (or used directly when you want a system/bot avatar). */\n icon?: ReactNode;\n /** Override the default `?` fallback content. */\n fallback?: ReactNode;\n /** Stable seed for the persistent palette — canonically the user's\n * NAME. Falls back to `alt` (usually the person's name) before\n * `initials`, so every surface that renders the same person derives\n * the same color even when `seed` isn't passed explicitly. */\n seed?: string;\n /** Explicit palette index (0–11) — wins over seed hashing. Pair with a\n * host-persisted value (e.g. `user.profile.avatarPalette` computed once\n * via `avatarPaletteIndex(name)`) to guarantee the identical color on\n * every surface, including non-DS ones like transactional emails. */\n palette?: number;\n /** Pixel/font size variant. */\n size?: AvatarSize;\n /** Shape — `circle` (people, default) or `square` (teams, bots, brands). */\n shape?: AvatarShape;\n /** Presence indicator dot. */\n status?: AvatarStatus;\n /** Human-readable status label folded into the accessible name. Defaults\n * to the capitalized `status` value. */\n statusLabel?: string;\n /** When set, the avatar becomes a button (Enter/Space activated). */\n onClick?: () => void;\n /** Native image attributes — set `loading=\"eager\"` for above-the-fold avatars\n * if you've measured CLS regressions. Defaults to `lazy`. */\n imgLoading?: \"eager\" | \"lazy\";\n /** Native referrerPolicy for cross-origin avatar hosts (Gravatar, etc.). */\n referrerPolicy?: ComponentPropsWithoutRef<\"img\">[\"referrerPolicy\"];\n}\n\n/* ---------------------------------------------------------------------------\n * Persistent palette\n *\n * 12 gradients exposed as CSS custom properties so consumers can theme them\n * (or replace the whole palette) without touching the component. We do NOT\n * hit localStorage — a deterministic djb2 hash gives stable assignment\n * across renders, machines, and SSR/CSR boundaries.\n * ------------------------------------------------------------------------- */\n\nconst PALETTE_SIZE = 12;\n\nfunction djb2(str: string): number {\n let h = 5381;\n for (let i = 0; i < str.length; i++) h = (h << 5) + h + str.charCodeAt(i);\n return h >>> 0;\n}\n\nfunction paletteIndexFor(seed: string): number {\n return djb2(seed) % PALETTE_SIZE;\n}\n\n/** Number of persistent avatar palettes. */\nexport const AVATAR_PALETTE_SIZE = PALETTE_SIZE;\n\n/**\n * Deterministic palette index for a seed (canonically the user's name).\n * Exposed so hosts can compute the value ONCE, persist it on the user\n * record, and pass it back via the `palette` prop everywhere.\n */\nexport function avatarPaletteIndex(seed: string): number {\n return paletteIndexFor(seed);\n}\n\nfunction normalizeInitials(raw: string): string {\n // Take the first character of up to two whitespace-separated tokens —\n // \"Jane Doe\" → \"JD\", \"Postgres\" → \"P\", \"schema-drift\" → \"S\". Falls\n // back to the first two characters of a contiguous run.\n const trimmed = raw.trim();\n if (!trimmed) return \"\";\n const tokens = trimmed.split(/\\s+/).filter(Boolean);\n if (tokens.length >= 2) {\n return (tokens[0]!.charAt(0) + tokens[1]!.charAt(0)).toUpperCase();\n }\n return trimmed.slice(0, 2).toUpperCase();\n}\n\nconst STATUS_DEFAULT_LABEL: Record<AvatarStatus, string> = {\n online: \"Online\",\n offline: \"Offline\",\n busy: \"Busy\",\n away: \"Away\",\n};\n\n/* ---------------------------------------------------------------------------\n * Avatar\n * ------------------------------------------------------------------------- */\n\nexport const Avatar = forwardRef<HTMLDivElement, AvatarProps>(function Avatar(\n {\n src,\n alt,\n initials,\n icon,\n fallback,\n seed,\n palette,\n size = \"md\",\n shape = \"circle\",\n status,\n statusLabel,\n onClick,\n imgLoading = \"lazy\",\n referrerPolicy,\n className,\n ...rest\n },\n ref,\n) {\n // Image failure is tracked locally so the next render swaps to the\n // initials fallback transparently. Reset key change resets state.\n const [imgFailed, setImgFailed] = useState(false);\n const handleImgError = useCallback(() => setImgFailed(true), []);\n\n const showImage = Boolean(src) && !imgFailed;\n\n const normalizedInitials = useMemo(\n () => (initials ? normalizeInitials(initials) : \"\"),\n [initials],\n );\n\n // Resolve palette once. Stable across renders. Precedence: explicit\n // saved `palette` > `seed` > `alt` (usually the person's NAME — shared\n // by every surface) > `initials` (2 chars, least unique — last resort).\n const paletteIdx = useMemo(() => {\n if (palette !== undefined) {\n return ((Math.trunc(palette) % PALETTE_SIZE) + PALETTE_SIZE) % PALETTE_SIZE;\n }\n const resolved = seed ?? alt ?? initials ?? \"?\";\n return paletteIndexFor(resolved);\n }, [palette, seed, alt, initials]);\n\n // Accessible name — fold status into the label so AT announces\n // \"Jane Doe, online\" as a single coherent label, not two separate nodes.\n const baseName = alt || normalizedInitials || \"Avatar\";\n const announcedStatus = status ? (statusLabel ?? STATUS_DEFAULT_LABEL[status]) : \"\";\n const accessibleName = announcedStatus ? `${baseName}, ${announcedStatus}` : baseName;\n\n const isClickable = Boolean(onClick);\n\n const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (!isClickable) return;\n if ((e.key === \"Enter\" || e.key === \" \") && !e.repeat) {\n e.preventDefault();\n onClick?.();\n }\n };\n\n const rootClassName = cn(\n \"ods-avatar\",\n `ods-avatar--${size}`,\n `ods-avatar--${shape}`,\n isClickable && \"ods-avatar--clickable\",\n className,\n );\n\n return (\n <div\n {...rest}\n ref={ref}\n className={rootClassName}\n // Only the outer wrapper carries `role=\"img\"` + the merged label. The\n // inner <img> drops out of the AT tree (alt=\"\") so AT doesn't double-\n // announce \"Jane Doe avatar / Jane Doe\".\n role={isClickable ? \"button\" : \"img\"}\n aria-label={accessibleName}\n tabIndex={isClickable ? 0 : undefined}\n onClick={onClick}\n onKeyDown={isClickable ? handleKeyDown : undefined}\n data-status={status}\n >\n <span className=\"ods-avatar__inner\" data-palette={paletteIdx}>\n {showImage ? (\n <img\n src={src}\n alt=\"\"\n className=\"ods-avatar__image\"\n loading={imgLoading}\n decoding=\"async\"\n referrerPolicy={referrerPolicy}\n onError={handleImgError}\n draggable={false}\n />\n ) : icon ? (\n <span className=\"ods-avatar__icon\" aria-hidden=\"true\">\n {icon}\n </span>\n ) : normalizedInitials ? (\n <span className=\"ods-avatar__initials\" aria-hidden=\"true\">\n {normalizedInitials}\n </span>\n ) : (\n <span className=\"ods-avatar__initials\" aria-hidden=\"true\">\n {fallback ?? \"?\"}\n </span>\n )}\n </span>\n {status && (\n // Decorative — the textual status is folded into the wrapper's\n // aria-label above. `aria-hidden` keeps AT from double-announcing.\n <span\n className={cn(\"ods-avatar__status\", `ods-avatar__status--${status}`)}\n aria-hidden=\"true\"\n />\n )}\n </div>\n );\n});\n\nAvatar.displayName = \"Avatar\";\n\n/* ---------------------------------------------------------------------------\n * AvatarStack\n * ------------------------------------------------------------------------- */\n\nexport interface AvatarStackProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> {\n /** Avatars to display (in left-to-right stacking order). */\n children: ReactNode;\n /** Max avatars to show before collapsing the surplus into `+N`. */\n max?: number;\n /** Size applied to the overflow chip. Defaults to `md`. */\n size?: AvatarSize;\n /** Replace the default `+N` overflow chip. Receives the hidden count. */\n renderOverflow?: (count: number) => ReactNode;\n /** Stacking direction. `ltr` (default) overlaps each successive avatar to\n * the right of the previous one; `rtl` mirrors. */\n direction?: \"ltr\" | \"rtl\";\n}\n\nexport const AvatarStack = forwardRef<HTMLDivElement, AvatarStackProps>(function AvatarStack(\n { children, max, size = \"md\", renderOverflow, direction = \"ltr\", className, ...rest },\n ref,\n) {\n const arr = Array.isArray(children) ? children : [children];\n const visible = max && arr.length > max ? arr.slice(0, max) : arr;\n const overflow = max && arr.length > max ? arr.length - max : 0;\n\n return (\n <div\n {...rest}\n ref={ref}\n className={cn(\"ods-avatar-stack\", `ods-avatar-stack--${direction}`, className)}\n >\n {visible}\n {overflow > 0 &&\n (renderOverflow ? (\n renderOverflow(overflow)\n ) : (\n <div\n className={cn(\n \"ods-avatar\",\n `ods-avatar--${size}`,\n \"ods-avatar--circle\",\n \"ods-avatar-stack__overflow\",\n )}\n role=\"img\"\n aria-label={`${overflow} more`}\n >\n <span className=\"ods-avatar__inner\">\n <span className=\"ods-avatar__initials\" aria-hidden=\"true\">\n +{overflow}\n </span>\n </span>\n </div>\n ))}\n </div>\n );\n});\n\nAvatarStack.displayName = \"AvatarStack\";\n","\"use client\";\nimport { type ComponentPropsWithoutRef, forwardRef, type ReactNode, useId } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Avatar, type AvatarProps } from \"../Avatar\";\nimport { Card, type CardRadius } from \"../Card\";\n\n/* ---------------------------------------------------------------------------\n * BlogCard — composes on the polished `Card` primitive so it inherits\n * `forwardRef`, native prop spread, keyboard activation, hover/tap\n * microinteractions, and `prefers-reduced-motion` support for free.\n *\n * Adds blog-specific slots on top: cover image with configurable aspect\n * ratio, category chips, author row, reading-time + date meta. Renders\n * as a real `<a>` when `href` is given (via Card.asChild) so the link\n * gets browser semantics (open-in-new-tab, middle-click, etc.).\n * ------------------------------------------------------------------------- */\n\nexport type BlogCardOrientation = \"vertical\" | \"horizontal\";\nexport type BlogCardCoverAspect = \"16/9\" | \"4/3\" | \"1/1\" | \"3/4\" | \"21/9\";\n\nexport interface BlogCardAuthor {\n name: ReactNode;\n /** Optional avatar — passed through to the polished `Avatar` primitive. */\n avatar?: Pick<AvatarProps, \"src\" | \"initials\" | \"alt\" | \"seed\" | \"palette\">;\n /** Optional role / handle / etc. */\n byline?: ReactNode;\n}\n\nexport interface BlogCardProps\n extends Omit<\n ComponentPropsWithoutRef<\"div\">,\n \"title\" | \"onChange\" | \"onDrag\" | \"onDragStart\" | \"onDragEnd\" | \"onAnimationStart\"\n > {\n /** Cover artwork — usually an `<img>` element, but accepts any node. */\n cover?: ReactNode;\n /**\n * Cover aspect ratio. Lets a grid of cards stay visually consistent\n * regardless of source image dimensions. Default `\"16/9\"`.\n */\n coverAspect?: BlogCardCoverAspect;\n /** Single category chip (legacy — prefer `tags`). */\n category?: ReactNode;\n /** Multiple category chips. Rendered before the title. */\n tags?: ReactNode[];\n /** Date / publish info — inline meta. */\n meta?: ReactNode;\n /** Structured reading-time slot. Renders alongside `meta`. */\n readingTime?: ReactNode;\n /** Required title — drives `aria-labelledby` on the card. */\n title: ReactNode;\n /** Heading level for the title. Default `\"h3\"`. */\n titleAs?: \"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\";\n description?: ReactNode;\n /** Structured author block — avatar + name + optional byline. */\n author?: BlogCardAuthor;\n /** Right-aligned footer content (call-to-action / \"Read more\" link). */\n footer?: ReactNode;\n /** Card corner radius. */\n radius?: CardRadius;\n /** Cover on top (default) or cover on left. */\n orientation?: BlogCardOrientation;\n /** When set, the card renders as an `<a>` element. */\n href?: string;\n /** Click handler. Pairing with `href` is fine; both fire. */\n onClick?: () => void;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const BlogCard = forwardRef<HTMLDivElement, BlogCardProps>(function BlogCard(\n {\n cover,\n coverAspect = \"16/9\",\n category,\n tags,\n meta,\n readingTime,\n title,\n titleAs = \"h3\",\n description,\n author,\n footer,\n radius = \"md\",\n orientation = \"vertical\",\n href,\n onClick,\n id: providedId,\n className,\n ...rest\n },\n ref,\n) {\n const reactId = useId();\n const baseId = providedId ?? `ods-blog-card-${reactId}`;\n const titleId = `${baseId}-title`;\n const descId = description ? `${baseId}-desc` : undefined;\n\n // Resolve the tag list — a single `category` is treated as a one-tag\n // list for back-compat with the v1 API.\n const tagList: ReactNode[] = tags ?? (category ? [category] : []);\n\n const body = (\n <>\n {cover && (\n <div\n className={cn(\n \"ods-blog-card__cover\",\n `ods-blog-card__cover--aspect-${coverAspect.replace(\"/\", \"-\")}`,\n )}\n aria-hidden=\"true\"\n >\n {cover}\n </div>\n )}\n\n <div className=\"ods-blog-card__body\">\n {(tagList.length > 0 || meta || readingTime) && (\n <div className=\"ods-blog-card__meta\">\n {tagList.length > 0 && (\n <span className=\"ods-blog-card__tags\">\n {tagList.map((t, i) => (\n <span key={i} className=\"ods-blog-card__tag\">\n {t}\n </span>\n ))}\n </span>\n )}\n {meta && <span className=\"ods-blog-card__date\">{meta}</span>}\n {readingTime && <span className=\"ods-blog-card__reading\">{readingTime}</span>}\n </div>\n )}\n\n <Card.Title as={titleAs} id={titleId} className=\"ods-blog-card__title\">\n {title}\n </Card.Title>\n\n {description && (\n <Card.Description id={descId} className=\"ods-blog-card__desc\">\n {description}\n </Card.Description>\n )}\n\n {(author || footer) && (\n <div className=\"ods-blog-card__footer\">\n {author && (\n <div className=\"ods-blog-card__author\">\n {author.avatar && (\n <Avatar\n size=\"sm\"\n src={author.avatar.src}\n initials={author.avatar.initials}\n seed={author.avatar.seed}\n palette={author.avatar.palette}\n alt={\n author.avatar.alt ??\n (typeof author.name === \"string\" ? author.name : undefined)\n }\n />\n )}\n <div className=\"ods-blog-card__author-text\">\n <span className=\"ods-blog-card__author-name\">{author.name}</span>\n {author.byline && (\n <span className=\"ods-blog-card__author-byline\">{author.byline}</span>\n )}\n </div>\n </div>\n )}\n {footer && <div className=\"ods-blog-card__action\">{footer}</div>}\n </div>\n )}\n </div>\n </>\n );\n\n // `href` → render as a real <a> via Card.asChild for browser-native\n // link semantics (open-in-new-tab, middle-click, copy-link, etc.).\n if (href) {\n return (\n <Card\n asChild\n radius={radius}\n padding=\"none\"\n className={cn(\n \"ods-blog-card\",\n `ods-blog-card--${orientation}`,\n \"ods-blog-card--interactive\",\n className,\n )}\n aria-labelledby={titleId}\n aria-describedby={descId}\n >\n <a\n // `rest` is typed against HTMLDivElement handlers (BlogCardProps\n // extends div). The anchor accepts the same attributes\n // structurally at runtime, but TS sees\n // KeyboardEventHandler<HTMLDivElement> ≠ <HTMLAnchorElement>.\n // Route through `unknown` — TS's recommended escape hatch\n // when we know the runtime is safe.\n {...(rest as unknown as ComponentPropsWithoutRef<\"a\">)}\n ref={ref as unknown as React.Ref<HTMLAnchorElement>}\n href={href}\n id={baseId}\n onClick={onClick}\n >\n {body}\n </a>\n </Card>\n );\n }\n\n return (\n <Card\n {...rest}\n ref={ref}\n id={baseId}\n radius={radius}\n padding=\"none\"\n onClick={onClick}\n className={cn(\n \"ods-blog-card\",\n `ods-blog-card--${orientation}`,\n onClick && \"ods-blog-card--interactive\",\n className,\n )}\n aria-labelledby={titleId}\n aria-describedby={descId}\n >\n {body}\n </Card>\n );\n});\n\nBlogCard.displayName = \"BlogCard\";\n","\"use client\";\nimport {\n type ComponentPropsWithoutRef,\n type ElementType,\n forwardRef,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Slot } from \"../../utils/Slot\";\nimport { Avatar } from \"../Avatar/Avatar\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type ChatBubbleVariant = \"user\" | \"bot\" | \"system\";\nexport type ChatBubbleSize = \"sm\" | \"md\" | \"lg\";\nexport type ChatBubbleStatus = \"sent\" | \"delivered\" | \"read\" | \"failed\";\n\nexport interface ChatBubbleProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"color\" | \"title\"> {\n variant?: ChatBubbleVariant;\n size?: ChatBubbleSize;\n\n /** Display name shown in the meta row. */\n author?: ReactNode;\n /** Wall-clock timestamp (or ReactNode for relative formatters). */\n timestamp?: ReactNode;\n\n /** Avatar slot. Falls back to a string-initial Avatar when omitted. */\n avatar?: ReactNode;\n /** Override the auto-derived initial (first char of `author`). */\n initial?: string;\n /** Hide the avatar entirely — useful for \"consecutive messages from the\n * same author\" patterns. The avatar's WIDTH is still reserved so messages\n * stay aligned. */\n hideAvatar?: boolean;\n\n /** Render this bubble as a CONTINUATION of the previous same-author message:\n * reserves the avatar's width (no avatar) and squares the corner that meets\n * the message above so a stack reads as one grouped turn. Pair with a small\n * gap between bubbles. */\n continuation?: boolean;\n\n /** Where the author / timestamp / status meta sits relative to the bubble:\n * `\"top\"` (header style — best for the FIRST message of a group, so the meta\n * never gets sandwiched between two bubbles) or `\"bottom\"` (default). */\n metaPlacement?: \"top\" | \"bottom\";\n\n /** Show a typing indicator instead of children (three pulsing dots). */\n isTyping?: boolean;\n\n /** Delivery state badge in the meta row. `failed` adds an error tint to\n * the bubble. */\n status?: ChatBubbleStatus;\n\n /** Optional action slot rendered under the bubble (e.g. \"Retry\", reaction\n * buttons, copy-to-clipboard). */\n actions?: ReactNode;\n /** Optional attachments slot rendered below the body (file chips, image\n * previews, code blocks). */\n attachments?: ReactNode;\n\n /** Render ChatBubble's chrome onto a custom child element via Slot.\n * Internal slots (avatar, body, meta, actions) are NOT rendered when\n * `asChild` is true — useful for wrapping a router-link as a clickable\n * message bubble. */\n asChild?: boolean;\n\n children?: ReactNode;\n}\n\n/* ---------------------------------------------------------------------------\n * Helpers\n * ------------------------------------------------------------------------- */\n\nconst STATUS_LABEL: Record<ChatBubbleStatus, string> = {\n sent: \"Sent\",\n delivered: \"Delivered\",\n read: \"Read\",\n failed: \"Failed to send\",\n};\n\nfunction StatusGlyph({ status }: { status: ChatBubbleStatus }) {\n // Compact single-glyph delivery indicators. Self-contained SVGs so we\n // don't pull @octaviaflow/icons just for these four tiny shapes.\n switch (status) {\n case \"sent\":\n return (\n <svg viewBox=\"0 0 10 10\" width=\"10\" height=\"10\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M2 5l2 2 4-4\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n case \"delivered\":\n return (\n <svg viewBox=\"0 0 12 10\" width=\"12\" height=\"10\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M1 5l2 2 3.5-3.5 M5 5l2 2 4-4\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n case \"read\":\n return (\n <svg viewBox=\"0 0 12 10\" width=\"12\" height=\"10\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M1 5l2 2 3.5-3.5 M5 5l2 2 4-4\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n case \"failed\":\n return (\n <svg viewBox=\"0 0 10 10\" width=\"10\" height=\"10\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"5\" cy=\"5\" r=\"4\" stroke=\"currentColor\" strokeWidth=\"1.4\" />\n <path d=\"M5 3v3M5 6.8v.2\" stroke=\"currentColor\" strokeWidth=\"1.4\" strokeLinecap=\"round\" />\n </svg>\n );\n }\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const ChatBubble = forwardRef<HTMLDivElement, ChatBubbleProps>(function ChatBubble(\n {\n variant = \"bot\",\n size = \"md\",\n author,\n timestamp,\n avatar,\n initial,\n hideAvatar = false,\n continuation = false,\n metaPlacement = \"bottom\",\n isTyping = false,\n status,\n actions,\n attachments,\n asChild = false,\n className,\n children,\n ...rest\n },\n ref,\n) {\n const isUser = variant === \"user\";\n // A continuation reserves the avatar's width but shows no avatar.\n const reserveAvatar = hideAvatar || continuation;\n\n const rootClassName = cn(\n \"ods-chat\",\n `ods-chat--${variant}`,\n `ods-chat--${size}`,\n isTyping && \"ods-chat--typing\",\n continuation && \"ods-chat--continuation\",\n status === \"failed\" && \"ods-chat--failed\",\n className,\n );\n\n // asChild — project the chrome onto the consumer's element.\n if (asChild) {\n return (\n <Slot\n {...(rest as ComponentPropsWithoutRef<ElementType>)}\n ref={ref as Ref<HTMLElement>}\n className={rootClassName}\n >\n {children as ReactElement}\n </Slot>\n );\n }\n\n // Resolve the avatar: explicit ReactNode wins; otherwise build a string-\n // initial Avatar so consumers don't have to import it manually. It's\n // always built so the slot can RESERVE its width even when `hideAvatar`\n // is set — that's what keeps consecutive same-author messages aligned\n // (the bubble stays indented instead of jumping to the gutter).\n let resolvedAvatar: ReactNode;\n if (avatar !== undefined) {\n resolvedAvatar = avatar;\n } else {\n const resolvedInitial =\n initial ??\n (typeof author === \"string\"\n ? author\n : isUser\n ? \"You\"\n : variant === \"system\"\n ? \"System\"\n : \"AI\");\n // The Avatar's own seed → palette assignment keeps colors stable\n // across renders for a given author.\n resolvedAvatar = (\n <Avatar\n initials={resolvedInitial}\n alt={typeof author === \"string\" ? author : variant}\n seed={typeof author === \"string\" ? author : variant}\n size={size === \"sm\" ? \"sm\" : size === \"lg\" ? \"lg\" : \"md\"}\n />\n );\n }\n\n const metaEl =\n author || timestamp || status ? (\n <div className=\"ods-chat__meta\">\n {author && <span className=\"ods-chat__author\">{author}</span>}\n {timestamp && <span className=\"ods-chat__time\">{timestamp}</span>}\n {status && (\n <span\n className={cn(\"ods-chat__status\", `ods-chat__status--${status}`)}\n // role=\"img\" so `aria-label` is permitted on the span (axe\n // flags aria-label on a role-less generic element). The glyph\n // is decorative; the label carries the meaning (\"Read\" / …).\n role=\"img\"\n aria-label={STATUS_LABEL[status]}\n >\n <StatusGlyph status={status} />\n </span>\n )}\n </div>\n ) : null;\n\n return (\n <div {...rest} ref={ref} className={rootClassName}>\n <div\n className={cn(\"ods-chat__avatar-slot\", reserveAvatar && \"ods-chat__avatar-slot--hidden\")}\n // Hidden-but-present: occupies the avatar's width for alignment,\n // but is removed from the accessibility tree.\n aria-hidden={reserveAvatar || undefined}\n >\n {resolvedAvatar}\n </div>\n <div className=\"ods-chat__column\">\n {/* `metaPlacement=\"top\"` renders the author/time as a header above\n the bubble — so in a grouped turn the meta never gets sandwiched\n between two bubbles. */}\n {metaPlacement === \"top\" && metaEl}\n <div\n className=\"ods-chat__bubble\"\n // `role=status` for in-progress typing so AT users hear when\n // a response starts streaming.\n role={isTyping ? \"status\" : undefined}\n aria-live={isTyping ? \"polite\" : undefined}\n >\n {isTyping ? (\n // role=\"img\" gives the dots cluster an accessible name without\n // tripping axe's \"aria-label on a non-roleful span\" rule. The\n // outer bubble already carries role=\"status\" + aria-live, so\n // AT users hear \"Typing\" the moment the indicator appears.\n <span className=\"ods-chat__typing\" role=\"img\" aria-label=\"Typing\">\n <span className=\"ods-chat__typing-dot\" />\n <span className=\"ods-chat__typing-dot\" />\n <span className=\"ods-chat__typing-dot\" />\n </span>\n ) : (\n <div className=\"ods-chat__body\">{children}</div>\n )}\n {!isTyping && attachments && <div className=\"ods-chat__attachments\">{attachments}</div>}\n </div>\n {metaPlacement === \"bottom\" && metaEl}\n {actions && <div className=\"ods-chat__actions\">{actions}</div>}\n </div>\n </div>\n );\n});\n\nChatBubble.displayName = \"ChatBubble\";\n","\"use client\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type KeyboardEvent,\n type ReactNode,\n useEffect,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type ChatComposerSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface ChatComposerProps\n // Extends the underlying <textarea> props (everything in `rest` is forwarded\n // to the field). `value` / `defaultValue` / `onChange` are re-typed below as\n // string-first callbacks; `className` lands on the composer container.\n extends Omit<\n ComponentPropsWithoutRef<\"textarea\">,\n \"value\" | \"defaultValue\" | \"onChange\" | \"children\" | \"size\"\n > {\n /** Controlled value. Omit for an uncontrolled composer (it clears itself\n * after each send). */\n value?: string;\n /** Initial value when uncontrolled. */\n defaultValue?: string;\n /** Fires on every keystroke with the new value. */\n onChange?: (value: string) => void;\n /** Fires when the user submits — Enter (without Shift) or the send button.\n * Receives the current text. Never fires while empty (unless\n * `allowEmpty`) or while `sending`/`disabled`. */\n onSend?: (value: string) => void;\n\n placeholder?: string;\n disabled?: boolean;\n /** Spinner on the send button + sending is blocked. The field stays\n * editable so the user can keep typing the next message. */\n sending?: boolean;\n /** Allow sending an empty message. Default `false`. */\n allowEmpty?: boolean;\n\n size?: ChatComposerSize;\n /** Visible rows the field starts at. Default `1`. */\n minRows?: number;\n /** Rows before the field stops growing and scrolls. Default `6`. */\n maxRows?: number;\n /**\n * Which edge stays anchored as the field auto-grows.\n * - `\"up\"` — bottom edge fixed, the composer expands upward (the chat\n * default: docked above the send line, it grows into the thread).\n * - `\"down\"` — top edge fixed, expands downward (classic textarea).\n * - `\"both\"` — expands from the centre.\n * Visible when the composer has spare vertical space (a flex child / fixed\n * height); a content-sized composer simply hugs its content. Default `\"up\"`.\n */\n grow?: \"up\" | \"down\" | \"both\";\n\n /** Leading slot, left of the field (e.g. an attach button). */\n leading?: ReactNode;\n /** Controls between the field and the send button (e.g. a model picker). */\n trailing?: ReactNode;\n\n /**\n * While `sending`, the send button becomes a Stop button that calls this\n * (a reply being written can be stopped). Without it, `sending` shows a\n * spinner, as before.\n */\n onStop?: () => void;\n /** Accessible label for the Stop button. Default `\"Stop\"`. */\n stopLabel?: string;\n\n /** Override the send button's glyph. */\n sendIcon?: ReactNode;\n /** Accessible label for the send button. Default `\"Send message\"`. */\n sendLabel?: string;\n /** Accessible name for the text field. Default `\"Message\"`. */\n fieldLabel?: string;\n /** Helper line under the composer (e.g. an Enter-to-send hint). */\n hint?: ReactNode;\n}\n\n/* ---------------------------------------------------------------------------\n * Helpers\n * ------------------------------------------------------------------------- */\n\n/** Default send glyph — a paper-plane. Self-contained so the composer never\n * hard-depends on the icon package for this one shape. */\nfunction SendGlyph() {\n return (\n <svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M14.5 1.5 7 9M14.5 1.5l-4.6 13-2.9-5.5L1.5 6.1l13-4.6Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.3\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\n/** Loading spinner shown on the send button while `sending`. The arc spins\n * via CSS; reduced-motion is handled in the stylesheet. */\nfunction SpinnerGlyph() {\n return (\n <svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"8\" cy=\"8\" r=\"6\" stroke=\"currentColor\" strokeOpacity=\"0.3\" strokeWidth=\"2\" />\n <path d=\"M8 2a6 6 0 0 1 6 6\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" />\n </svg>\n );\n}\n\n/** Stop glyph — a rounded square, shown while a stoppable reply is written. */\nfunction StopGlyph() {\n return (\n <svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" aria-hidden=\"true\">\n <rect x=\"4\" y=\"4\" width=\"8\" height=\"8\" rx=\"1\" fill=\"currentColor\" />\n </svg>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const ChatComposer = forwardRef<HTMLTextAreaElement, ChatComposerProps>(\n function ChatComposer(\n {\n value,\n defaultValue,\n onChange,\n onSend,\n placeholder = \"Write a message…\",\n disabled = false,\n sending = false,\n allowEmpty = false,\n size = \"md\",\n minRows = 1,\n maxRows = 6,\n grow = \"up\",\n leading,\n trailing,\n onStop,\n stopLabel = \"Stop\",\n sendIcon,\n sendLabel = \"Send message\",\n fieldLabel = \"Message\",\n hint,\n className,\n onKeyDown,\n ...rest\n },\n forwardedRef,\n ) {\n const innerRef = useRef<HTMLTextAreaElement>(null);\n const setRef = (node: HTMLTextAreaElement | null) => {\n (innerRef as { current: HTMLTextAreaElement | null }).current = node;\n if (typeof forwardedRef === \"function\") forwardedRef(node);\n else if (forwardedRef)\n (forwardedRef as { current: HTMLTextAreaElement | null }).current = node;\n };\n\n const isControlled = value !== undefined;\n const [internal, setInternal] = useState<string>(defaultValue ?? \"\");\n const text = isControlled ? (value as string) : internal;\n\n const baseId = useId();\n\n const setText = (next: string) => {\n if (!isControlled) setInternal(next);\n onChange?.(next);\n };\n\n // ── Auto-grow the field, capped at `maxRows` (then it scrolls). Mirrors\n // the line-height-aware approach used by the DS Textarea so a unitless\n // line-height multiplier isn't treated as pixels.\n useEffect(() => {\n const el = innerRef.current;\n if (!el) return;\n el.style.height = \"auto\";\n const cs = window.getComputedStyle(el);\n const fontSize = parseFloat(cs.fontSize) || 14;\n const lh =\n cs.lineHeight === \"normal\"\n ? fontSize * 1.4\n : cs.lineHeight.endsWith(\"px\")\n ? parseFloat(cs.lineHeight)\n : parseFloat(cs.lineHeight) * fontSize;\n const padV = parseFloat(cs.paddingTop) + parseFloat(cs.paddingBottom);\n const max = lh * maxRows + padV;\n const next = Math.min(el.scrollHeight, max);\n el.style.height = `${next}px`;\n const overflowing = el.scrollHeight > max;\n el.style.overflowY = overflowing ? \"auto\" : \"hidden\";\n // Once capped, keep the caret line in view (you're typing at the end),\n // so growth reads as \"the newest line stays visible\" rather than the\n // field silently clipping the bottom.\n if (overflowing) el.scrollTop = el.scrollHeight;\n }, [text, maxRows]);\n\n const canSend = !disabled && !sending && (allowEmpty || text.trim().length > 0);\n const stoppable = sending && Boolean(onStop);\n\n const submit = () => {\n if (!canSend) return;\n onSend?.(text);\n // Uncontrolled composers clear themselves; controlled ones leave it to\n // the consumer (set `value=\"\"` after a successful send).\n if (!isControlled) setInternal(\"\");\n };\n\n const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {\n // Let the consumer's handler run first (it may preventDefault).\n onKeyDown?.(e);\n if (e.defaultPrevented) return;\n // Enter sends; Shift+Enter inserts a newline. IME composition (e.g.\n // selecting a CJK candidate with Enter) must not submit.\n if (e.key === \"Enter\" && !e.shiftKey && !e.nativeEvent.isComposing) {\n e.preventDefault();\n submit();\n }\n };\n\n return (\n <div\n className={cn(\n \"ods-composer\",\n `ods-composer--${size}`,\n `ods-composer--grow-${grow}`,\n disabled && \"ods-composer--disabled\",\n sending && \"ods-composer--sending\",\n stoppable && \"ods-composer--stoppable\",\n className,\n )}\n >\n <div className=\"ods-composer__row\">\n {leading && <div className=\"ods-composer__leading\">{leading}</div>}\n <textarea\n {...rest}\n ref={setRef}\n id={`ods-composer-${baseId}`}\n className=\"ods-composer__field\"\n rows={minRows}\n value={text}\n placeholder={placeholder}\n disabled={disabled}\n aria-label={fieldLabel}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={handleKeyDown}\n />\n <div className=\"ods-composer__trailing\">\n {trailing}\n <button\n type=\"button\"\n className=\"ods-composer__send\"\n aria-label={stoppable ? stopLabel : sending ? \"Sending…\" : sendLabel}\n aria-busy={(sending && !stoppable) || undefined}\n onClick={stoppable ? onStop : submit}\n disabled={stoppable ? false : !canSend}\n >\n {/* All glyphs are always mounted; CSS crossfades plane→spinner\n (or plane→stop when stoppable) so the button morphs smoothly. */}\n <span className=\"ods-composer__send-icon\">{sendIcon ?? <SendGlyph />}</span>\n <span className=\"ods-composer__send-spinner\" aria-hidden=\"true\">\n <SpinnerGlyph />\n </span>\n <span className=\"ods-composer__send-stop\" aria-hidden=\"true\">\n <StopGlyph />\n </span>\n </button>\n </div>\n </div>\n {hint && <div className=\"ods-composer__hint\">{hint}</div>}\n </div>\n );\n },\n);\n\nChatComposer.displayName = \"ChatComposer\";\n","\"use client\";\nimport { type ComponentPropsWithoutRef, forwardRef, type ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { TruncatedText } from \"../TruncatedText/TruncatedText\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type ChatLinkTarget = \"_blank\" | \"_self\";\n\nexport interface ChatLinkPreviewProps\n extends Omit<ComponentPropsWithoutRef<\"a\">, \"href\" | \"title\" | \"target\"> {\n /** The page the card opens. */\n url: string;\n /** Page title, on one line (\"…\" and a tooltip when longer). Falls back to the host. */\n title?: ReactNode;\n /** Short summary, clamped to two lines. */\n description?: ReactNode;\n /** Site name shown above the title. Falls back to the host. */\n siteName?: ReactNode;\n /** Preview image URL (a square crop is shown at the end of the card). */\n image?: string;\n /** Small site icon URL shown before the site name. */\n favicon?: string;\n /** Where the link opens. Default `\"_blank\"` (a new tab). */\n linkTarget?: ChatLinkTarget;\n /** Tighter card: no description, smaller image. Default `false`. */\n compact?: boolean;\n}\n\n/* ---------------------------------------------------------------------------\n * Helpers\n * ------------------------------------------------------------------------- */\n\n/** \"www.example.com/a\" → \"example.com\"; the raw value when it is not a URL. */\nexport function hostOf(url: string): string {\n try {\n return new URL(url).hostname.replace(/^www\\./, \"\");\n } catch {\n return url;\n }\n}\n\n/** `target` + `rel` for a link: a new tab gets no handle on this page. */\nexport function linkTargetProps(target: ChatLinkTarget) {\n return { target, rel: target === \"_blank\" ? \"noopener noreferrer\" : undefined };\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\n/**\n * A link a chat reply mentions, shown as a card: site, title, a short summary\n * and an optional image. The whole card is the link.\n */\nexport const ChatLinkPreview = forwardRef<HTMLAnchorElement, ChatLinkPreviewProps>(\n function ChatLinkPreview(\n {\n url,\n title,\n description,\n siteName,\n image,\n favicon,\n linkTarget = \"_blank\",\n compact = false,\n className,\n ...rest\n },\n ref,\n ) {\n const host = hostOf(url);\n return (\n <a\n {...rest}\n ref={ref}\n href={url}\n {...linkTargetProps(linkTarget)}\n className={cn(\n \"ods-chat-link-preview\",\n compact && \"ods-chat-link-preview--compact\",\n className,\n )}\n >\n <span className=\"ods-chat-link-preview__body\">\n <span className=\"ods-chat-link-preview__site\">\n {favicon && (\n <img\n className=\"ods-chat-link-preview__favicon\"\n src={favicon}\n alt=\"\"\n width={14}\n height={14}\n />\n )}\n <span className=\"ods-chat-link-preview__site-name\">{siteName ?? host}</span>\n </span>\n <TruncatedText className=\"ods-chat-link-preview__title\">{title ?? host}</TruncatedText>\n {description && !compact && (\n <span className=\"ods-chat-link-preview__description\">{description}</span>\n )}\n </span>\n {image && (\n <span\n className=\"ods-chat-link-preview__image\"\n style={{ backgroundImage: `url(${JSON.stringify(image)})` }}\n aria-hidden=\"true\"\n />\n )}\n </a>\n );\n },\n);\n\nChatLinkPreview.displayName = \"ChatLinkPreview\";\n","\"use client\";\nimport { type ReactNode, useLayoutEffect, useRef, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Tooltip } from \"../Tooltip/Tooltip\";\n\nexport interface TruncatedTextProps {\n children: ReactNode;\n className?: string;\n}\n\n/**\n * One line of text that ends in \"…\" when it does not fit. The full text\n * shows in a tooltip only when it is actually cut, re-measured when the text\n * or its box's width changes. The truncation is visual only: the full text\n * stays in the DOM, so an enclosing link or button keeps it as its name.\n *\n * Used for titles and names in cards: AgentCard and the chat preview cards.\n */\nexport function TruncatedText({ children, className }: Readonly<TruncatedTextProps>) {\n const ref = useRef<HTMLSpanElement>(null);\n const [cut, setCut] = useState(false);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: `children` is the trigger — new text can overflow without the box resizing, which the observer alone would miss.\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n const measure = () => setCut(el.scrollWidth > el.clientWidth);\n measure();\n if (typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(measure);\n observer.observe(el);\n return () => observer.disconnect();\n }, [children]);\n\n return (\n <Tooltip content={children} disabled={!cut} position=\"top\">\n <span ref={ref} className={cn(\"ods-truncated-text\", className)}>\n {children}\n </span>\n </Tooltip>\n );\n}\n","\"use client\";\nimport { type ComponentPropsWithoutRef, forwardRef, type ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { type ChatLinkTarget, linkTargetProps } from \"../ChatLinkPreview/ChatLinkPreview\";\nimport { TruncatedText } from \"../TruncatedText/TruncatedText\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport interface ChatDocPreviewProps\n extends Omit<ComponentPropsWithoutRef<\"a\">, \"href\" | \"title\" | \"target\"> {\n /** The docs page. */\n url: string;\n /** Page title, on one line; a longer one ends in \"…\" and shows in full in a tooltip. */\n title: ReactNode;\n /** Where the page sits in the docs, outermost first, e.g. `[\"Connectors\", \"Salesforce\"]`. */\n path?: string[];\n /** The passage the answer drew from, clamped to three lines. */\n excerpt?: ReactNode;\n /** Where the link opens. Default `\"_blank\"` (a new tab). */\n linkTarget?: ChatLinkTarget;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nfunction PageGlyph() {\n return (\n <svg viewBox=\"0 0 16 16\" width=\"16\" height=\"16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M4 2.5h5L13 6.5V13a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1Z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.1\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M9 2.5V6h3.5M5.5 9h5M5.5 11h3.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.1\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n}\n\n/**\n * A documentation page a chat reply points to: its title, the passage the\n * answer used, and where it sits in the docs. The whole card is the link.\n */\nexport const ChatDocPreview = forwardRef<HTMLAnchorElement, ChatDocPreviewProps>(\n function ChatDocPreview(\n { url, title, path, excerpt, linkTarget = \"_blank\", className, ...rest },\n ref,\n ) {\n return (\n <a\n {...rest}\n ref={ref}\n href={url}\n {...linkTargetProps(linkTarget)}\n className={cn(\"ods-chat-doc-preview\", className)}\n >\n {/* Only the title sits beside the glyph; what follows uses the full width. */}\n <span className=\"ods-chat-doc-preview__head\">\n <span className=\"ods-chat-doc-preview__icon\">\n <PageGlyph />\n </span>\n <TruncatedText className=\"ods-chat-doc-preview__title\">{title}</TruncatedText>\n </span>\n {excerpt && <span className=\"ods-chat-doc-preview__excerpt\">{excerpt}</span>}\n {path && path.length > 0 && (\n <span className=\"ods-chat-doc-preview__path\">\n {path.map((segment, i) => (\n // Keyed by the path up to here: unique even when a name repeats.\n <span key={path.slice(0, i + 1).join(\"/\")} className=\"ods-chat-doc-preview__segment\">\n {segment}\n </span>\n ))}\n </span>\n )}\n </a>\n );\n },\n);\n\nChatDocPreview.displayName = \"ChatDocPreview\";\n","\"use client\";\nimport {\n type ComponentPropsWithoutRef,\n createContext,\n forwardRef,\n type ReactNode,\n useContext,\n useId,\n useRef,\n} from \"react\";\nimport { useRadioGroup } from \"react-aria\";\nimport { type RadioGroupState, useRadioGroupState } from \"react-stately\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Context (internal)\n * ------------------------------------------------------------------------- */\n\nexport const RadioGroupContext = createContext<RadioGroupState | null>(null);\n\nexport function useRadioGroupContext() {\n const context = useContext(RadioGroupContext);\n if (!context) {\n throw new Error(\"Radio must be used within a RadioGroup\");\n }\n return context;\n}\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type RadioGroupOrientation = \"horizontal\" | \"vertical\";\n\ntype DivPropsBase = Omit<ComponentPropsWithoutRef<\"div\">, \"children\" | \"onChange\" | \"defaultValue\">;\n\nexport interface RadioGroupProps extends DivPropsBase {\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n label?: ReactNode;\n orientation?: RadioGroupOrientation;\n disabled?: boolean;\n children: ReactNode;\n /** Group name used by member `<input type=\"radio\">` elements during\n * form submission. */\n name?: string;\n /** Marks the radio group as required for form validation. */\n required?: boolean;\n /** Helper text rendered below the group. Suppressed when `error` is\n * set (the error message takes the slot). */\n helperText?: ReactNode;\n /** Error message — when present, the group renders the error state\n * and AT users hear the message via `role=\"alert\"`. */\n error?: ReactNode;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(function RadioGroup(\n {\n value,\n defaultValue,\n onChange,\n label,\n orientation = \"vertical\",\n disabled = false,\n children,\n className,\n name,\n required,\n id: providedId,\n helperText,\n error,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": consumerDescribedBy,\n ...rest\n },\n ref,\n) {\n const reactId = useId();\n const baseId = providedId ?? `ods-radio-group-${reactId}`;\n const hintId = error || helperText ? `${baseId}-hint` : undefined;\n const innerRef = useRef<HTMLDivElement>(null);\n\n const describedBy = [consumerDescribedBy, hintId].filter(Boolean).join(\" \") || undefined;\n\n const ariaProps = {\n // react-aria wants a string label for its `<label>` association,\n // even if our public API also takes ReactNode. Fall back to the\n // explicit aria-label when label isn't a string.\n label: typeof label === \"string\" ? label : ariaLabel || \"radio group\",\n value,\n defaultValue,\n onChange,\n isDisabled: disabled,\n isInvalid: !!error,\n isRequired: required,\n orientation,\n name,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n \"aria-describedby\": describedBy,\n };\n\n const state = useRadioGroupState(ariaProps);\n const { radioGroupProps, labelProps } = useRadioGroup(ariaProps, state);\n\n // Compose the forwarded ref with the internal one.\n const setRef = (node: HTMLDivElement | null) => {\n (innerRef as { current: HTMLDivElement | null }).current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) (ref as { current: HTMLDivElement | null }).current = node;\n };\n\n return (\n <div\n {...rest}\n {...radioGroupProps}\n ref={setRef}\n id={baseId}\n className={cn(\n \"ods-radio-group\",\n `ods-radio-group--${orientation}`,\n disabled && \"ods-radio-group--disabled\",\n error && \"ods-radio-group--error\",\n className,\n )}\n >\n {label && (\n <span {...labelProps} className=\"ods-radio-group__label\">\n {label}\n </span>\n )}\n <RadioGroupContext.Provider value={state}>\n <div className=\"ods-radio-group__items\">{children}</div>\n </RadioGroupContext.Provider>\n {error ? (\n <div\n id={hintId}\n className=\"ods-radio-group__hint ods-radio-group__hint--error\"\n role=\"alert\"\n >\n {error}\n </div>\n ) : helperText ? (\n <div id={hintId} className=\"ods-radio-group__hint\">\n {helperText}\n </div>\n ) : null}\n </div>\n );\n});\n\nRadioGroup.displayName = \"RadioGroup\";\n","\"use client\";\nimport { type ComponentPropsWithoutRef, forwardRef, type ReactNode, useRef } from \"react\";\nimport { useRadio } from \"react-aria\";\nimport { resolveAccessibleName } from \"../../utils/a11y\";\nimport { cn } from \"../../utils/cn\";\nimport { useRadioGroupContext } from \"./RadioGroup\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type RadioSize = \"sm\" | \"md\" | \"lg\";\n\ntype InputPropsBase = Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"value\" | \"size\" | \"onChange\" | \"type\" | \"ref\"\n>;\n\nexport interface RadioProps extends InputPropsBase {\n value: string;\n /** Visible label — accepts rich content for \"radio card\" layouts. */\n label?: ReactNode;\n /** Optional secondary line rendered below the label. Useful for the\n * \"radio with description\" pattern (settings panels, plan pickers). */\n description?: ReactNode;\n size?: RadioSize;\n disabled?: boolean;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const Radio = forwardRef<HTMLInputElement, RadioProps>(function Radio(\n { value, label, description, size = \"md\", disabled = false, className, ...props },\n forwardedRef,\n) {\n const state = useRadioGroupContext();\n const innerRef = useRef<HTMLInputElement>(null);\n // Compose the forwarded ref with our internal one — react-aria needs\n // to read the input via the ref it owns, but consumers may also want\n // direct access.\n const setRef = (node: HTMLInputElement | null) => {\n (innerRef as { current: HTMLInputElement | null }).current = node;\n if (typeof forwardedRef === \"function\") forwardedRef(node);\n else if (forwardedRef) (forwardedRef as { current: HTMLInputElement | null }).current = node;\n };\n\n // Falls back to `value` so radios in a group are distinguishable to\n // screen readers even if the caller forgets to pass `label`.\n const ariaNameProps = resolveAccessibleName({\n label: typeof label === \"string\" ? label : undefined,\n ariaLabel: (props as Record<string, unknown>)[\"aria-label\"] as string | undefined,\n ariaLabelledby: (props as Record<string, unknown>)[\"aria-labelledby\"] as string | undefined,\n componentName: \"Radio\",\n fallbacks: [value],\n });\n\n const { inputProps } = useRadio(\n {\n value,\n isDisabled: disabled,\n ...ariaNameProps,\n },\n state,\n innerRef,\n );\n\n const isSelected = state.selectedValue === value;\n\n // React Aria owns interactive handlers; let native form attrs pass\n // through (id, name, autoComplete, data-*, etc.).\n const {\n onClick: _onClick,\n onKeyDown: _onKeyDown,\n onKeyUp: _onKeyUp,\n onFocus: _onFocus,\n onBlur: _onBlur,\n ...passthroughProps\n } = props as Record<string, unknown>;\n\n return (\n <label\n className={cn(\n \"ods-radio\",\n `ods-radio--${size}`,\n isSelected && \"ods-radio--selected\",\n disabled && \"ods-radio--disabled\",\n description && \"ods-radio--with-description\",\n className,\n )}\n >\n <input\n {...(passthroughProps as ComponentPropsWithoutRef<\"input\">)}\n {...inputProps}\n ref={setRef}\n className=\"ods-radio__input\"\n />\n <div className=\"ods-radio__circle\" aria-hidden=\"true\">\n <div className={cn(\"ods-radio__dot\", isSelected && \"ods-radio__dot--visible\")} />\n </div>\n {(label || description) && (\n <div className=\"ods-radio__text\">\n {label && <span className=\"ods-radio__label\">{label}</span>}\n {description && <span className=\"ods-radio__description\">{description}</span>}\n </div>\n )}\n </label>\n );\n});\n\nRadio.displayName = \"Radio\";\n","\"use client\";\nimport {\n type ComponentPropsWithoutRef,\n type FormEvent,\n forwardRef,\n type ReactNode,\n useId,\n useState,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button } from \"../Button/Button\";\nimport { Checkbox } from \"../Checkbox/Checkbox\";\nimport { Input } from \"../Input/Input\";\nimport { Radio } from \"../Radio/Radio\";\nimport { RadioGroup } from \"../Radio/RadioGroup\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type ChatInputFieldType =\n | \"text\"\n | \"email\"\n | \"number\"\n | \"date\"\n | \"choice\"\n | \"multichoice\"\n | \"boolean\";\n\nexport interface ChatInputOption {\n value: string;\n label: string;\n}\n\nexport interface ChatInputField {\n /** Key of the value in the submitted answer. */\n name: string;\n label: string;\n type: ChatInputFieldType;\n /** `choice` / `multichoice` only. Plain strings are their own label. */\n options?: Array<ChatInputOption | string>;\n required?: boolean;\n placeholder?: string;\n helperText?: string;\n}\n\nexport type ChatInputValue = string | string[] | boolean | null;\nexport type ChatInputValues = Record<string, ChatInputValue>;\n\n/** The request once dealt with: the submitted values (and any typed answer), or skipped. */\nexport type ChatInputAnswer = { values: ChatInputValues; text?: string } | \"skipped\";\n\nexport interface ChatInputRequestProps extends Omit<ComponentPropsWithoutRef<\"form\">, \"onSubmit\"> {\n /** The question, in the assistant's words. */\n prompt: ReactNode;\n /** Optional line under the question: why it is asked, what happens next. */\n description?: ReactNode;\n /** The fields to fill. Empty: the card is a question answered by typing. */\n fields: ChatInputField[];\n /**\n * Fires on Send with the field values and the typed answer, if any. A typed\n * answer stands in for the fields: they are then not required, but anything\n * filled in must still be valid.\n */\n onSubmit: (values: ChatInputValues, text?: string) => void;\n /** Placeholder of the box every request has for typing an answer. Default `\"Or type your answer…\"`. */\n textPlaceholder?: string;\n /** Shows a Skip button when set. */\n onSkip?: () => void;\n /** Set once answered: the card turns read-only and shows the answer. */\n answer?: ChatInputAnswer | null;\n /** The answer is being sent. */\n submitting?: boolean;\n /** Default `\"Send\"`. */\n submitLabel?: ReactNode;\n /** Default `\"Skip\"`. */\n skipLabel?: ReactNode;\n}\n\n/* ---------------------------------------------------------------------------\n * Values\n * ------------------------------------------------------------------------- */\n\nconst EMAIL = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n\nexport function optionsOf(field: ChatInputField): ChatInputOption[] {\n return (field.options ?? []).map((o) => (typeof o === \"string\" ? { value: o, label: o } : o));\n}\n\nfunction emptyValue(field: ChatInputField): ChatInputValue {\n if (field.type === \"multichoice\") return [];\n return null;\n}\n\nfunction isEmpty(value: ChatInputValue): boolean {\n if (Array.isArray(value)) return value.length === 0;\n return value === null || value === \"\";\n}\n\n/** The problem with one field's value, in plain words; null when it is fine. */\nexport function fieldProblem(field: ChatInputField, value: ChatInputValue): string | null {\n if (isEmpty(value)) return field.required ? \"Required.\" : null;\n if (field.type === \"email\" && typeof value === \"string\" && !EMAIL.test(value.trim())) {\n return \"Enter an email address, like name@company.com.\";\n }\n if (field.type === \"number\" && typeof value === \"string\" && Number.isNaN(Number(value)))\n return \"Enter a number.\";\n return null;\n}\n\n/**\n * Each field's problem on Send. A typed answer stands in for the fields, so\n * an empty field is then fine; a filled one must still be valid.\n */\nexport function problemsOf(\n fields: ChatInputField[],\n values: ChatInputValues,\n typed: string,\n): Record<string, string | null> {\n return Object.fromEntries(\n fields.map((f) => {\n const value = values[f.name] ?? null;\n return [f.name, typed && isEmpty(value) ? null : fieldProblem(f, value)];\n }),\n );\n}\n\n/** One value as the answered card shows it. */\nexport function displayValue(field: ChatInputField, value: ChatInputValue): string {\n if (value === null || isEmpty(value)) return \"\";\n if (typeof value === \"boolean\") return value ? \"Yes\" : \"No\";\n const labels = new Map(optionsOf(field).map((o) => [o.value, o.label]));\n if (Array.isArray(value)) return value.map((v) => labels.get(v) ?? v).join(\", \");\n return labels.get(value) ?? value;\n}\n\n/* ---------------------------------------------------------------------------\n * Fields\n * ------------------------------------------------------------------------- */\n\ninterface FieldProps {\n field: ChatInputField;\n value: ChatInputValue;\n error: string | null;\n disabled: boolean;\n onChange: (value: ChatInputValue) => void;\n}\n\nfunction ChoiceField({ field, value, error, disabled, onChange }: Readonly<FieldProps>) {\n const options =\n field.type === \"boolean\"\n ? [\n { value: \"yes\", label: \"Yes\" },\n { value: \"no\", label: \"No\" },\n ]\n : optionsOf(field);\n let selected = \"\";\n if (field.type === \"boolean\" && typeof value === \"boolean\") selected = value ? \"yes\" : \"no\";\n else if (typeof value === \"string\") selected = value;\n return (\n <RadioGroup\n label={field.label}\n value={selected}\n onChange={(v) => onChange(field.type === \"boolean\" ? v === \"yes\" : v)}\n orientation={options.length > 3 ? \"vertical\" : \"horizontal\"}\n required={field.required}\n disabled={disabled}\n helperText={field.helperText}\n error={error ?? undefined}\n >\n {options.map((o) => (\n <Radio key={o.value} value={o.value} label={o.label} size=\"sm\" />\n ))}\n </RadioGroup>\n );\n}\n\nfunction MultiChoiceField({ field, value, error, disabled, onChange }: Readonly<FieldProps>) {\n const selected = Array.isArray(value) ? value : [];\n const toggle = (v: string, on: boolean) =>\n onChange(on ? [...selected, v] : selected.filter((s) => s !== v));\n return (\n <fieldset className=\"ods-chat-input-request__group\" disabled={disabled}>\n <legend className=\"ods-chat-input-request__legend\">{field.label}</legend>\n {optionsOf(field).map((o) => (\n <Checkbox\n key={o.value}\n size=\"sm\"\n label={o.label}\n checked={selected.includes(o.value)}\n onChange={(on) => toggle(o.value, on)}\n />\n ))}\n {error && (\n <span className=\"ods-chat-input-request__error\" role=\"alert\">\n {error}\n </span>\n )}\n </fieldset>\n );\n}\n\nfunction TextField({ field, value, error, disabled, onChange }: Readonly<FieldProps>) {\n return (\n <Input\n size=\"sm\"\n type={\n field.type === \"choice\" || field.type === \"multichoice\" || field.type === \"boolean\"\n ? \"text\"\n : field.type\n }\n label={field.label}\n value={typeof value === \"string\" ? value : \"\"}\n onChange={(e) => onChange(e.target.value)}\n placeholder={field.placeholder}\n helperText={field.helperText}\n required={field.required}\n disabled={disabled}\n error={Boolean(error)}\n errorMessage={error ?? undefined}\n />\n );\n}\n\nfunction Field(props: Readonly<FieldProps>) {\n const { type } = props.field;\n if (type === \"choice\" || type === \"boolean\") return <ChoiceField {...props} />;\n if (type === \"multichoice\") return <MultiChoiceField {...props} />;\n return <TextField {...props} />;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nfunction AnswerSummary({\n fields,\n answer,\n}: Readonly<{ fields: ChatInputField[]; answer: ChatInputAnswer }>) {\n if (answer === \"skipped\") return <p className=\"ods-chat-input-request__answer\">Skipped</p>;\n const parts = fields.map((f) => displayValue(f, answer.values[f.name] ?? null)).filter(Boolean);\n if (answer.text) parts.push(answer.text);\n return (\n <p className=\"ods-chat-input-request__answer\">\n <svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M3.5 8.5l3 3 6-7\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n <span>{parts.length > 0 ? parts.join(\" · \") : \"Sent\"}</span>\n </p>\n );\n}\n\n/**\n * The assistant asking the user for something, inside the thread: the\n * question, the fields, and a box to type the answer instead, with Send (plus\n * Skip when allowed). Once answered it turns read-only and shows the answer,\n * so the thread reads as a record.\n */\nexport const ChatInputRequest = forwardRef<HTMLFormElement, ChatInputRequestProps>(\n function ChatInputRequest(\n {\n prompt,\n description,\n fields,\n onSubmit,\n onSkip,\n answer = null,\n submitting = false,\n submitLabel = \"Send\",\n skipLabel = \"Skip\",\n textPlaceholder = \"Or type your answer…\",\n className,\n ...rest\n },\n ref,\n ) {\n const promptId = useId();\n const [values, setValues] = useState<ChatInputValues>(() =>\n Object.fromEntries(fields.map((f) => [f.name, emptyValue(f)])),\n );\n const [errors, setErrors] = useState<Record<string, string | null>>({});\n const [text, setText] = useState(\"\");\n const [textError, setTextError] = useState<string | null>(null);\n const answered = answer !== null;\n const locked = answered || submitting;\n\n const submit = (e: FormEvent) => {\n e.preventDefault();\n if (locked) return;\n const typed = text.trim();\n // With no fields, the typed answer is the answer.\n if (fields.length === 0 && !typed) {\n setTextError(\"Type an answer.\");\n return;\n }\n const found = problemsOf(fields, values, typed);\n setErrors(found);\n if (Object.values(found).some(Boolean)) return;\n onSubmit(values, typed || undefined);\n };\n\n return (\n <form\n {...rest}\n ref={ref}\n noValidate\n aria-labelledby={promptId}\n onSubmit={submit}\n className={cn(\n \"ods-chat-input-request\",\n answered && \"ods-chat-input-request--answered\",\n className,\n )}\n >\n <div className=\"ods-chat-input-request__head\">\n <p id={promptId} className=\"ods-chat-input-request__prompt\">\n {prompt}\n </p>\n {description && !answered && (\n <p className=\"ods-chat-input-request__description\">{description}</p>\n )}\n </div>\n\n {answered ? (\n <AnswerSummary fields={fields} answer={answer} />\n ) : (\n <>\n {fields.length > 0 && (\n <div className=\"ods-chat-input-request__fields\">\n {fields.map((f) => (\n <Field\n key={f.name}\n field={f}\n value={values[f.name] ?? null}\n error={errors[f.name] ?? null}\n disabled={locked}\n onChange={(v) => {\n setValues((prev) => ({ ...prev, [f.name]: v }));\n if (errors[f.name]) setErrors((prev) => ({ ...prev, [f.name]: null }));\n }}\n />\n ))}\n </div>\n )}\n <div className=\"ods-chat-input-request__reply\">\n <Input\n size=\"sm\"\n aria-label=\"Type your answer\"\n className=\"ods-chat-input-request__text\"\n value={text}\n onChange={(e) => {\n setText(e.target.value);\n if (textError) setTextError(null);\n }}\n placeholder={textPlaceholder}\n disabled={locked}\n error={Boolean(textError)}\n errorMessage={textError ?? undefined}\n />\n </div>\n <div className=\"ods-chat-input-request__actions\">\n {onSkip && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={onSkip}\n disabled={submitting}\n >\n {skipLabel}\n </Button>\n )}\n <Button type=\"submit\" variant=\"primary\" size=\"sm\" loading={submitting}>\n {submitLabel}\n </Button>\n </div>\n </>\n )}\n </form>\n );\n },\n);\n\nChatInputRequest.displayName = \"ChatInputRequest\";\n","\"use client\";\nimport { type ComponentPropsWithoutRef, forwardRef, type ReactNode, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button } from \"../Button/Button\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type ChatFeedbackRating = \"up\" | \"down\";\nexport type ChatFeedbackSize = \"sm\" | \"md\";\n\nexport interface ChatFeedbackProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"onChange\"> {\n /** Controlled rating. Omit for uncontrolled. */\n rating?: ChatFeedbackRating | null;\n /** Initial rating when uncontrolled. */\n defaultRating?: ChatFeedbackRating | null;\n /** Fires when the rating changes. Re-clicking the active thumb clears it\n * (passes `null`). */\n onRate?: (rating: ChatFeedbackRating | null) => void;\n /** Copy handler. When set, a Copy control appears (with a transient\n * \"Copied\" state). */\n onCopy?: () => void;\n /** Regenerate handler. When set, a Regenerate control appears. */\n onRegenerate?: () => void;\n /** Extra controls appended to the row. */\n children?: ReactNode;\n size?: ChatFeedbackSize;\n}\n\n/* ---------------------------------------------------------------------------\n * Glyphs — self-contained so the row doesn't hard-depend on the icon package.\n * ------------------------------------------------------------------------- */\n\nfunction ThumbUp() {\n return (\n <svg viewBox=\"0 0 16 16\" width=\"15\" height=\"15\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M5 7v6H3a1 1 0 0 1-1-1V8a1 1 0 0 1 1-1h2Zm0 0 3-4.5A1.5 1.5 0 0 1 10.4 4l-.6 3h3.1a1.5 1.5 0 0 1 1.47 1.8l-.8 4A1.5 1.5 0 0 1 12.1 14H5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.2\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\nfunction ThumbDown() {\n return (\n <svg viewBox=\"0 0 16 16\" width=\"15\" height=\"15\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M11 9V3h2a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-2Zm0 0-3 4.5A1.5 1.5 0 0 1 5.6 12l.6-3H3.1A1.5 1.5 0 0 1 1.63 7.2l.8-4A1.5 1.5 0 0 1 3.9 2H11\"\n stroke=\"currentColor\"\n strokeWidth=\"1.2\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\nfunction CopyGlyph() {\n return (\n <svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" aria-hidden=\"true\">\n <rect x=\"5.5\" y=\"5.5\" width=\"8\" height=\"8\" rx=\"1.5\" stroke=\"currentColor\" strokeWidth=\"1.2\" />\n <path\n d=\"M10.5 5.5V4A1.5 1.5 0 0 0 9 2.5H4A1.5 1.5 0 0 0 2.5 4v5A1.5 1.5 0 0 0 4 10.5h1.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.2\"\n />\n </svg>\n );\n}\nfunction CheckGlyph() {\n return (\n <svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M3 8.5l3 3 7-7\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\nfunction RegenGlyph() {\n return (\n <svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M13 8a5 5 0 1 1-1.5-3.5M13 2v3h-3\"\n stroke=\"currentColor\"\n strokeWidth=\"1.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const ChatFeedback = forwardRef<HTMLDivElement, ChatFeedbackProps>(function ChatFeedback(\n {\n rating,\n defaultRating = null,\n onRate,\n onCopy,\n onRegenerate,\n children,\n size = \"sm\",\n className,\n ...rest\n },\n ref,\n) {\n const isControlled = rating !== undefined;\n const [internal, setInternal] = useState<ChatFeedbackRating | null>(defaultRating);\n const current = isControlled ? rating : internal;\n\n const [copied, setCopied] = useState(false);\n\n const rate = (next: ChatFeedbackRating) => {\n const resolved = current === next ? null : next;\n if (!isControlled) setInternal(resolved);\n onRate?.(resolved);\n };\n\n const copy = () => {\n onCopy?.();\n setCopied(true);\n window.setTimeout(() => setCopied(false), 1600);\n };\n\n const btnSize = size === \"md\" ? \"md\" : \"sm\";\n\n return (\n <div\n {...rest}\n ref={ref}\n className={cn(\"ods-chat-feedback\", `ods-chat-feedback--${size}`, className)}\n role=\"group\"\n aria-label=\"Message feedback\"\n >\n <Button\n variant=\"icon\"\n size={btnSize}\n aria-label=\"Good response\"\n pressed={current === \"up\"}\n onClick={() => rate(\"up\")}\n >\n <ThumbUp />\n </Button>\n <Button\n variant=\"icon\"\n size={btnSize}\n aria-label=\"Bad response\"\n pressed={current === \"down\"}\n onClick={() => rate(\"down\")}\n >\n <ThumbDown />\n </Button>\n {onCopy && (\n <Button\n variant=\"icon\"\n size={btnSize}\n aria-label={copied ? \"Copied\" : \"Copy\"}\n onClick={copy}\n >\n {copied ? <CheckGlyph /> : <CopyGlyph />}\n </Button>\n )}\n {onRegenerate && (\n <Button\n variant=\"icon\"\n size={btnSize}\n aria-label=\"Regenerate response\"\n onClick={onRegenerate}\n >\n <RegenGlyph />\n </Button>\n )}\n {children}\n </div>\n );\n});\n\nChatFeedback.displayName = \"ChatFeedback\";\n","\"use client\";\nimport { type ComponentPropsWithoutRef, forwardRef, type ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport interface ChatScrollToBottomProps\n extends Omit<ComponentPropsWithoutRef<\"button\">, \"children\"> {\n /** Unread/new-message count shown as a badge. `0` / undefined hides it. */\n count?: number;\n /** Accessible label. Default `\"Jump to latest\"`. */\n label?: string;\n /** Render the label text beside the arrow (otherwise icon-only). Default\n * `true` when there's a `count`, else `false`. */\n showLabel?: boolean;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const ChatScrollToBottom = forwardRef<HTMLButtonElement, ChatScrollToBottomProps>(\n function ChatScrollToBottom(\n { count, label = \"Jump to latest\", showLabel, className, ...rest },\n ref,\n ) {\n const hasCount = typeof count === \"number\" && count > 0;\n const withLabel = showLabel ?? hasCount;\n\n const text: ReactNode = hasCount ? `${count} new` : withLabel ? label : null;\n\n return (\n <button\n {...rest}\n ref={ref}\n type=\"button\"\n className={cn(\n \"ods-chat-scroll-bottom\",\n !withLabel && \"ods-chat-scroll-bottom--icon\",\n className,\n )}\n aria-label={label}\n >\n <svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M8 3v8.5M4.5 8L8 11.5 11.5 8\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n {text && <span className=\"ods-chat-scroll-bottom__text\">{text}</span>}\n </button>\n );\n },\n);\n\nChatScrollToBottom.displayName = \"ChatScrollToBottom\";\n","\"use client\";\nimport {\n Children,\n type ComponentPropsWithoutRef,\n forwardRef,\n type ReactNode,\n type Ref,\n type UIEvent,\n useEffect,\n useRef,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Spinner } from \"../Spinner/Spinner\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type ChatThreadGap = \"sm\" | \"md\" | \"lg\";\n\nexport interface ChatThreadProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"title\"> {\n /** Messages — typically <ChatBubble> elements. */\n children?: ReactNode;\n /** Rendered (centered) when there are no messages and no `footer`. */\n emptyState?: ReactNode;\n /** Centered loading state for the initial fetch — takes precedence over\n * messages / empty state while `true`. */\n loading?: boolean;\n /** Pinned above the messages, scrolling with them — the home for a\n * \"Load earlier\" button or a day / context divider (history trails). */\n header?: ReactNode;\n /** Pinned to the bottom of the list, after the messages — e.g. a\n * <ChatBubble isTyping /> row while the agent is responding. */\n footer?: ReactNode;\n /** Auto-scroll to the newest message when content changes — but only when\n * the user is already near the bottom, so reading history isn't yanked.\n * Default `true`. */\n stickToBottom?: boolean;\n /** Vertical gap between messages. Default `\"md\"`. */\n gap?: ChatThreadGap;\n}\n\n/* How close to the bottom (px) still counts as \"following the conversation\". */\nconst STICK_THRESHOLD = 120;\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const ChatThread = forwardRef<HTMLDivElement, ChatThreadProps>(function ChatThread(\n {\n children,\n emptyState,\n loading = false,\n header,\n footer,\n stickToBottom = true,\n gap = \"md\",\n className,\n onScroll,\n ...rest\n },\n forwardedRef,\n) {\n const innerRef = useRef<HTMLDivElement>(null);\n const setRef = (node: HTMLDivElement | null) => {\n (innerRef as { current: HTMLDivElement | null }).current = node;\n if (typeof forwardedRef === \"function\") forwardedRef(node);\n else if (forwardedRef) (forwardedRef as { current: HTMLDivElement | null }).current = node;\n };\n\n // Track whether the user is \"following\" the bottom. Updated on scroll so\n // the post-render effect knows whether to pin to the newest message.\n const following = useRef(true);\n\n const handleScroll = (e: UIEvent<HTMLDivElement>) => {\n const el = e.currentTarget;\n following.current = el.scrollHeight - el.scrollTop - el.clientHeight < STICK_THRESHOLD;\n onScroll?.(e);\n };\n\n // After children/footer change, stick to bottom when the user was already\n // near it. Runs every commit; the `following` guard keeps it cheap and\n // non-intrusive when the user has scrolled up to read.\n useEffect(() => {\n if (!stickToBottom || loading) return;\n const el = innerRef.current;\n if (el && following.current) el.scrollTop = el.scrollHeight;\n });\n\n const isEmpty = Children.count(children) === 0;\n const showEmpty = !loading && isEmpty && !footer && emptyState != null;\n\n return (\n <div\n {...rest}\n ref={setRef as Ref<HTMLDivElement>}\n className={cn(\"ods-chat-thread\", `ods-chat-thread--gap-${gap}`, className)}\n // A log of messages — announce new arrivals politely to AT users.\n role=\"log\"\n aria-live=\"polite\"\n aria-relevant=\"additions\"\n onScroll={handleScroll}\n >\n {loading ? (\n <div className=\"ods-chat-thread__loading\">\n <Spinner label=\"Loading messages\" />\n </div>\n ) : showEmpty ? (\n <div className=\"ods-chat-thread__empty\">{emptyState}</div>\n ) : (\n <div className=\"ods-chat-thread__list\">\n {header && <div className=\"ods-chat-thread__header\">{header}</div>}\n {children}\n {footer && <div className=\"ods-chat-thread__footer\">{footer}</div>}\n </div>\n )}\n </div>\n );\n});\n\nChatThread.displayName = \"ChatThread\";\n","\"use client\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type ReactNode,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { ChatComposer, type ChatComposerProps } from \"../ChatComposer/ChatComposer\";\nimport { ChatScrollToBottom } from \"../ChatScrollToBottom/ChatScrollToBottom\";\nimport { ChatThread, type ChatThreadProps } from \"../ChatThread/ChatThread\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport interface ChatPanelProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"onSubmit\"> {\n /** Top bar — agent name, status, actions. Omit for no header. */\n header?: ReactNode;\n /** Messages: ChatBubble elements, dividers, etc. */\n children?: ReactNode;\n /** Centered empty state when there are no messages. */\n emptyState?: ReactNode;\n /** Initial-load spinner inside the thread. */\n loading?: boolean;\n /** Typing/thinking footer (e.g. `<ChatThinking/>` or `<ChatBubble isTyping/>`). */\n thinking?: ReactNode;\n /** Pinned above the messages (e.g. a \"Load earlier\" button). */\n threadHeader?: ReactNode;\n /** Quick-reply row shown just above the composer (e.g. `<ChatSuggestions/>`). */\n suggestions?: ReactNode;\n /** The composer. Provide a wired `<ChatComposer/>`, OR pass `onSend` and a\n * built-in composer is rendered. */\n composer?: ReactNode;\n /** Convenience: render a built-in `<ChatComposer onSend={…}/>` when no\n * `composer` slot is given. */\n onSend?: (value: string) => void;\n /** Props for the built-in composer (when using `onSend`). */\n composerProps?: Partial<ChatComposerProps>;\n /** Props forwarded to the inner `ChatThread`. */\n threadProps?: Partial<ChatThreadProps>;\n /** Show the floating \"jump to latest\" button when scrolled up. Default\n * `true`. */\n showScrollToBottom?: boolean;\n}\n\n/* How far from the bottom (px) before the jump-to-latest button appears. */\nconst JUMP_THRESHOLD = 200;\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const ChatPanel = forwardRef<HTMLDivElement, ChatPanelProps>(function ChatPanel(\n {\n header,\n children,\n emptyState,\n loading = false,\n thinking,\n threadHeader,\n suggestions,\n composer,\n onSend,\n composerProps,\n threadProps,\n showScrollToBottom = true,\n className,\n ...rest\n },\n ref,\n) {\n const threadRef = useRef<HTMLDivElement>(null);\n const [showJump, setShowJump] = useState(false);\n\n const handleScroll = useCallback(() => {\n const el = threadRef.current;\n if (!el) return;\n setShowJump(el.scrollHeight - el.scrollTop - el.clientHeight > JUMP_THRESHOLD);\n }, []);\n\n const jumpToBottom = useCallback(() => {\n const el = threadRef.current;\n if (el) el.scrollTo({ top: el.scrollHeight, behavior: \"smooth\" });\n }, []);\n\n return (\n <div {...rest} ref={ref} className={cn(\"ods-chat-panel\", className)}>\n {header && <div className=\"ods-chat-panel__header\">{header}</div>}\n\n <div className=\"ods-chat-panel__body\">\n <ChatThread\n {...threadProps}\n ref={threadRef}\n loading={loading}\n emptyState={emptyState}\n header={threadHeader}\n footer={thinking}\n onScroll={handleScroll}\n >\n {children}\n </ChatThread>\n\n {showScrollToBottom && showJump && (\n <div className=\"ods-chat-panel__jump\">\n <ChatScrollToBottom showLabel onClick={jumpToBottom} />\n </div>\n )}\n </div>\n\n {suggestions && <div className=\"ods-chat-panel__suggestions\">{suggestions}</div>}\n\n {(composer || onSend) && (\n <div className=\"ods-chat-panel__composer\">\n {composer ?? <ChatComposer onSend={onSend} {...composerProps} />}\n </div>\n )}\n </div>\n );\n});\n\nChatPanel.displayName = \"ChatPanel\";\n","\"use client\";\n\nimport type { ComponentPropsWithoutRef, ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * AssistantAura — the assistant's living border (DEV-575).\n *\n * Wraps any surface (a launcher, a top-bar trigger, a chat panel) in a 1 px\n * hairline whose accent light travels around the edge. It reads the\n * assistant's state, so the persona feels present:\n * idle — a short light drifts slowly round\n * listening — a little longer and quicker (the visitor is typing)\n * thinking — fast, with the soft accent tint behind: working on an answer\n * processing — two lights, with the tint: running tools or steps\n * speaking — steady while the reply is written\n * done — the whole edge lights once, then settles to the hairline\n * stopped — the light stops: a plain hairline\n * error — a still hairline in the failed colour\n * offline — a plain hairline\n * `intensity` scales it (`off` draws a plain hairline). The DS radius, no blur\n * or drop shadow; under reduced motion it stands still.\n * ------------------------------------------------------------------------- */\n\n/**\n * What the assistant is doing. The working states (`thinking`, `processing`,\n * `speaking`) move; the outcomes (`done`, `stopped`, `error`) say how the last\n * turn ended; `offline` means it can't answer at all.\n */\nexport type AssistantState =\n | \"idle\"\n | \"listening\"\n | \"thinking\"\n | \"processing\"\n | \"speaking\"\n | \"done\"\n | \"stopped\"\n | \"error\"\n | \"offline\";\n\n/** Every state, in the order a turn moves through them (stories, tests, pickers). */\nexport const ASSISTANT_STATES: readonly AssistantState[] = [\n \"idle\",\n \"listening\",\n \"thinking\",\n \"processing\",\n \"speaking\",\n \"done\",\n \"stopped\",\n \"error\",\n \"offline\",\n];\nexport type AssistantAuraIntensity = \"off\" | \"subtle\" | \"normal\" | \"strong\";\n\nexport interface AssistantAuraProps extends ComponentPropsWithoutRef<\"div\"> {\n /** What the assistant is doing: it sets the light's pace and brightness. Default `idle`. */\n state?: AssistantState;\n /** How much aura. Default `normal`. */\n intensity?: AssistantAuraIntensity;\n /** Ring thickness in px. Default `1`. */\n thickness?: number;\n children?: ReactNode;\n}\n\nexport function AssistantAura({\n state = \"idle\",\n intensity = \"normal\",\n thickness = 1,\n className,\n style,\n children,\n ...rest\n}: AssistantAuraProps) {\n return (\n <div\n {...rest}\n data-state={state}\n className={cn(\"ods-aura\", `ods-aura--${intensity}`, `ods-aura--${state}`, className)}\n style={{ ...style, [\"--aura-thickness\" as string]: `${thickness}px` }}\n >\n <div className=\"ods-aura__content\">{children}</div>\n </div>\n );\n}\n","\"use client\";\n\nimport type { ComponentPropsWithoutRef, ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport type { AssistantState } from \"../AssistantAura/AssistantAura\";\n\n/* ---------------------------------------------------------------------------\n * AssistantOrb — Ova's mark, alive (DEV-575).\n *\n * The Octaviaflow logo itself — the cube on its blue-to-teal tile, at the\n * logo's proportions — chosen by the owner from the Ova icon explorations. It\n * is the face of the assistant in headers, triggers and launchers, and it\n * moves with the assistant's state:\n * idle — the centre node breathes\n * listening — a hairline frames the tile; the inner edges draw in\n * thinking — the inner edges withdraw and return, one after another\n * processing — the inner edges turn round the cube, a sixth at a time\n * speaking — the node pulses with the words; the edges answer\n * done — the edges draw out once and the node lands\n * stopped — the edges pull in and the node becomes a stop square\n * error — the tile turns the failed colour and shows \"!\", with a shake\n * offline — a grey tile, still\n * `children` replaces the cube (an avatar image, a letter). Decorative by\n * default; pass `label` to give it an accessible name. Still under reduced\n * motion.\n * ------------------------------------------------------------------------- */\n\nexport type AssistantOrbSize = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n\nexport interface AssistantOrbProps extends ComponentPropsWithoutRef<\"span\"> {\n state?: AssistantState;\n /** xs 16 · sm 20 · md 28 · lg 40 · xl 56 px. Default `md`. */\n size?: AssistantOrbSize;\n /** An accessible name (e.g. \"Ova is thinking\"). Omit when the orb is decoration. */\n label?: string;\n /** Replaces the cube: an image, a letter. */\n children?: ReactNode;\n}\n\n/* The logo's cube (octaviaflow-ui icon.svg, a 512 tile) at 1/16: the hexagon,\n * the three inner edges drawn from the centre out, and the centre node. The\n * stop square and the \"!\" are hidden until their states. */\nfunction CubeMark() {\n return (\n <svg className=\"ods-orb__mark\" viewBox=\"0 0 32 32\" aria-hidden=\"true\" focusable=\"false\">\n <path className=\"ods-orb__hex\" d=\"M16 7 9 11v8l7 4 7-4v-8l-7-4Z\" />\n <g className=\"ods-orb__edges\">\n <path className=\"ods-orb__edge\" pathLength={1} d=\"M16 15V7\" />\n <path className=\"ods-orb__edge\" pathLength={1} d=\"M16 15l7-4\" />\n <path className=\"ods-orb__edge\" pathLength={1} d=\"M16 15 9 11\" />\n </g>\n <circle className=\"ods-orb__node\" cx=\"16\" cy=\"15\" r=\"1.75\" />\n <rect className=\"ods-orb__stop\" x=\"14\" y=\"13\" width=\"4\" height=\"4\" />\n <g className=\"ods-orb__alert\">\n <path d=\"M16 10.5v5\" />\n <circle cx=\"16\" cy=\"18.5\" r=\"1.1\" />\n </g>\n </svg>\n );\n}\n\nexport function AssistantOrb({\n state = \"idle\",\n size = \"md\",\n label,\n className,\n children,\n ...rest\n}: AssistantOrbProps) {\n return (\n <span\n {...rest}\n {...(label ? { role: \"img\", \"aria-label\": label } : { \"aria-hidden\": true })}\n data-state={state}\n className={cn(\"ods-orb\", `ods-orb--${size}`, `ods-orb--${state}`, className)}\n >\n <span className=\"ods-orb__ring\" />\n <span className=\"ods-orb__core\">{children ?? <CubeMark />}</span>\n </span>\n );\n}\n","\"use client\";\nimport { type ComponentPropsWithoutRef, forwardRef, type ReactNode, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * How the sources render inside the expanded panel:\n * - `\"links\"` — stacked rows, title links out, optional snippet.\n * - `\"chips\"` — compact pills that link out.\n * - `\"plain-chips\"` — compact pills, NO link (labels only).\n * - `\"urls\"` — rows showing the raw URL (monospace), links out.\n */\nexport type ChatSourcesDisplay = \"links\" | \"chips\" | \"plain-chips\" | \"urls\";\n\n/**\n * Where a source link opens:\n * - `\"_blank\"` — a new tab (the default).\n * - `\"_self\"` — the current tab, e.g. a docs assistant whose sources are\n * pages of the same site.\n */\nexport type ChatSourcesLinkTarget = \"_blank\" | \"_self\";\n\nexport interface ChatSource {\n /** Stable key. Falls back to the index. */\n id?: string;\n /** Source title / name. */\n title: ReactNode;\n /** Link — makes the source clickable (opens per `linkTarget`). */\n url?: string;\n /** Short excerpt the answer drew from (`links` display). */\n snippet?: ReactNode;\n /** Small trailing label, e.g. a domain or file path. */\n meta?: ReactNode;\n}\n\nexport interface ChatSourcesProps\n extends Omit<ComponentPropsWithoutRef<\"details\">, \"title\" | \"onToggle\"> {\n sources: ChatSource[];\n /** Trigger label. Default `\"Sources\"`. */\n label?: ReactNode;\n /** How the sources render once expanded. Default `\"links\"`. */\n display?: ChatSourcesDisplay;\n /** Prefix sources with `[n]` (applies to `links` / `urls`). Default `true`. */\n numbered?: boolean;\n /** Start expanded. Default `false`. */\n defaultOpen?: boolean;\n /** Where source links open. Default `\"_blank\"` (a new tab). */\n linkTarget?: ChatSourcesLinkTarget;\n}\n\n/* ---------------------------------------------------------------------------\n * Helpers\n * ------------------------------------------------------------------------- */\n\nfunction hostOf(url: string): string {\n try {\n return new URL(url).hostname.replace(/^www\\./, \"\");\n } catch {\n return url;\n }\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const ChatSources = forwardRef<HTMLDetailsElement, ChatSourcesProps>(function ChatSources(\n {\n sources,\n label = \"Sources\",\n display = \"links\",\n numbered = true,\n defaultOpen = false,\n linkTarget = \"_blank\",\n className,\n ...rest\n },\n ref,\n) {\n // Controlled-open synced with native toggling — keeps it an accessible\n // <details> disclosure while letting us rotate the caret.\n const [open, setOpen] = useState(defaultOpen);\n if (!sources || sources.length === 0) return null;\n\n const count = sources.length;\n const isChips = display === \"chips\" || display === \"plain-chips\";\n\n return (\n <details\n {...rest}\n ref={ref}\n open={open}\n onToggle={(e) => setOpen((e.currentTarget as HTMLDetailsElement).open)}\n className={cn(\"ods-chat-sources\", `ods-chat-sources--${display}`, className)}\n >\n {/* Trigger — styled like a ChatBubble action button. */}\n <summary className=\"ods-chat-sources__trigger\">\n <span className=\"ods-chat-sources__caret\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 12 12\" width=\"11\" height=\"11\" fill=\"none\">\n <path\n d=\"M4 2.5L8 6l-4 3.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </span>\n <span className=\"ods-chat-sources__trigger-label\">{label}</span>\n <span className=\"ods-chat-sources__count\">{count}</span>\n </summary>\n\n <div className={cn(\"ods-chat-sources__panel\", isChips && \"ods-chat-sources__panel--chips\")}>\n {sources.map((s, i) => {\n const key = s.id ?? `${i}`;\n const idx = numbered ? <span className=\"ods-chat-sources__index\">[{i + 1}]</span> : null;\n // A new tab gets no handle on this page (`noopener`).\n const linkProps = s.url\n ? {\n href: s.url,\n target: linkTarget,\n rel: linkTarget === \"_blank\" ? \"noopener noreferrer\" : undefined,\n }\n : null;\n\n // ── chips / plain-chips ──────────────────────────────────────\n if (isChips) {\n const chipClass = cn(\n \"ods-chat-sources__chip\",\n s.url && display === \"chips\" && \"ods-chat-sources__chip--link\",\n );\n return display === \"chips\" && linkProps ? (\n <a key={key} className={chipClass} {...linkProps}>\n {s.title}\n </a>\n ) : (\n <span key={key} className={chipClass}>\n {s.title}\n </span>\n );\n }\n\n // ── urls ─────────────────────────────────────────────────────\n if (display === \"urls\") {\n const shown = s.url ?? \"\";\n return (\n <a key={key} className=\"ods-chat-sources__url\" {...(linkProps ?? {})}>\n {idx}\n <span className=\"ods-chat-sources__url-text\">{shown || s.title}</span>\n </a>\n );\n }\n\n // ── links (default) ──────────────────────────────────────────\n const Row = linkProps ? \"a\" : \"div\";\n return (\n <Row\n key={key}\n className={cn(\"ods-chat-sources__row\", s.url && \"ods-chat-sources__row--link\")}\n {...(linkProps ?? {})}\n >\n {idx}\n <span className=\"ods-chat-sources__body\">\n <span className=\"ods-chat-sources__title\">{s.title}</span>\n {s.snippet && <span className=\"ods-chat-sources__snippet\">{s.snippet}</span>}\n </span>\n {(s.meta ?? (s.url ? hostOf(s.url) : null)) && (\n <span className=\"ods-chat-sources__meta\">{s.meta ?? hostOf(s.url as string)}</span>\n )}\n </Row>\n );\n })}\n </div>\n </details>\n );\n});\n\nChatSources.displayName = \"ChatSources\";\n","\"use client\";\nimport { type ComponentPropsWithoutRef, forwardRef, type ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type ChatSuggestionsSize = \"sm\" | \"md\";\nexport type ChatSuggestionsLayout = \"wrap\" | \"scroll\";\n\nexport interface ChatSuggestion {\n /** Stable key. Falls back to the index. */\n id?: string;\n /** Chip label. */\n label: ReactNode;\n /** Text sent on select. Defaults to `label` when it's a string. */\n value?: string;\n /** Optional leading glyph. */\n icon?: ReactNode;\n disabled?: boolean;\n}\n\nexport interface ChatSuggestionsProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"onSelect\"> {\n /** Suggestions — plain strings or `{ label, value, … }` objects. */\n items: Array<string | ChatSuggestion>;\n /** Fires with the resolved text + the source item when a chip is clicked. */\n onSelect?: (value: string, item: ChatSuggestion) => void;\n /** Optional heading above the chips. */\n label?: ReactNode;\n size?: ChatSuggestionsSize;\n /** `\"wrap\"` (chips wrap to new rows) or `\"scroll\"` (single scrolling row).\n * Default `\"wrap\"`. */\n layout?: ChatSuggestionsLayout;\n /** Disable the whole set. */\n disabled?: boolean;\n}\n\n/* ---------------------------------------------------------------------------\n * Helpers\n * ------------------------------------------------------------------------- */\n\nfunction normalize(item: string | ChatSuggestion): ChatSuggestion {\n return typeof item === \"string\" ? { label: item, value: item } : item;\n}\n\nfunction resolveValue(s: ChatSuggestion): string {\n if (s.value != null) return s.value;\n return typeof s.label === \"string\" ? s.label : \"\";\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const ChatSuggestions = forwardRef<HTMLDivElement, ChatSuggestionsProps>(\n function ChatSuggestions(\n { items, onSelect, label, size = \"md\", layout = \"wrap\", disabled = false, className, ...rest },\n ref,\n ) {\n return (\n <div\n {...rest}\n ref={ref}\n className={cn(\n \"ods-chat-suggestions\",\n `ods-chat-suggestions--${size}`,\n `ods-chat-suggestions--${layout}`,\n className,\n )}\n role=\"group\"\n aria-label={typeof label === \"string\" ? label : \"Suggested replies\"}\n >\n {label && <span className=\"ods-chat-suggestions__label\">{label}</span>}\n <div className=\"ods-chat-suggestions__track\">\n {items.map((raw, i) => {\n const s = normalize(raw);\n const isDisabled = disabled || s.disabled;\n return (\n <button\n key={s.id ?? `${i}`}\n type=\"button\"\n className=\"ods-chat-suggestions__chip\"\n disabled={isDisabled}\n onClick={() => onSelect?.(resolveValue(s), s)}\n >\n {s.icon && <span className=\"ods-chat-suggestions__chip-icon\">{s.icon}</span>}\n <span className=\"ods-chat-suggestions__chip-label\">{s.label}</span>\n </button>\n );\n })}\n </div>\n </div>\n );\n },\n);\n\nChatSuggestions.displayName = \"ChatSuggestions\";\n","\"use client\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type ReactNode,\n useEffect,\n useState,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Thinking / typing animation style:\n * - `\"dots\"` — three bouncing dots (classic typing).\n * - `\"wave\"` — five dots in a smooth travelling wave.\n * - `\"pulse\"` — a single pulsing orb (compact \"alive\" cue).\n * - `\"bars\"` — equalizer bars (good for \"listening / generating audio\").\n * - `\"shimmer\"` — a shimmering label, e.g. \"Thinking…\" with a light sweep.\n * - `\"cursor\"` — a label + blinking caret (streaming-text feel).\n */\nexport type ChatThinkingVariant = \"dots\" | \"wave\" | \"pulse\" | \"bars\" | \"shimmer\" | \"cursor\";\n\nexport type ChatThinkingSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface ChatThinkingProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"children\"> {\n variant?: ChatThinkingVariant;\n /** Optional label, e.g. \"Thinking…\", \"Searching the web…\". For `shimmer` /\n * `cursor` the label IS the animated element (defaults to \"Thinking…\"). */\n label?: ReactNode;\n /** Cycle through these labels in a loop (with a fade transition) until the\n * component unmounts — e.g. while waiting for a response. Overrides\n * `label`. Best with the `shimmer` variant. */\n labels?: string[];\n /** Milliseconds each label stays before the next. Default `2200`. */\n cycleMs?: number;\n size?: ChatThinkingSize;\n /** Accessible status announced to AT. Default `\"Assistant is thinking\"`. */\n srLabel?: string;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const ChatThinking = forwardRef<HTMLDivElement, ChatThinkingProps>(function ChatThinking(\n {\n variant = \"dots\",\n label,\n labels,\n cycleMs = 2200,\n size = \"md\",\n srLabel = \"Assistant is thinking\",\n className,\n ...rest\n },\n ref,\n) {\n // Optionally cycle through `labels` on a loop with a fade transition.\n const cycling = Array.isArray(labels) && labels.length > 0;\n const [idx, setIdx] = useState(0);\n useEffect(() => {\n if (!cycling || labels!.length < 2) return;\n const id = window.setInterval(() => setIdx((i) => (i + 1) % labels!.length), cycleMs);\n return () => window.clearInterval(id);\n }, [cycling, labels, cycleMs]);\n\n // The active label and a key that changes each cycle so the fade replays.\n const activeLabel: ReactNode = cycling ? labels![idx % labels!.length] : label;\n const fadeKey = cycling ? idx : undefined;\n\n let indicator: ReactNode;\n switch (variant) {\n case \"wave\":\n indicator = (\n <span className=\"ods-thinking__wave\">\n {[0, 1, 2, 3, 4].map((i) => (\n <span key={i} className=\"ods-thinking__wave-dot\" />\n ))}\n </span>\n );\n break;\n case \"pulse\":\n indicator = <span className=\"ods-thinking__pulse\" />;\n break;\n case \"bars\":\n indicator = (\n <span className=\"ods-thinking__bars\">\n {[0, 1, 2, 3].map((i) => (\n <span key={i} className=\"ods-thinking__bar\" />\n ))}\n </span>\n );\n break;\n case \"shimmer\":\n indicator = (\n <span key={fadeKey} className=\"ods-thinking__shimmer\">\n {activeLabel ?? \"Thinking…\"}\n </span>\n );\n break;\n case \"cursor\":\n indicator = (\n <>\n <span key={fadeKey} className=\"ods-thinking__cursor-label ods-thinking__fade\">\n {activeLabel ?? \"Thinking\"}\n </span>\n <span className=\"ods-thinking__cursor\" />\n </>\n );\n break;\n case \"dots\":\n default:\n indicator = (\n <span className=\"ods-thinking__dots\">\n {[0, 1, 2].map((i) => (\n <span key={i} className=\"ods-thinking__dot\" />\n ))}\n </span>\n );\n }\n\n // shimmer / cursor render the label themselves; the others show it after\n // the indicator.\n const labelInline = variant !== \"shimmer\" && variant !== \"cursor\";\n const inlineLabel = cycling ? activeLabel : label;\n\n return (\n <div\n {...rest}\n ref={ref}\n role=\"status\"\n aria-live=\"polite\"\n className={cn(\"ods-thinking\", `ods-thinking--${variant}`, `ods-thinking--${size}`, className)}\n >\n <span className=\"ods-thinking__sr\">{srLabel}</span>\n <span className=\"ods-thinking__indicator\" aria-hidden=\"true\">\n {indicator}\n </span>\n {labelInline && inlineLabel && (\n <span key={fadeKey} className=\"ods-thinking__label ods-thinking__fade\" aria-hidden=\"true\">\n {inlineLabel}\n </span>\n )}\n </div>\n );\n});\n\nChatThinking.displayName = \"ChatThinking\";\n","\"use client\";\nimport { type ComponentPropsWithoutRef, forwardRef, type ReactNode, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type ChatToolCallStatus = \"success\" | \"error\" | \"running\" | \"pending\";\n\nexport interface ChatToolCall {\n /** Stable key. Falls back to the index. */\n id?: string;\n /** Tool / function name. */\n name: ReactNode;\n /** Invocation arguments — rendered monospace. */\n args?: ReactNode;\n /** Call outcome. Default `\"success\"`. */\n status?: ChatToolCallStatus;\n /** Short result / summary line. */\n result?: ReactNode;\n /** Wall-clock duration in ms — shown as a trailing badge. */\n durationMs?: number;\n}\n\nexport interface ChatToolTraceProps\n extends Omit<ComponentPropsWithoutRef<\"details\">, \"title\" | \"onToggle\"> {\n calls: ChatToolCall[];\n /** Collapsed summary. Defaults to a live \"Working…\" while a step runs, or\n * \"Used N tool(s)\" once finished. */\n summary?: ReactNode;\n /** Start expanded. Default `false` — but the trace auto-opens while a step\n * is still running so the activity is visible. */\n defaultOpen?: boolean;\n /** Open by itself while a step runs. Default `true`; `false` keeps a slim\n * one-line summary (the assistant's surfaces). */\n autoOpen?: boolean;\n}\n\n/* ---------------------------------------------------------------------------\n * Status node glyphs\n * ------------------------------------------------------------------------- */\n\nfunction NodeGlyph({ status }: { status: ChatToolCallStatus }) {\n switch (status) {\n case \"success\":\n return (\n <svg viewBox=\"0 0 12 12\" width=\"9\" height=\"9\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M2.5 6.2l2.2 2.2L9.5 3.6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n case \"error\":\n return (\n <svg viewBox=\"0 0 12 12\" width=\"9\" height=\"9\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M3.5 3.5l5 5M8.5 3.5l-5 5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n case \"running\":\n return (\n <svg\n viewBox=\"0 0 12 12\"\n width=\"11\"\n height=\"11\"\n fill=\"none\"\n aria-hidden=\"true\"\n className=\"ods-chat-tools__spin\"\n >\n <circle\n cx=\"6\"\n cy=\"6\"\n r=\"4.4\"\n stroke=\"currentColor\"\n strokeOpacity=\"0.25\"\n strokeWidth=\"1.6\"\n />\n <path\n d=\"M6 1.6a4.4 4.4 0 0 1 4.4 4.4\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n />\n </svg>\n );\n case \"pending\":\n return <span className=\"ods-chat-tools__dot\" aria-hidden=\"true\" />;\n }\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const ChatToolTrace = forwardRef<HTMLDetailsElement, ChatToolTraceProps>(\n function ChatToolTrace(\n { calls, summary, defaultOpen = false, autoOpen = true, className, ...rest },\n ref,\n ) {\n const count = calls?.length ?? 0;\n const running = (calls ?? []).some((c) => c.status === \"running\" || c.status === \"pending\");\n\n // Auto-open while work is in flight so the agent's activity \"announces\"\n // itself; otherwise honour `defaultOpen`.\n const [open, setOpen] = useState(defaultOpen || (autoOpen && running));\n\n const defaultSummary = running ? \"Working…\" : `Used ${count} ${count === 1 ? \"tool\" : \"tools\"}`;\n\n return (\n <details\n {...rest}\n ref={ref}\n open={open}\n onToggle={(e) => setOpen((e.currentTarget as HTMLDetailsElement).open)}\n className={cn(\"ods-chat-tools\", running && \"ods-chat-tools--running\", className)}\n >\n <summary className=\"ods-chat-tools__summary\">\n <span className=\"ods-chat-tools__caret\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 12 12\" width=\"11\" height=\"11\" fill=\"none\">\n <path\n d=\"M4 2.5L8 6l-4 3.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.4\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </span>\n {running && <span className=\"ods-chat-tools__live\" aria-hidden=\"true\" />}\n <span className=\"ods-chat-tools__summary-text\">{summary ?? defaultSummary}</span>\n {!running && count > 0 && <span className=\"ods-chat-tools__count\">{count}</span>}\n </summary>\n\n <ol className=\"ods-chat-tools__steps\">\n {calls.map((c, i) => {\n const status = c.status ?? \"success\";\n return (\n <li\n key={c.id ?? `${i}`}\n className={cn(\"ods-chat-tools__step\", `ods-chat-tools__step--${status}`)}\n >\n <span className=\"ods-chat-tools__rail\" aria-hidden=\"true\">\n <span className=\"ods-chat-tools__node\">\n <NodeGlyph status={status} />\n </span>\n </span>\n <span className=\"ods-chat-tools__detail\">\n <span className=\"ods-chat-tools__head\">\n <code className=\"ods-chat-tools__name\">{c.name}</code>\n {c.args != null && <code className=\"ods-chat-tools__args\">{c.args}</code>}\n {typeof c.durationMs === \"number\" && (\n <span className=\"ods-chat-tools__duration\">{c.durationMs}ms</span>\n )}\n </span>\n {c.result != null && <span className=\"ods-chat-tools__result\">{c.result}</span>}\n </span>\n </li>\n );\n })}\n </ol>\n </details>\n );\n },\n);\n\nChatToolTrace.displayName = \"ChatToolTrace\";\n","\"use client\";\nimport { type ComponentPropsWithoutRef, forwardRef, type ReactNode, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { type ChatLinkTarget, hostOf, linkTargetProps } from \"../ChatLinkPreview/ChatLinkPreview\";\nimport { TruncatedText } from \"../TruncatedText/TruncatedText\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type ChatVideoProvider = \"youtube\" | \"vimeo\" | \"loom\" | \"file\";\n\nexport interface ChatVideoEmbed {\n provider: ChatVideoProvider;\n /** What the player loads: the provider's embed URL, or the file itself. */\n src: string;\n}\n\nexport interface ChatVideoPreviewProps extends Omit<ComponentPropsWithoutRef<\"div\">, \"title\"> {\n /** The video's page (or file) URL. */\n url: string;\n /** Video title. */\n title: ReactNode;\n /**\n * Poster image URL. Pass a proxied URL: the component never fetches a\n * provider thumbnail itself. Without one, or if it fails to load, the card\n * shows generated art instead.\n */\n thumbnail?: string;\n /** Human duration, e.g. `\"4:12\"`. */\n duration?: ReactNode;\n /** Where \"Open\" goes. Default `\"_blank\"` (a new tab). */\n linkTarget?: ChatLinkTarget;\n}\n\n/* ---------------------------------------------------------------------------\n * Embeds\n * ------------------------------------------------------------------------- */\n\nconst PROVIDER_LABEL: Record<ChatVideoProvider, string> = {\n youtube: \"YouTube\",\n vimeo: \"Vimeo\",\n loom: \"Loom\",\n file: \"Video\",\n};\n\nconst ID = /^[\\w-]+$/;\n\nfunction youtubeId(u: URL): string | null {\n const host = u.hostname.replace(/^www\\.|^m\\./, \"\");\n if (host === \"youtu.be\") return u.pathname.slice(1).split(\"/\")[0] || null;\n if (host !== \"youtube.com\" && host !== \"youtube-nocookie.com\") return null;\n if (u.pathname === \"/watch\") return u.searchParams.get(\"v\");\n const [, kind, id] = u.pathname.split(\"/\");\n return kind === \"embed\" || kind === \"shorts\" || kind === \"live\" ? (id ?? null) : null;\n}\n\nfunction lastSegment(u: URL, prefixes: string[]): string | null {\n const parts = u.pathname.split(\"/\").filter(Boolean);\n if (parts.length === 0) return null;\n if (prefixes.length > 0 && !prefixes.includes(parts[0] ?? \"\")) return null;\n return parts[parts.length - 1] ?? null;\n}\n\n/**\n * The player for a video URL: YouTube (privacy-enhanced host), Vimeo, Loom,\n * or a direct .mp4 / .webm / .mov file. Null for anything else — the card\n * then only links out. Ids are checked, so nothing else reaches the src.\n */\nexport function videoEmbedOf(url: string): ChatVideoEmbed | null {\n let u: URL;\n try {\n u = new URL(url);\n } catch {\n return null;\n }\n if (u.protocol !== \"https:\" && u.protocol !== \"http:\") return null;\n const host = u.hostname.replace(/^www\\./, \"\");\n const yt = youtubeId(u);\n if (yt && ID.test(yt))\n return { provider: \"youtube\", src: `https://www.youtube-nocookie.com/embed/${yt}?autoplay=1` };\n if (host === \"vimeo.com\" || host === \"player.vimeo.com\") {\n const id = lastSegment(u, []);\n if (id && /^\\d+$/.test(id))\n return { provider: \"vimeo\", src: `https://player.vimeo.com/video/${id}?autoplay=1` };\n }\n if (host === \"loom.com\") {\n const id = lastSegment(u, [\"share\", \"embed\"]);\n if (id && ID.test(id))\n return { provider: \"loom\", src: `https://www.loom.com/embed/${id}?autoplay=1` };\n }\n if (/\\.(mp4|webm|mov)$/i.test(u.pathname)) return { provider: \"file\", src: u.toString() };\n return null;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nfunction PlayGlyph() {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"22\" height=\"22\" aria-hidden=\"true\">\n <path d=\"M8 5.5v13l10.5-6.5z\" fill=\"currentColor\" />\n </svg>\n );\n}\n\n/** A small stable hash of a string, for picking the art's proportions. */\nfunction seedOf(text: string): number {\n let h = 2166136261;\n for (let i = 0; i < text.length; i++) {\n h ^= text.charCodeAt(i);\n h = Math.imul(h, 16777619);\n }\n return h >>> 0;\n}\n\n/** The nth value in [min, max] from a seed, different for each n. */\nfunction pick(seed: number, n: number, min: number, max: number): number {\n const v = (seed >>> (n * 3)) % 1000;\n return min + Math.round((v / 999) * (max - min));\n}\n\n/**\n * Art for a video with no poster, or whose poster did not load: a film strip\n * framing three storyboard frames and two caption lines, drawn from tokens.\n * The proportions come from the URL, so each video gets its own and keeps it.\n */\nfunction PosterArt({ url, source }: Readonly<{ url: string; source: ReactNode }>) {\n const seed = seedOf(url);\n const holes = Array.from({ length: 16 }, (_, i) => i * 20 + 6);\n const frames = [0, 1, 2].map((i) => ({ x: 24 + i * 94, h: pick(seed, i, 44, 62) }));\n return (\n <span className=\"ods-chat-video-preview__art\" aria-hidden=\"true\">\n <svg\n viewBox=\"0 0 320 180\"\n preserveAspectRatio=\"xMidYMid slice\"\n width=\"100%\"\n height=\"100%\"\n aria-hidden=\"true\"\n >\n <rect className=\"ods-chat-video-preview__art-strip\" x=\"0\" y=\"0\" width=\"320\" height=\"16\" />\n <rect className=\"ods-chat-video-preview__art-strip\" x=\"0\" y=\"164\" width=\"320\" height=\"16\" />\n {holes.map((x) => (\n <g key={x}>\n <rect className=\"ods-chat-video-preview__art-hole\" x={x} y=\"5\" width=\"8\" height=\"6\" />\n <rect className=\"ods-chat-video-preview__art-hole\" x={x} y=\"169\" width=\"8\" height=\"6\" />\n </g>\n ))}\n {frames.map((f, i) => (\n <rect\n key={f.x}\n className={`ods-chat-video-preview__art-frame ods-chat-video-preview__art-frame--${i}`}\n x={f.x}\n y={90 - f.h / 2 - 8}\n width=\"84\"\n height={f.h}\n />\n ))}\n <rect\n className=\"ods-chat-video-preview__art-line\"\n x=\"24\"\n y=\"134\"\n width={pick(seed, 3, 120, 220)}\n height=\"5\"\n />\n <rect\n className=\"ods-chat-video-preview__art-line\"\n x=\"24\"\n y=\"145\"\n width={pick(seed, 4, 60, 150)}\n height=\"5\"\n />\n </svg>\n <span className=\"ods-chat-video-preview__art-label\">{source}</span>\n </span>\n );\n}\n\nfunction Player({ embed, title }: Readonly<{ embed: ChatVideoEmbed; title: string }>) {\n if (embed.provider === \"file\") {\n return (\n // biome-ignore lint/a11y/useMediaCaption: captions come with the source file, which the card does not own.\n <video\n className=\"ods-chat-video-preview__player\"\n src={embed.src}\n controls\n autoPlay\n playsInline\n />\n );\n }\n return (\n <iframe\n className=\"ods-chat-video-preview__player\"\n src={embed.src}\n title={title}\n allow=\"autoplay; encrypted-media; picture-in-picture; fullscreen\"\n allowFullScreen\n referrerPolicy=\"strict-origin-when-cross-origin\"\n />\n );\n}\n\n/**\n * A video a chat reply points to. Until it is played the card shows only the\n * poster, title and length: no player, and nothing from the video's site, is\n * loaded before the click. A URL with no known player links out instead.\n */\nexport const ChatVideoPreview = forwardRef<HTMLDivElement, ChatVideoPreviewProps>(\n function ChatVideoPreview(\n { url, title, thumbnail, duration, linkTarget = \"_blank\", className, ...rest },\n ref,\n ) {\n const [playing, setPlaying] = useState(false);\n // The poster that failed to load, if any: a new `thumbnail` is tried afresh.\n const [failedPoster, setFailedPoster] = useState<string | null>(null);\n const embed = videoEmbedOf(url);\n const label = typeof title === \"string\" ? title : \"video\";\n const source = embed ? PROVIDER_LABEL[embed.provider] : hostOf(url);\n const showImage = Boolean(thumbnail) && failedPoster !== thumbnail;\n\n // The art is always drawn; a poster that loads covers it. So a slow,\n // missing or broken poster still leaves something to look at.\n const poster = (\n <span className=\"ods-chat-video-preview__poster\">\n <PosterArt url={url} source={source} />\n {showImage && (\n <img\n className=\"ods-chat-video-preview__poster-img\"\n src={thumbnail}\n alt=\"\"\n onError={() => setFailedPoster(thumbnail ?? null)}\n />\n )}\n <span className=\"ods-chat-video-preview__play\">\n <PlayGlyph />\n </span>\n {duration && <span className=\"ods-chat-video-preview__duration\">{duration}</span>}\n </span>\n );\n\n let stage: ReactNode;\n if (embed && playing) {\n stage = <Player embed={embed} title={label} />;\n } else if (embed) {\n stage = (\n <button\n type=\"button\"\n className=\"ods-chat-video-preview__stage\"\n onClick={() => setPlaying(true)}\n aria-label={`Play ${label}`}\n >\n {poster}\n </button>\n );\n } else {\n stage = (\n <a\n className=\"ods-chat-video-preview__stage\"\n href={url}\n {...linkTargetProps(linkTarget)}\n aria-label={`Open ${label}`}\n >\n {poster}\n </a>\n );\n }\n\n return (\n <div\n {...rest}\n ref={ref}\n className={cn(\n \"ods-chat-video-preview\",\n playing && \"ods-chat-video-preview--playing\",\n className,\n )}\n >\n <div className=\"ods-chat-video-preview__frame\">{stage}</div>\n <div className=\"ods-chat-video-preview__meta\">\n <TruncatedText className=\"ods-chat-video-preview__title\">{title}</TruncatedText>\n <span className=\"ods-chat-video-preview__source\">\n {source}\n <a className=\"ods-chat-video-preview__open\" href={url} {...linkTargetProps(linkTarget)}>\n Open\n </a>\n </span>\n </div>\n </div>\n );\n },\n);\n\nChatVideoPreview.displayName = \"ChatVideoPreview\";\n","\"use client\";\n\nimport { type ComponentPropsWithoutRef, type ReactNode, useState } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport {\n AssistantAura,\n type AssistantAuraIntensity,\n type AssistantState,\n} from \"../AssistantAura/AssistantAura\";\nimport { AssistantOrb } from \"../AssistantOrb/AssistantOrb\";\nimport { ChatBubble } from \"../ChatBubble/ChatBubble\";\nimport { ChatComposer } from \"../ChatComposer/ChatComposer\";\nimport { ChatDocPreview } from \"../ChatDocPreview/ChatDocPreview\";\nimport { ChatFeedback, type ChatFeedbackRating } from \"../ChatFeedback/ChatFeedback\";\nimport {\n type ChatInputAnswer,\n type ChatInputField,\n ChatInputRequest,\n type ChatInputValues,\n} from \"../ChatInputRequest/ChatInputRequest\";\nimport { ChatPanel } from \"../ChatPanel/ChatPanel\";\nimport { type ChatSource, ChatSources } from \"../ChatSources/ChatSources\";\nimport { ChatSuggestions } from \"../ChatSuggestions/ChatSuggestions\";\nimport { ChatThinking } from \"../ChatThinking/ChatThinking\";\nimport { type ChatToolCall, ChatToolTrace } from \"../ChatToolTrace/ChatToolTrace\";\nimport { ChatVideoPreview } from \"../ChatVideoPreview/ChatVideoPreview\";\n\n/* ---------------------------------------------------------------------------\n * AssistantConversation — the assistant's conversation, one core for every\n * surface (DEV-575).\n *\n * The website's chat box (marketing `AssistantWidget`, every mode) and the\n * platform's copilot (`AssistantDock`) both render this: a header with the\n * living orb and what the assistant is doing, the thread (greeting, replies\n * with sources, doc / video / ask cards, tool steps, feedback), suggestions\n * until the first message, and a composer whose send button becomes Stop\n * while a reply is written — all inside the aura, which moves with the state.\n *\n * Presentational and controlled: the caller owns the conversation and the\n * connection and passes `messages`. Surfaces add their own header controls\n * (`actions`) and context (`context`).\n * ------------------------------------------------------------------------- */\n\n/** A card the assistant shows with a reply (gateway §3.3, DEV-561 shapes). */\nexport type AssistantBlock =\n | { type: \"doc\"; url: string; title: string; path?: string[]; excerpt?: string }\n | { type: \"video\"; url: string; title: string; thumbnail?: string; duration?: string }\n | {\n type: \"ask\";\n askId: string;\n prompt: string;\n description?: string;\n fields: ChatInputField[];\n skippable?: boolean;\n /** Set once answered or skipped: the card shows the answer, read-only. */\n answer?: ChatInputAnswer | null;\n };\n\nexport interface AssistantMessage {\n id: string;\n role: \"user\" | \"assistant\";\n /** The text so far (it grows while `streaming`). A ReactNode for rendered markdown. */\n content: ReactNode;\n /** The reply is still being written. */\n streaming?: boolean;\n /** Progress while no text has arrived yet, e.g. \"Searching the docs…\". */\n status?: string;\n sources?: ChatSource[];\n blocks?: AssistantBlock[];\n /** Tools the assistant used for this reply (the platform's copilot). */\n steps?: ChatToolCall[];\n /** A short line under the reply: \"Stopped\", an error. */\n note?: ReactNode;\n /** How the turn ended, once it has: the orb and aura show it until the next turn. */\n outcome?: \"done\" | \"stopped\" | \"error\";\n rating?: ChatFeedbackRating | null;\n}\n\n/** Conditions outside the thread that decide the state. */\nexport interface AssistantStateFlags {\n /** A problem is shown above the composer (connection lost, rate limited). */\n error?: boolean;\n /** The assistant can't answer at all. */\n offline?: boolean;\n}\n\n/**\n * What the assistant is doing, from the conversation:\n * - while busy: writing (`speaking`), running a tool step (`processing`), or\n * working before the first words (`thinking`);\n * - otherwise: `offline`, a shown `error`, the person typing (`listening`),\n * how the last turn ended (its `outcome`: `done`, `stopped`, `error`), or\n * nothing (`idle`).\n */\nexport function assistantStateOf(\n messages: readonly AssistantMessage[],\n busy: boolean,\n typing = false,\n flags: AssistantStateFlags = {},\n): AssistantState {\n if (flags.offline) return \"offline\";\n const last = messages[messages.length - 1];\n const reply = last?.role === \"assistant\" ? last : undefined;\n if (busy) {\n if (reply?.content) return \"speaking\";\n if (reply?.steps?.some((s) => s.status === \"running\")) return \"processing\";\n return \"thinking\";\n }\n if (flags.error) return \"error\";\n if (typing) return \"listening\";\n return reply?.outcome ?? \"idle\";\n}\n\n/**\n * The status line under the name; empty falls back to the subtitle. A finished\n * reply says nothing: the reply itself shows it is done, and \"Done\" would stay\n * under the name until the next question.\n */\nconst STATE_LINE: Record<AssistantState, string> = {\n idle: \"\",\n listening: \"\",\n thinking: \"Thinking…\",\n processing: \"Working…\",\n speaking: \"Writing…\",\n done: \"\",\n stopped: \"Stopped\",\n error: \"Couldn't answer\",\n offline: \"Offline\",\n};\n\n/** States whose status line is coloured: the working ones accent, the error red. */\nconst STATUS_TONE: Partial<Record<AssistantState, \"active\" | \"error\">> = {\n thinking: \"active\",\n processing: \"active\",\n speaking: \"active\",\n error: \"error\",\n};\n\nexport interface AssistantConversationProps\n extends Omit<ComponentPropsWithoutRef<\"div\">, \"title\" | \"onSubmit\"> {\n /** The assistant's name. Default \"Ova\". */\n name?: ReactNode;\n /** The line under the name when nothing is happening. */\n subtitle?: ReactNode;\n /** Replaces the orb's cube (an image, a letter). */\n avatar?: ReactNode;\n /** Header controls on the right (close, reset, focus, pin…). */\n actions?: ReactNode;\n /** A strip under the header: what the assistant can see (the page, the flow…). */\n context?: ReactNode;\n /** Aura around the conversation. Default `normal`; `off` for a plain hairline. */\n aura?: AssistantAuraIntensity;\n /** Hide the header (a surface that draws its own). */\n hideHeader?: boolean;\n /**\n * Overrides the state worked out from the conversation (`assistantStateOf`),\n * e.g. `offline`, or `done` after an action the caller ran.\n */\n state?: AssistantState;\n\n greeting?: ReactNode;\n suggestions?: string[];\n messages: AssistantMessage[];\n /** Shown instead of the thread and composer (e.g. the contact form). */\n replacement?: ReactNode;\n\n busy?: boolean;\n onSend?: (text: string) => void;\n onStop?: () => void;\n onRate?: (messageId: string, rating: ChatFeedbackRating | null) => void;\n onAnswer?: (askId: string, values: ChatInputValues, text?: string) => void;\n onSkipAsk?: (askId: string) => void;\n\n placeholder?: string;\n maxLength?: number;\n composerDisabled?: boolean;\n /** A problem above the composer (rate limited, connection lost). */\n error?: ReactNode;\n /** The small print under the composer. */\n notice?: ReactNode;\n /** Optional id for the name, so a surrounding dialog/region can be labelled by it. */\n nameId?: string;\n}\n\n/** A small square header control (close, new chat, focus, pin…), shared by every surface. */\nexport function AssistantHeaderButton({\n label,\n children,\n pressed,\n className,\n type = \"button\",\n ...rest\n}: Omit<ComponentPropsWithoutRef<\"button\">, \"aria-label\"> & { label: string; pressed?: boolean }) {\n return (\n <button\n {...rest}\n type={type}\n aria-label={label}\n title={label}\n aria-pressed={pressed}\n className={cn(\"ods-assistant__icon-btn\", className)}\n >\n {children}\n </button>\n );\n}\n\nfunction Block({\n block,\n busy,\n onAnswer,\n onSkipAsk,\n}: {\n block: AssistantBlock;\n busy: boolean;\n onAnswer?: AssistantConversationProps[\"onAnswer\"];\n onSkipAsk?: AssistantConversationProps[\"onSkipAsk\"];\n}) {\n if (block.type === \"doc\") {\n return (\n <ChatDocPreview\n url={block.url}\n title={block.title}\n path={block.path}\n excerpt={block.excerpt}\n />\n );\n }\n if (block.type === \"video\") {\n return (\n <ChatVideoPreview\n url={block.url}\n title={block.title}\n thumbnail={block.thumbnail}\n duration={block.duration}\n />\n );\n }\n return (\n <ChatInputRequest\n prompt={block.prompt}\n description={block.description}\n fields={block.fields}\n answer={block.answer ?? null}\n submitting={busy}\n onSubmit={(values, text) => onAnswer?.(block.askId, values, text)}\n {...(block.skippable && onSkipAsk ? { onSkip: () => onSkipAsk(block.askId) } : {})}\n />\n );\n}\n\nexport function AssistantConversation({\n name = \"Ova\",\n subtitle = \"Octaviaflow assistant\",\n avatar,\n actions,\n context,\n aura = \"normal\",\n hideHeader = false,\n state: stateProp,\n greeting,\n suggestions,\n messages,\n replacement,\n busy = false,\n onSend,\n onStop,\n onRate,\n onAnswer,\n onSkipAsk,\n placeholder = \"Ask anything…\",\n maxLength,\n composerDisabled = false,\n error,\n notice,\n nameId,\n className,\n ...rest\n}: AssistantConversationProps) {\n const [typing, setTyping] = useState(false);\n const state = stateProp ?? assistantStateOf(messages, busy, typing, { error: Boolean(error) });\n const statusLine = STATE_LINE[state] || subtitle;\n const tone = STATUS_TONE[state];\n\n const header = hideHeader ? undefined : (\n <div className=\"ods-assistant__header\">\n <AssistantOrb state={state} size=\"md\">\n {avatar}\n </AssistantOrb>\n <div className=\"ods-assistant__heading\">\n <span id={nameId} className=\"ods-assistant__name\">\n {name}\n </span>\n <span\n className={cn(\"ods-assistant__status\", tone && `ods-assistant__status--${tone}`)}\n aria-live=\"polite\"\n >\n {statusLine}\n </span>\n </div>\n {actions && <div className=\"ods-assistant__actions\">{actions}</div>}\n </div>\n );\n\n const thread = (\n <>\n {greeting && (\n <ChatBubble variant=\"bot\" hideAvatar>\n {greeting}\n </ChatBubble>\n )}\n {messages.map((m) =>\n m.role === \"user\" ? (\n <ChatBubble key={m.id} variant=\"user\" hideAvatar>\n {m.content}\n </ChatBubble>\n ) : (\n <div key={m.id} className=\"ods-assistant__reply\">\n {m.steps && m.steps.length > 0 && <ChatToolTrace calls={m.steps} />}\n <ChatBubble variant=\"bot\" hideAvatar>\n {m.content ? (\n // Plain text keeps its line breaks; rendered content (markdown,\n // lists) is block content and lays out its own lines.\n typeof m.content === \"string\" ? (\n <span\n className={cn(\n \"ods-assistant__text\",\n m.streaming && \"ods-assistant__text--streaming\",\n )}\n >\n {m.content}\n </span>\n ) : (\n <div\n className={cn(\n \"ods-assistant__text\",\n \"ods-assistant__text--rich\",\n m.streaming && \"ods-assistant__text--streaming\",\n )}\n >\n {m.content}\n </div>\n )\n ) : (\n <ChatThinking variant=\"shimmer\" label={m.status || \"Thinking…\"} size=\"sm\" />\n )}\n </ChatBubble>\n {m.blocks && m.blocks.length > 0 && (\n <div className=\"ods-assistant__blocks\">\n {m.blocks.map((b, i) => (\n <Block\n key={b.type === \"ask\" ? b.askId : `${b.type}:${b.url}:${i}`}\n block={b}\n busy={busy}\n onAnswer={onAnswer}\n onSkipAsk={onSkipAsk}\n />\n ))}\n </div>\n )}\n {m.sources && m.sources.length > 0 && (\n <ChatSources\n sources={m.sources}\n display=\"chips\"\n label=\"Sources\"\n linkTarget=\"_blank\"\n />\n )}\n {(m.note || (!m.streaming && onRate && m.content)) && (\n <div className=\"ods-assistant__meta\">\n {m.note ? <span className=\"ods-assistant__note\">{m.note}</span> : <span />}\n {!m.streaming && onRate && m.content && (\n <ChatFeedback\n size=\"sm\"\n rating={m.rating ?? null}\n onRate={(r) => onRate(m.id, r)}\n />\n )}\n </div>\n )}\n </div>\n ),\n )}\n </>\n );\n\n const showSuggestions = !replacement && messages.length === 0 && (suggestions?.length ?? 0) > 0;\n\n return (\n <AssistantAura\n {...rest}\n state={state}\n intensity={aura}\n className={cn(\"ods-assistant\", className)}\n >\n {replacement ? (\n <div className=\"ods-assistant__replacement\">\n {header}\n {context && <div className=\"ods-assistant__context\">{context}</div>}\n <div className=\"ods-assistant__replacement-body\">{replacement}</div>\n </div>\n ) : (\n <ChatPanel\n header={\n header || context ? (\n <>\n {header}\n {context && <div className=\"ods-assistant__context\">{context}</div>}\n </>\n ) : undefined\n }\n suggestions={\n showSuggestions ? (\n <ChatSuggestions\n items={suggestions ?? []}\n onSelect={(v) => onSend?.(v)}\n size=\"sm\"\n layout=\"wrap\"\n disabled={busy}\n />\n ) : undefined\n }\n composer={\n <div className=\"ods-assistant__composer\">\n {error && (\n <div className=\"ods-assistant__error\" role=\"alert\">\n {error}\n </div>\n )}\n <ChatComposer\n onSend={(v) => {\n setTyping(false);\n onSend?.(v);\n }}\n onChange={(v) => setTyping(v.trim().length > 0)}\n onBlur={() => setTyping(false)}\n {...(onStop ? { onStop } : {})}\n placeholder={placeholder}\n sending={busy}\n disabled={composerDisabled}\n maxRows={5}\n {...(maxLength ? { maxLength } : {})}\n />\n {notice && <div className=\"ods-assistant__notice\">{notice}</div>}\n </div>\n }\n >\n {thread}\n </ChatPanel>\n )}\n </AssistantAura>\n );\n}\n","\"use client\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n type ReactNode,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * CountUp — animated numeric counter.\n *\n * For ETL / orchestration dashboards: rows processed, runs completed,\n * MRR, throughput totals. Pairs naturally with `Sparkline` and `Stat`.\n *\n * The animation is implementation-light — a `requestAnimationFrame` loop\n * with a configurable easing function. Skips entirely when the user has\n * `prefers-reduced-motion` enabled or `disableAnimation` is true.\n *\n * Re-runs the tween whenever `value` changes, starting from the previous\n * displayed value (so consecutive updates flow smoothly without a reset\n * to 0).\n * ------------------------------------------------------------------------- */\n\nexport type Easing = (t: number) => number;\n\nexport interface CountUpProps\n extends Omit<\n ComponentPropsWithoutRef<\"span\">,\n // HTMLSpanElement carries a native `prefix` attribute (string) — omit\n // it so our `ReactNode` prefix slot can coexist.\n \"children\" | \"onChange\" | \"prefix\"\n > {\n /** Target value. */\n value: number;\n /** Starting value on FIRST mount. Default 0. */\n from?: number;\n /** Tween duration in ms. Default 800. */\n duration?: number;\n /** Easing function. Default `easeOutCubic`. */\n easing?: Easing;\n /** Decimal places when no `formatValue` is supplied. Default 0. */\n decimals?: number;\n /** Custom formatter — wins over `decimals`. */\n formatValue?: (value: number) => ReactNode;\n /** Inline content before the number. */\n prefix?: ReactNode;\n /** Inline content after the number (e.g. \"%\"). */\n suffix?: ReactNode;\n /** Delay the tween start in ms. */\n delay?: number;\n /**\n * Skip the animation and render `value` immediately. Reads as a\n * \"static mode\" — useful for SSR snapshots or print views.\n */\n disableAnimation?: boolean;\n /** Fires once when the tween settles on the target value. */\n onComplete?: () => void;\n}\n\n/* ---------------------------------------------------------------------------\n * Easings\n * ------------------------------------------------------------------------- */\n\nexport const easeLinear: Easing = (t) => t;\nexport const easeOutCubic: Easing = (t) => 1 - (1 - t) ** 3;\nexport const easeOutQuart: Easing = (t) => 1 - (1 - t) ** 4;\nexport const easeOutExpo: Easing = (t) => (t === 1 ? 1 : 1 - 2 ** (-10 * t));\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const CountUp = forwardRef<HTMLSpanElement, CountUpProps>(function CountUp(\n {\n value,\n from = 0,\n duration = 800,\n easing = easeOutCubic,\n decimals = 0,\n formatValue,\n prefix,\n suffix,\n delay = 0,\n disableAnimation = false,\n onComplete,\n className,\n ...rest\n },\n ref,\n) {\n // The current rendered number. Initialise to `from` on first mount;\n // subsequent renders tween from the previous displayed value.\n const [n, setN] = useState<number>(disableAnimation ? value : from);\n const lastRendered = useRef<number>(disableAnimation ? value : from);\n\n useEffect(() => {\n // Respect prefers-reduced-motion — snap to target without animation.\n const reduced =\n typeof window !== \"undefined\" &&\n window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches;\n\n if (disableAnimation || reduced) {\n setN(value);\n lastRendered.current = value;\n onComplete?.();\n return;\n }\n\n const startValue = lastRendered.current;\n const delta = value - startValue;\n if (delta === 0) return;\n\n let raf: number | null = null;\n let timeoutId: number | null = null;\n let startTime: number | null = null;\n let cancelled = false;\n\n const tick = (ts: number) => {\n if (cancelled) return;\n if (startTime === null) startTime = ts;\n const t = Math.min(1, (ts - startTime) / Math.max(1, duration));\n const eased = easing(t);\n const current = startValue + delta * eased;\n setN(current);\n lastRendered.current = current;\n if (t < 1) {\n raf = requestAnimationFrame(tick);\n } else {\n lastRendered.current = value;\n setN(value);\n onComplete?.();\n }\n };\n\n const start = () => {\n raf = requestAnimationFrame(tick);\n };\n\n if (delay > 0) {\n timeoutId = window.setTimeout(start, delay);\n } else {\n start();\n }\n\n return () => {\n cancelled = true;\n if (raf !== null) cancelAnimationFrame(raf);\n if (timeoutId !== null) window.clearTimeout(timeoutId);\n };\n // We intentionally exclude `easing` from deps — it should be a\n // stable function reference. If the consumer changes easing\n // mid-flight, we just pick it up on the next value change.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [value, duration, delay, disableAnimation]);\n\n const display = formatValue ? formatValue(n) : n.toFixed(decimals);\n\n return (\n <span\n {...rest}\n ref={ref}\n className={cn(\"ods-count-up\", className)}\n // aria-live so screen readers announce updates without a stale\n // value lingering. Polite (default for \"status\") avoids\n // interrupting other announcements.\n aria-live=\"polite\"\n aria-atomic=\"true\"\n >\n {prefix}\n {display}\n {suffix}\n </span>\n );\n});\n\nCountUp.displayName = \"CountUp\";\n","\"use client\";\nimport type { RefObject } from \"react\";\nimport {\n type KeyboardEvent as ReactKeyboardEvent,\n type ReactNode,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\n/* ---------------------------------------------------------------------------\n * useTextareaCommands — inline `/command` palette for a textarea.\n *\n * const cmd = useTextareaCommands({\n * textareaRef,\n * value,\n * onChange,\n * commands: [\n * { id: \"today\", label: \"Today\", insert: () => new Date().toDateString() },\n * { id: \"summary\", label: \"AI Summary\", insert: \"{{ai.summary}}\" },\n * ],\n * trigger: \"/\", // default\n * openOnEmptyTrigger: true,\n * });\n *\n * <Textarea ... commands={cmd.props} /> // or wire manually\n *\n * The hook owns: trigger detection, filtering, keyboard nav, caret-aware\n * insertion. The consumer / Textarea owns rendering the popover.\n * ------------------------------------------------------------------------- */\n\nexport interface TextareaCommand {\n id: string;\n label: ReactNode;\n description?: ReactNode;\n icon?: ReactNode;\n /** Text to insert at the caret. Can be a string OR a function that\n * receives the live query and returns the string — useful for\n * commands that consume the typed query (e.g. `/mention bob` →\n * `@bob`). */\n insert: string | ((query: string) => string);\n /** Extra keywords to match against the typed query in addition to\n * the rendered `label` (when label is a string) and `description`. */\n keywords?: string[];\n}\n\nexport interface UseTextareaCommandsOptions {\n textareaRef: RefObject<HTMLTextAreaElement | null>;\n /** Controlled value — pass the same string you pass to the textarea. */\n value: string;\n /** Setter — receives the new full value after insertion. */\n onChange: (next: string) => void;\n commands: TextareaCommand[];\n /** Trigger character. Default `\"/\"`. */\n trigger?: string;\n /** Open the palette as soon as the trigger is typed (even with no\n * query). Default `true`. Set `false` if you want consumers to type\n * at least one character to open. */\n openOnEmptyTrigger?: boolean;\n /** Maximum visible items in the filtered result list. Default 8. */\n maxItems?: number;\n}\n\nexport interface UseTextareaCommandsReturn {\n /** Whether the palette is currently open. */\n isOpen: boolean;\n /** Query typed after the trigger (without the trigger character). */\n query: string;\n /** Highlighted item index (0-based). */\n activeIndex: number;\n /** Filtered + capped list of matching commands. */\n items: TextareaCommand[];\n\n /** Keydown handler — wire to the textarea's `onKeyDown`. Returns\n * `true` if the key was consumed (so the consumer can stop). */\n onKeyDown: (e: ReactKeyboardEvent<HTMLTextAreaElement>) => boolean;\n /** Force-close the palette (e.g. on textarea blur). */\n dismiss: () => void;\n /** Commit the supplied command — inserts its text at the trigger\n * position and consumes the trigger + query. */\n commit: (cmd: TextareaCommand) => void;\n\n /** Pixel position of the caret at the moment the palette opened.\n * Use to anchor the popover in your own UI. */\n caretRect: DOMRect | null;\n}\n\n/* ---------------------------------------------------------------------------\n * Helpers\n * ------------------------------------------------------------------------- */\n\n/** Find the nearest trigger character behind the caret (within the\n * current line) and return the index + query string. Returns `null`\n * when no open trigger is in scope (e.g. there's whitespace between\n * the trigger and the caret, or the caret is mid-word that doesn't\n * start with the trigger). */\nfunction findOpenTrigger(\n value: string,\n caret: number,\n trigger: string,\n): { triggerIndex: number; query: string } | null {\n // Walk backwards from the caret looking for the trigger char OR a\n // whitespace boundary. Whitespace closes the trigger window.\n let i = caret - 1;\n while (i >= 0) {\n const ch = value[i];\n if (ch === \"\\n\" || ch === \" \" || ch === \"\\t\") return null;\n if (value.startsWith(trigger, i)) {\n // Trigger must be at the start of input OR preceded by whitespace\n // / newline. Stops \"https://\" from opening a command palette.\n const before = i === 0 ? \"\" : value[i - 1];\n if (i === 0 || before === \" \" || before === \"\\n\" || before === \"\\t\") {\n return {\n triggerIndex: i,\n query: value.slice(i + trigger.length, caret),\n };\n }\n return null;\n }\n i--;\n }\n return null;\n}\n\n/** Approximate caret-pixel-rect for a textarea using a mirror div.\n * Browsers don't expose the caret position natively for textareas. */\nfunction getCaretRect(textarea: HTMLTextAreaElement, caret: number): DOMRect | null {\n if (typeof document === \"undefined\") return null;\n const mirror = document.createElement(\"div\");\n const styles = window.getComputedStyle(textarea);\n // Copy the visual properties that affect line-wrapping + glyph metrics.\n for (const prop of [\n \"boxSizing\",\n \"width\",\n \"fontFamily\",\n \"fontSize\",\n \"fontWeight\",\n \"fontStyle\",\n \"letterSpacing\",\n \"lineHeight\",\n \"paddingTop\",\n \"paddingRight\",\n \"paddingBottom\",\n \"paddingLeft\",\n \"borderTopWidth\",\n \"borderRightWidth\",\n \"borderBottomWidth\",\n \"borderLeftWidth\",\n \"textTransform\",\n \"wordSpacing\",\n \"tabSize\",\n \"whiteSpace\",\n ] as const) {\n (mirror.style as unknown as Record<string, string>)[prop] = styles[prop];\n }\n mirror.style.position = \"absolute\";\n mirror.style.visibility = \"hidden\";\n mirror.style.overflow = \"hidden\";\n mirror.style.top = \"0\";\n mirror.style.left = \"0\";\n mirror.style.whiteSpace = \"pre-wrap\";\n mirror.style.wordWrap = \"break-word\";\n mirror.textContent = textarea.value.slice(0, caret);\n const marker = document.createElement(\"span\");\n marker.textContent = \"​\"; // zero-width space → measurable\n mirror.appendChild(marker);\n document.body.appendChild(mirror);\n\n const taRect = textarea.getBoundingClientRect();\n const markerRect = marker.getBoundingClientRect();\n const mirrorRect = mirror.getBoundingClientRect();\n const x = taRect.left + (markerRect.left - mirrorRect.left) - textarea.scrollLeft;\n const y = taRect.top + (markerRect.top - mirrorRect.top) - textarea.scrollTop;\n const out = new DOMRect(x, y, 0, markerRect.height || 16);\n document.body.removeChild(mirror);\n return out;\n}\n\n/* ---------------------------------------------------------------------------\n * Hook\n * ------------------------------------------------------------------------- */\n\nexport function useTextareaCommands({\n textareaRef,\n value,\n onChange,\n commands,\n trigger = \"/\",\n openOnEmptyTrigger = true,\n maxItems = 8,\n}: UseTextareaCommandsOptions): UseTextareaCommandsReturn {\n const [isOpen, setIsOpen] = useState(false);\n const [query, setQuery] = useState(\"\");\n const [activeIndex, setActiveIndex] = useState(0);\n const [triggerIndex, setTriggerIndex] = useState<number | null>(null);\n const [caretRect, setCaretRect] = useState<DOMRect | null>(null);\n // Tracks the (value, caret) snapshot at the moment the user dismissed\n // the palette. The trigger-detect effect skips re-opening when the\n // current state still matches — without this guard, Escape would\n // dismiss but the very next effect run would re-open the palette\n // because the trigger char is still in scope.\n const dismissedAtRef = useRef<{ value: string; caret: number } | null>(null);\n\n /* ── Filter the command list against the current query ── */\n const items = useMemo(() => {\n const q = query.trim().toLowerCase();\n if (!q) return commands.slice(0, maxItems);\n return commands\n .filter((c) => {\n const hay = [\n typeof c.label === \"string\" ? c.label : \"\",\n typeof c.description === \"string\" ? c.description : \"\",\n c.id,\n ...(c.keywords ?? []),\n ]\n .join(\" \")\n .toLowerCase();\n return hay.includes(q);\n })\n .slice(0, maxItems);\n }, [commands, query, maxItems]);\n\n /* ── Re-evaluate the trigger window on every value or caret change ── */\n useEffect(() => {\n const ta = textareaRef.current;\n if (!ta) return;\n const caret = ta.selectionStart ?? 0;\n // If the user dismissed at this exact (value, caret), don't reopen.\n const dismissedAt = dismissedAtRef.current;\n if (dismissedAt && dismissedAt.value === value && dismissedAt.caret === caret) {\n return;\n }\n const found = findOpenTrigger(value, caret, trigger);\n if (!found) {\n if (isOpen) setIsOpen(false);\n setTriggerIndex(null);\n return;\n }\n // Clear the dismissed snapshot once the user moves out of it —\n // future trigger events are real, not stale.\n if (dismissedAt) dismissedAtRef.current = null;\n // Open if the trigger is in scope AND either we already have a\n // query OR `openOnEmptyTrigger` allows opening on the bare trigger.\n if (found.query.length > 0 || openOnEmptyTrigger) {\n setQuery(found.query);\n setTriggerIndex(found.triggerIndex);\n setIsOpen(true);\n // Reset highlight when the query changes — keeps it pinned to\n // the top match.\n setActiveIndex(0);\n setCaretRect(getCaretRect(ta, caret));\n }\n }, [value, trigger, openOnEmptyTrigger, isOpen, textareaRef]);\n\n /* ── Commit a chosen command ── */\n const commit = useCallback(\n (cmd: TextareaCommand) => {\n const ta = textareaRef.current;\n if (!ta || triggerIndex == null) return;\n const insertText = typeof cmd.insert === \"function\" ? cmd.insert(query) : cmd.insert;\n const caret = ta.selectionStart ?? value.length;\n const before = value.slice(0, triggerIndex);\n const after = value.slice(caret);\n const next = `${before}${insertText}${after}`;\n // Snapshot the post-commit caret position so the trigger-detect\n // effect doesn't immediately reopen against the original\n // (unchanged) value when the consumer's onChange is async or\n // a no-op (e.g. in tests).\n dismissedAtRef.current = {\n value,\n caret,\n };\n onChange(next);\n setIsOpen(false);\n setTriggerIndex(null);\n // Restore caret to the end of the inserted text on the next frame.\n requestAnimationFrame(() => {\n const pos = before.length + insertText.length;\n ta.focus();\n ta.setSelectionRange(pos, pos);\n });\n },\n [textareaRef, triggerIndex, query, value, onChange],\n );\n\n const dismiss = useCallback(() => {\n const ta = textareaRef.current;\n dismissedAtRef.current = {\n value,\n caret: ta?.selectionStart ?? value.length,\n };\n setIsOpen(false);\n setTriggerIndex(null);\n }, [textareaRef, value]);\n\n /* ── Keyboard nav while the palette is open ── */\n const onKeyDown = useCallback(\n (e: ReactKeyboardEvent<HTMLTextAreaElement>): boolean => {\n if (!isOpen) return false;\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setActiveIndex((i) => Math.min(items.length - 1, i + 1));\n return true;\n }\n if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setActiveIndex((i) => Math.max(0, i - 1));\n return true;\n }\n if (e.key === \"Enter\" || e.key === \"Tab\") {\n const pick = items[activeIndex];\n if (pick) {\n e.preventDefault();\n commit(pick);\n return true;\n }\n }\n if (e.key === \"Escape\") {\n e.preventDefault();\n dismiss();\n return true;\n }\n return false;\n },\n [isOpen, items, activeIndex, commit, dismiss],\n );\n\n return {\n isOpen,\n query,\n activeIndex,\n items,\n onKeyDown,\n dismiss,\n commit,\n caretRect,\n };\n}\n","\"use client\";\nimport type { RefObject } from \"react\";\nimport { useCallback, useEffect, useState } from \"react\";\n\n/* ---------------------------------------------------------------------------\n * useTextareaSelection — selection state + clipboard / wrap helpers.\n *\n * const sel = useTextareaSelection({ textareaRef, value, onChange });\n *\n * if (sel.active) {\n * // user has highlighted text — render a floating toolbar\n * sel.copy(); // copies selection to clipboard\n * sel.cut(); // copies + deletes\n * sel.wrap(\"**\",\"**\"); // selection becomes **selection**\n * sel.replace(\"...\"); // replace the selection with a literal string\n * }\n *\n * The hook tracks the selection across `selectionchange` events (more\n * reliable than `select` for shift-arrow nav). Returns a pixel rect for\n * the SELECTION so callers can anchor a floating toolbar above it.\n * ------------------------------------------------------------------------- */\n\nexport interface UseTextareaSelectionOptions {\n textareaRef: RefObject<HTMLTextAreaElement | null>;\n /** Current textarea value. */\n value: string;\n /** Setter — called when `cut`/`wrap`/`replace` mutate the text. */\n onChange: (next: string) => void;\n}\n\nexport interface UseTextareaSelectionReturn {\n /** True when there's a non-empty selection in the focused textarea. */\n active: boolean;\n /** Selected text. Empty string when `active` is false. */\n text: string;\n /** Character offsets. */\n start: number;\n end: number;\n /** Approximate pixel rect of the selection — anchor a floating\n * toolbar above this (`top - toolbar.height - 4`). Null when no\n * active selection. */\n rect: DOMRect | null;\n\n /** Copy the current selection to the clipboard. Resolves with `true`\n * on success. */\n copy: () => Promise<boolean>;\n /** Copy + delete (= cut). Resolves `true` on success. */\n cut: () => Promise<boolean>;\n /** Wrap the selection with `open` / `close` strings. Selection\n * expands to include the wrappers. */\n wrap: (open: string, close?: string) => void;\n /** Replace the selection with a literal string. Caret lands at the\n * end of the inserted text. */\n replace: (text: string) => void;\n}\n\n/* ---------------------------------------------------------------------------\n * Helpers — selection-rect via a measured mirror div (same recipe as\n * useTextareaCommands' caret-rect helper, expanded to cover a range).\n * ------------------------------------------------------------------------- */\n\nfunction getSelectionRect(\n textarea: HTMLTextAreaElement,\n start: number,\n end: number,\n): DOMRect | null {\n if (typeof document === \"undefined\") return null;\n if (start === end) return null;\n const mirror = document.createElement(\"div\");\n const styles = window.getComputedStyle(textarea);\n for (const prop of [\n \"boxSizing\",\n \"width\",\n \"fontFamily\",\n \"fontSize\",\n \"fontWeight\",\n \"fontStyle\",\n \"letterSpacing\",\n \"lineHeight\",\n \"paddingTop\",\n \"paddingRight\",\n \"paddingBottom\",\n \"paddingLeft\",\n \"borderTopWidth\",\n \"borderRightWidth\",\n \"borderBottomWidth\",\n \"borderLeftWidth\",\n \"textTransform\",\n \"wordSpacing\",\n \"tabSize\",\n \"whiteSpace\",\n ] as const) {\n (mirror.style as unknown as Record<string, string>)[prop] = styles[prop];\n }\n mirror.style.position = \"absolute\";\n mirror.style.visibility = \"hidden\";\n mirror.style.overflow = \"hidden\";\n mirror.style.top = \"0\";\n mirror.style.left = \"0\";\n mirror.style.whiteSpace = \"pre-wrap\";\n mirror.style.wordWrap = \"break-word\";\n\n const pre = document.createTextNode(textarea.value.slice(0, start));\n const range = document.createElement(\"span\");\n range.textContent = textarea.value.slice(start, end) || \"​\";\n const post = document.createTextNode(textarea.value.slice(end));\n\n mirror.appendChild(pre);\n mirror.appendChild(range);\n mirror.appendChild(post);\n document.body.appendChild(mirror);\n\n const taRect = textarea.getBoundingClientRect();\n const rangeRect = range.getBoundingClientRect();\n const mirrorRect = mirror.getBoundingClientRect();\n const out = new DOMRect(\n taRect.left + (rangeRect.left - mirrorRect.left) - textarea.scrollLeft,\n taRect.top + (rangeRect.top - mirrorRect.top) - textarea.scrollTop,\n rangeRect.width,\n rangeRect.height,\n );\n document.body.removeChild(mirror);\n return out;\n}\n\n/* ---------------------------------------------------------------------------\n * Hook\n * ------------------------------------------------------------------------- */\n\nexport function useTextareaSelection({\n textareaRef,\n value,\n onChange,\n}: UseTextareaSelectionOptions): UseTextareaSelectionReturn {\n const [start, setStart] = useState(0);\n const [end, setEnd] = useState(0);\n const [rect, setRect] = useState<DOMRect | null>(null);\n\n /* ── Subscribe to selectionchange (fires on caret moves + drags) ── */\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n const handler = () => {\n const ta = textareaRef.current;\n if (!ta || document.activeElement !== ta) {\n setStart(0);\n setEnd(0);\n setRect(null);\n return;\n }\n const s = ta.selectionStart ?? 0;\n const e = ta.selectionEnd ?? 0;\n setStart(s);\n setEnd(e);\n setRect(s !== e ? getSelectionRect(ta, s, e) : null);\n };\n document.addEventListener(\"selectionchange\", handler);\n return () => document.removeEventListener(\"selectionchange\", handler);\n }, [textareaRef]);\n\n const active = start !== end;\n const text = active ? value.slice(start, end) : \"\";\n\n const writeToClipboard = useCallback(async (str: string): Promise<boolean> => {\n try {\n if (typeof navigator !== \"undefined\" && navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(str);\n return true;\n }\n } catch {\n /* fall through to execCommand fallback */\n }\n // Legacy fallback for permission-denied environments. Uses an\n // off-screen textarea so we don't disturb the user's selection.\n try {\n const tmp = document.createElement(\"textarea\");\n tmp.value = str;\n tmp.style.position = \"fixed\";\n tmp.style.left = \"-9999px\";\n document.body.appendChild(tmp);\n tmp.select();\n const ok = document.execCommand(\"copy\");\n document.body.removeChild(tmp);\n return ok;\n } catch {\n return false;\n }\n }, []);\n\n const copy = useCallback(async () => {\n if (!active) return false;\n return writeToClipboard(text);\n }, [active, text, writeToClipboard]);\n\n const replace = useCallback(\n (str: string) => {\n const ta = textareaRef.current;\n if (!ta) return;\n const next = value.slice(0, start) + str + value.slice(end);\n onChange(next);\n requestAnimationFrame(() => {\n ta.focus();\n const caret = start + str.length;\n ta.setSelectionRange(caret, caret);\n });\n },\n [textareaRef, value, start, end, onChange],\n );\n\n const cut = useCallback(async () => {\n if (!active) return false;\n const ok = await writeToClipboard(text);\n if (ok) replace(\"\");\n return ok;\n }, [active, text, writeToClipboard, replace]);\n\n const wrap = useCallback(\n (open: string, close?: string) => {\n const ta = textareaRef.current;\n if (!ta) return;\n const closing = close ?? open;\n const before = value.slice(0, start);\n const sel = value.slice(start, end);\n const after = value.slice(end);\n const next = `${before}${open}${sel}${closing}${after}`;\n onChange(next);\n requestAnimationFrame(() => {\n ta.focus();\n // Re-select the wrapped content (including the wrappers) so\n // the user sees the result and can keep working.\n const newStart = start;\n const newEnd = end + open.length + closing.length;\n ta.setSelectionRange(newStart, newEnd);\n });\n },\n [textareaRef, value, start, end, onChange],\n );\n\n return {\n active,\n text,\n start,\n end,\n rect,\n copy,\n cut,\n wrap,\n replace,\n };\n}\n","\"use client\";\nimport {\n CodeIcon,\n HeadingIcon,\n ListBulletedIcon,\n ListNumberedIcon,\n QuotesIcon,\n RedoIcon,\n TextBoldIcon,\n TextItalicIcon,\n TextLinkIcon,\n TextStrikethroughIcon,\n UndoIcon,\n} from \"@octaviaflow/icons\";\nimport type { RefObject } from \"react\";\nimport { type ReactNode, useCallback, useMemo, useRef } from \"react\";\n\n/* ---------------------------------------------------------------------------\n * useTextareaTools — toolbar tools + always-on editor helpers.\n *\n * The \"third tier\" of the textarea editor section, sitting alongside:\n * - `useTextareaCommands` (inline `/command` palette)\n * - `useTextareaSelection` (selection-only toolbar)\n *\n * Tools are always-visible buttons rendered in a toolbar above/below the\n * textarea (think Markdown editor chrome: B / I / Code / Link / Quote).\n * Each tool receives a `helpers` bundle that exposes the underlying\n * editing primitives (selection, caret, line-aware mutations, undo).\n *\n * Consumers can:\n * - Compose any combination of built-in tools from the\n * `textareaTools` factory\n * - Mix in fully custom tools (`{ id, label, icon, onAction }`)\n * - Drive the hook directly to build their own toolbar UI\n * ------------------------------------------------------------------------- */\n\nexport interface TextareaToolHelpers {\n /** Current full text. */\n value: string;\n /** Current selection / caret state. */\n selection: {\n text: string;\n start: number;\n end: number;\n active: boolean;\n };\n /** Replace the entire textarea content. */\n setValue: (next: string) => void;\n /** Replace the selection with `text` (inserts at caret when no\n * selection is active). Caret lands after the inserted text. */\n replace: (text: string) => void;\n /** Insert `text` at the caret without disturbing the selection's\n * surrounding content. Identical to `replace` when nothing is\n * selected. */\n insert: (text: string) => void;\n /** Wrap the selection with `open` / `close` strings. When no\n * selection is active, drops the markers around an empty span at\n * the caret. Caret ends up between them so the user can type. */\n wrap: (open: string, close?: string) => void;\n /** Prepend `prefix` to the start of every line that overlaps the\n * selection (or just the caret's line when no selection). Useful for\n * list / quote / heading tools. */\n prependLines: (prefix: string) => void;\n /** Programmatic undo / redo via the native execCommand bridge.\n * Falls back silently when the browser doesn't expose it. */\n undo: () => void;\n redo: () => void;\n /** Direct access to the underlying DOM node for cases the abstraction\n * doesn't cover. */\n getTextarea: () => HTMLTextAreaElement | null;\n}\n\nexport interface TextareaTool {\n id: string;\n label: ReactNode;\n icon?: ReactNode;\n /** Title attribute for the toolbar button. Defaults to the `label`\n * when it's a string. */\n title?: string;\n /** Visual treatment — `\"divider\"` renders a vertical separator\n * instead of a button. Otherwise `\"button\"`. */\n kind?: \"button\" | \"divider\";\n /** Fires when the toolbar button is clicked. Receives a helpers\n * bundle that proxies the editing primitives. Can be async. */\n onAction?: (helpers: TextareaToolHelpers) => void | Promise<void>;\n /** Hide the button when this predicate returns false. Re-evaluated\n * on every value / selection change. Useful for \"only show Link\n * when something is selected\" patterns. */\n isVisible?: (helpers: TextareaToolHelpers) => boolean;\n}\n\nexport interface UseTextareaToolsOptions {\n textareaRef: RefObject<HTMLTextAreaElement | null>;\n value: string;\n onChange: (next: string) => void;\n tools: TextareaTool[];\n}\n\nexport interface UseTextareaToolsReturn {\n /** Filtered + ready-to-render tools (visibility predicates applied). */\n tools: TextareaTool[];\n /** Invoke a tool by id. */\n runTool: (id: string) => Promise<void>;\n /** Snapshot helpers — same object passed into `onAction` so consumers\n * can call them outside the toolbar (e.g. from a keyboard shortcut). */\n helpers: TextareaToolHelpers;\n}\n\n/* ---------------------------------------------------------------------------\n * Hook\n * ------------------------------------------------------------------------- */\n\nexport function useTextareaTools({\n textareaRef,\n value,\n onChange,\n tools,\n}: UseTextareaToolsOptions): UseTextareaToolsReturn {\n // Keep latest value in a ref so tool callbacks always see the\n // up-to-date string, even when chained synchronously.\n const valueRef = useRef(value);\n valueRef.current = value;\n\n const helpers = useMemo<TextareaToolHelpers>(() => {\n const getTa = () => textareaRef.current;\n\n const getSelection = () => {\n const ta = getTa();\n const s = ta?.selectionStart ?? 0;\n const e = ta?.selectionEnd ?? 0;\n return {\n text: valueRef.current.slice(s, e),\n start: s,\n end: e,\n active: s !== e,\n };\n };\n\n const setValue = (next: string) => onChange(next);\n\n const replace = (text: string) => {\n const ta = getTa();\n if (!ta) return;\n const { start, end } = getSelection();\n const next = valueRef.current.slice(0, start) + text + valueRef.current.slice(end);\n onChange(next);\n requestAnimationFrame(() => {\n ta.focus();\n const caret = start + text.length;\n ta.setSelectionRange(caret, caret);\n });\n };\n\n const insert = (text: string) => replace(text);\n\n const wrap = (open: string, close?: string) => {\n const ta = getTa();\n if (!ta) return;\n const closing = close ?? open;\n const { start, end } = getSelection();\n const sel = valueRef.current.slice(start, end);\n const next =\n valueRef.current.slice(0, start) + open + sel + closing + valueRef.current.slice(end);\n onChange(next);\n requestAnimationFrame(() => {\n ta.focus();\n if (start === end) {\n // Empty selection — drop the caret between the wrappers so\n // the user can type the body content right away.\n const caret = start + open.length;\n ta.setSelectionRange(caret, caret);\n } else {\n ta.setSelectionRange(start, end + open.length + closing.length);\n }\n });\n };\n\n const prependLines = (prefix: string) => {\n const ta = getTa();\n if (!ta) return;\n const { start, end } = getSelection();\n // Expand selection to whole lines so prefixes land at line starts.\n const v = valueRef.current;\n const lineStart = v.lastIndexOf(\"\\n\", start - 1) + 1;\n const lineEnd = (() => {\n const idx = v.indexOf(\"\\n\", end);\n return idx === -1 ? v.length : idx;\n })();\n const block = v.slice(lineStart, lineEnd);\n const updated = block\n .split(\"\\n\")\n .map((line) => `${prefix}${line}`)\n .join(\"\\n\");\n const next = v.slice(0, lineStart) + updated + v.slice(lineEnd);\n onChange(next);\n requestAnimationFrame(() => {\n ta.focus();\n ta.setSelectionRange(lineStart, lineStart + updated.length);\n });\n };\n\n const undo = () => {\n try {\n getTa()?.focus();\n document.execCommand(\"undo\");\n } catch {\n /* not all browsers expose undo via execCommand */\n }\n };\n const redo = () => {\n try {\n getTa()?.focus();\n document.execCommand(\"redo\");\n } catch {\n /* same */\n }\n };\n\n return {\n get value() {\n return valueRef.current;\n },\n get selection() {\n return getSelection();\n },\n setValue,\n replace,\n insert,\n wrap,\n prependLines,\n undo,\n redo,\n getTextarea: getTa,\n };\n }, [textareaRef, onChange]);\n\n // Visibility filter — re-evaluated each render so predicates that\n // depend on the current selection update naturally.\n const visibleTools = useMemo(\n () => tools.filter((t) => (t.isVisible ? t.isVisible(helpers) : true)),\n [tools, helpers],\n );\n\n const runTool = useCallback(\n async (id: string) => {\n const tool = tools.find((t) => t.id === id);\n if (!tool || tool.kind === \"divider\") return;\n await tool.onAction?.(helpers);\n },\n [tools, helpers],\n );\n\n return { tools: visibleTools, runTool, helpers };\n}\n\n/* ---------------------------------------------------------------------------\n * `textareaTools` — factory for the built-in Markdown/editor tools.\n *\n * Each factory returns a `TextareaTool`. Consumers compose them freely:\n *\n * tools={[\n * textareaTools.bold(),\n * textareaTools.italic(),\n * textareaTools.divider(),\n * textareaTools.bulletList(),\n * textareaTools.numberedList(),\n * textareaTools.divider(),\n * textareaTools.link(),\n * myCustomTool,\n * ]}\n * ------------------------------------------------------------------------- */\n\nconst wrapTool = (\n id: string,\n open: string,\n close: string,\n label: ReactNode,\n icon: ReactNode,\n title?: string,\n): TextareaTool => ({\n id,\n label,\n icon,\n title,\n onAction: (h) => h.wrap(open, close),\n});\n\nconst prependLineTool = (\n id: string,\n prefix: string,\n label: ReactNode,\n icon: ReactNode,\n title?: string,\n): TextareaTool => ({\n id,\n label,\n icon,\n title,\n onAction: (h) => h.prependLines(prefix),\n});\n\nexport const textareaTools = {\n bold: (): TextareaTool => wrapTool(\"bold\", \"**\", \"**\", \"Bold\", <TextBoldIcon />, \"Bold (⌘B)\"),\n\n italic: (): TextareaTool =>\n wrapTool(\"italic\", \"*\", \"*\", \"Italic\", <TextItalicIcon />, \"Italic (⌘I)\"),\n\n strikethrough: (): TextareaTool =>\n wrapTool(\"strike\", \"~~\", \"~~\", \"Strikethrough\", <TextStrikethroughIcon />, \"Strikethrough\"),\n\n code: (): TextareaTool => wrapTool(\"code\", \"`\", \"`\", \"Code\", <CodeIcon />, \"Inline code\"),\n\n codeBlock: (): TextareaTool => ({\n id: \"code-block\",\n label: \"Code block\",\n icon: <CodeIcon />,\n title: \"Code block\",\n onAction: (h) => h.wrap(\"```\\n\", \"\\n```\"),\n }),\n\n link: (): TextareaTool => ({\n id: \"link\",\n label: \"Link\",\n icon: <TextLinkIcon />,\n title: \"Insert link\",\n onAction: (h) => {\n const sel = h.selection;\n const text = sel.active ? sel.text : \"link text\";\n h.replace(`[${text}](https://)`);\n },\n }),\n\n /** Heading. Defaults to H2. Pass a `level` (1–6) to override. */\n heading: (level: 1 | 2 | 3 | 4 | 5 | 6 = 2): TextareaTool =>\n prependLineTool(\n `heading-${level}`,\n `${\"#\".repeat(level)} `,\n `H${level}`,\n <HeadingIcon />,\n `Heading ${level}`,\n ),\n\n bulletList: (): TextareaTool =>\n prependLineTool(\"ul\", \"- \", \"Bullet list\", <ListBulletedIcon />, \"Bullet list\"),\n\n numberedList: (): TextareaTool =>\n prependLineTool(\"ol\", \"1. \", \"Numbered list\", <ListNumberedIcon />, \"Numbered list\"),\n\n quote: (): TextareaTool => prependLineTool(\"quote\", \"> \", \"Quote\", <QuotesIcon />, \"Quote\"),\n\n undo: (): TextareaTool => ({\n id: \"undo\",\n label: \"Undo\",\n icon: <UndoIcon />,\n title: \"Undo (⌘Z)\",\n onAction: (h) => h.undo(),\n }),\n\n redo: (): TextareaTool => ({\n id: \"redo\",\n label: \"Redo\",\n icon: <RedoIcon />,\n title: \"Redo (⌘⇧Z)\",\n onAction: (h) => h.redo(),\n }),\n\n divider: (id = \"divider\"): TextareaTool => ({\n id: `${id}-${Math.random().toString(36).slice(2, 8)}`,\n label: \"\",\n kind: \"divider\",\n }),\n};\n","\"use client\";\nimport { CopyIcon, CutIcon } from \"@octaviaflow/icons\";\nimport {\n type ComponentPropsWithoutRef,\n type CSSProperties,\n forwardRef,\n type ReactNode,\n useEffect,\n useId,\n useRef,\n useState,\n} from \"react\";\nimport { useTextField } from \"react-aria\";\nimport { createPortal } from \"react-dom\";\nimport { type TextareaCommand, useTextareaCommands } from \"../../hooks/useTextareaCommands\";\nimport { useTextareaSelection } from \"../../hooks/useTextareaSelection\";\nimport { type TextareaTool, useTextareaTools } from \"../../hooks/useTextareaTools\";\nimport { resolveAccessibleName } from \"../../utils/a11y\";\nimport { cn } from \"../../utils/cn\";\n\n/* ---------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\nexport type TextareaSize = \"sm\" | \"md\" | \"lg\";\n\n/** User-resize handle direction. Mirrors the native CSS `resize`\n * property. Pass `false` (legacy) and we map it to `\"none\"`. */\nexport type TextareaResize = \"vertical\" | \"horizontal\" | \"both\" | \"none\" | boolean;\n\ntype TextareaPropsBase = Omit<ComponentPropsWithoutRef<\"textarea\">, \"size\" | \"prefix\">;\n\nexport interface TextareaProps extends TextareaPropsBase {\n /** Visible label — accepts rich content. */\n label?: ReactNode;\n /** Boolean error flag — pairs with `errorMessage`. (Back-compat with v1.) */\n error?: boolean;\n /** Error message. When set with `error={true}` renders below the input\n * with `role=\"alert\"` and tints the border. */\n errorMessage?: ReactNode;\n /** Helper text rendered below the field when no error is set. */\n helperText?: ReactNode;\n /** User-drag resize handle direction. Default `\"vertical\"`.\n *\n * - `\"vertical\"` — only the bottom edge is draggable (most common).\n * - `\"horizontal\"` — only the right edge.\n * - `\"both\"` — corner handle, both axes.\n * - `\"none\"` — no user resize (auto-grow still works if enabled).\n * - Legacy `boolean` — `true` ≡ `\"vertical\"`, `false` ≡ `\"none\"`.\n */\n resize?: TextareaResize;\n /** Auto-grow the textarea as the user types, capped at `maxRows`.\n * Default `false`. When enabled the user-drag `resize` handle is\n * typically set to `\"none\"` so the two systems don't fight. */\n autoResize?: boolean;\n /** Minimum visible rows (only when `autoResize` is on). Default `rows`. */\n minRows?: number;\n /** Maximum visible rows before the textarea scrolls (only when\n * `autoResize` is on). Default `Infinity`. */\n maxRows?: number;\n /** Hard pixel ceiling on the textarea's height — applied as inline\n * `max-height`. Pair with `autoResize` to cap the auto-grow OR use\n * alone to limit how tall the user can drag the resize handle. */\n maxHeight?: number | string;\n /** Hard pixel ceiling on the textarea's width — applied as inline\n * `max-width`. Useful when `resize=\"horizontal\"` or `\"both\"`. */\n maxWidth?: number | string;\n /** Minimum pixel floor for the textarea's height. */\n minHeight?: number | string;\n /** Minimum pixel floor for the textarea's width. */\n minWidth?: number | string;\n maxLength?: number;\n size?: TextareaSize;\n rows?: number;\n\n /* ─── Inline command palette + selection toolbar ─────────────────\n *\n * These two opt-in sections live below / above the textarea while\n * the user is editing, giving the field a \"rich editor\" feel without\n * pulling in a contenteditable + range library:\n *\n * - `commands` → typing the trigger (default `/`) opens an\n * inline popover with the supplied commands. Arrow keys + Enter\n * commit. Each command's `insert` is appended at the caret with\n * the trigger + query removed automatically.\n *\n * - `selectionToolbar` → selecting text reveals a floating\n * toolbar with Copy / Cut / wrap buttons; consumers can extend\n * with custom actions.\n *\n * Both are powered by the `useTextareaCommands` and\n * `useTextareaSelection` hooks, which are also exported standalone\n * for consumers who want to roll their own UI.\n */\n commands?: TextareaCommand[];\n /** Trigger character for the command palette. Default `\"/\"`. */\n commandTrigger?: string;\n /** Show a floating Copy / Cut toolbar over a non-empty selection.\n * Default `false`. */\n selectionToolbar?: boolean;\n /** Custom actions appended to the selection toolbar's built-in\n * Copy / Cut. Each action receives the live selected text and the\n * selection helpers from `useTextareaSelection`. */\n selectionActions?: TextareaSelectionAction[];\n /** Always-visible toolbar of tools that act on the textarea content.\n * Compose from the `textareaTools` factory (bold, italic, code,\n * heading, link, undo, …) and / or pass custom `TextareaTool`\n * objects. The toolbar uses `useTextareaTools` under the hood —\n * consumers can also call the hook directly to roll their own UI. */\n tools?: TextareaTool[];\n /** Where the tools toolbar sits relative to the field. Default\n * `\"top\"`. */\n toolbarPosition?: \"top\" | \"bottom\";\n}\n\n/* ---------------------------------------------------------------------------\n * Selection toolbar action\n * ------------------------------------------------------------------------- */\n\nexport interface TextareaSelectionAction {\n id: string;\n label: ReactNode;\n icon?: ReactNode;\n /** Called when the user clicks the action. Receives the live\n * selection text and the helpers from `useTextareaSelection`. */\n onAction: (\n selection: string,\n helpers: {\n replace: (s: string) => void;\n wrap: (open: string, close?: string) => void;\n copy: () => Promise<boolean>;\n cut: () => Promise<boolean>;\n },\n ) => void;\n}\n\n/* ---------------------------------------------------------------------------\n * Component\n * ------------------------------------------------------------------------- */\n\nexport const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>(function Textarea(\n {\n label,\n error = false,\n errorMessage,\n helperText,\n resize = \"vertical\",\n autoResize = false,\n minRows,\n maxRows,\n maxHeight,\n maxWidth,\n minHeight,\n minWidth,\n maxLength,\n size = \"md\",\n rows = 3,\n disabled = false,\n className,\n style: consumerStyle,\n defaultValue,\n value,\n onChange,\n id: providedId,\n commands,\n commandTrigger = \"/\",\n selectionToolbar = false,\n selectionActions,\n tools,\n toolbarPosition = \"top\",\n ...props\n },\n forwardedRef,\n) {\n const innerRef = useRef<HTMLTextAreaElement>(null);\n // Compose forwarded + internal ref.\n const setRef = (node: HTMLTextAreaElement | null) => {\n (innerRef as { current: HTMLTextAreaElement | null }).current = node;\n if (typeof forwardedRef === \"function\") forwardedRef(node);\n else if (forwardedRef) (forwardedRef as { current: HTMLTextAreaElement | null }).current = node;\n };\n\n const reactId = useId();\n const baseId = providedId ?? `ods-textarea-${reactId}`;\n const hintId = (error && errorMessage) || helperText ? `${baseId}-hint` : undefined;\n const [charCount, setCharCount] = useState(() => String(value ?? defaultValue ?? \"\").length);\n\n const ariaNameProps = resolveAccessibleName({\n label: typeof label === \"string\" ? label : undefined,\n ariaLabel: props[\"aria-label\"],\n ariaLabelledby: (props as Record<string, unknown>)[\"aria-labelledby\"] as string | undefined,\n componentName: \"Textarea\",\n });\n\n const { labelProps, inputProps } = useTextField(\n {\n label: typeof label === \"string\" ? label : undefined,\n ...ariaNameProps,\n isDisabled: disabled,\n errorMessage: typeof errorMessage === \"string\" ? errorMessage : undefined,\n validationState: error ? \"invalid\" : undefined,\n inputElementType: \"textarea\",\n value: value as string | undefined,\n defaultValue: defaultValue as string | undefined,\n },\n innerRef,\n );\n\n const describedBy =\n [(props as Record<string, unknown>)[\"aria-describedby\"] as string | undefined, hintId]\n .filter(Boolean)\n .join(\" \") || undefined;\n\n const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setCharCount(e.target.value.length);\n onChange?.(e);\n };\n\n /* ── Inline command palette ───────────────────────────────────── */\n // The hooks need a `(value, onChange(string))` pair. Controlled\n // textareas already have a `value` prop; uncontrolled ones don't.\n // We mirror the current DOM value via `liveValue` so the hooks see\n // the same string regardless of which mode the consumer chose.\n const [liveValue, setLiveValue] = useState<string>(String(value ?? defaultValue ?? \"\"));\n useEffect(() => {\n // Keep liveValue in sync with the controlled prop when present.\n if (value != null) setLiveValue(String(value));\n }, [value]);\n const handleChangeWithMirror = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setLiveValue(e.target.value);\n handleChange(e);\n };\n const setLiveAndCommit = (next: string) => {\n setLiveValue(next);\n // Synthesize an event-like change so the consumer's `onChange`\n // receives the updated value via the same path.\n if (innerRef.current) innerRef.current.value = next;\n onChange?.({\n target: innerRef.current as HTMLTextAreaElement,\n currentTarget: innerRef.current as HTMLTextAreaElement,\n } as unknown as React.ChangeEvent<HTMLTextAreaElement>);\n setCharCount(next.length);\n };\n\n const cmdPalette = useTextareaCommands({\n textareaRef: innerRef,\n value: liveValue,\n onChange: setLiveAndCommit,\n commands: commands ?? [],\n trigger: commandTrigger,\n });\n const cmdEnabled = (commands?.length ?? 0) > 0;\n\n const sel = useTextareaSelection({\n textareaRef: innerRef,\n value: liveValue,\n onChange: setLiveAndCommit,\n });\n\n // Always-visible toolbar — driven by the `useTextareaTools` hook.\n // Stays empty when no `tools` array is provided so the toolbar\n // section never renders.\n const toolbar = useTextareaTools({\n textareaRef: innerRef,\n value: liveValue,\n onChange: setLiveAndCommit,\n tools: tools ?? [],\n });\n const toolbarEnabled = (tools?.length ?? 0) > 0;\n\n const handleKeyDownWithCommands = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (cmdEnabled) {\n const consumed = cmdPalette.onKeyDown(e);\n if (consumed) return;\n }\n (props as { onKeyDown?: React.KeyboardEventHandler<HTMLTextAreaElement> }).onKeyDown?.(e);\n };\n\n // ── Auto-grow textarea (height) ───────────────────────────────────\n //\n // Mirrors the line-height-aware sizing we use in PromptInput. We\n // detect three line-height forms (`\"normal\"`, unitless like `\"1.5\"`,\n // or px like `\"24px\"`) so a unitless multiplier doesn't end up\n // being treated as 1.5 PIXELS — a real bug we hit in v1.\n //\n // Effective max comes from `maxHeight` (explicit px ceiling) OR the\n // computed line-height × `maxRows` cap, whichever is smaller. When\n // neither is set, the textarea grows freely (no cap).\n useEffect(() => {\n if (!autoResize) return;\n const el = innerRef.current;\n if (!el) return;\n const computed = window.getComputedStyle(el);\n const fontSize = parseFloat(computed.fontSize) || 16;\n const lhRaw = computed.lineHeight;\n const lh =\n lhRaw === \"normal\"\n ? fontSize * 1.2\n : lhRaw.endsWith(\"px\")\n ? parseFloat(lhRaw)\n : parseFloat(lhRaw) * fontSize;\n const padding = parseFloat(computed.paddingTop) + parseFloat(computed.paddingBottom);\n\n const rowCap =\n maxRows != null && Number.isFinite(maxRows)\n ? lh * maxRows + padding\n : Number.POSITIVE_INFINITY;\n const pixelCap = typeof maxHeight === \"number\" ? maxHeight : Number.POSITIVE_INFINITY;\n const effectiveMax = Math.min(rowCap, pixelCap);\n\n const rowFloor = lh * (minRows ?? rows) + padding;\n\n // Reset to natural height then clamp.\n el.style.height = \"auto\";\n const target = Math.max(rowFloor, Math.min(effectiveMax, el.scrollHeight));\n el.style.height = `${target}px`;\n el.style.overflowY = el.scrollHeight > effectiveMax ? \"auto\" : \"hidden\";\n }, [autoResize, value, defaultValue, minRows, maxRows, maxHeight, rows]);\n\n const resolvedResize: \"vertical\" | \"horizontal\" | \"both\" | \"none\" =\n typeof resize === \"boolean\" ? (resize ? \"vertical\" : \"none\") : resize;\n\n const toCss = (v: number | string | undefined): string | undefined =>\n v == null ? undefined : typeof v === \"number\" ? `${v}px` : v;\n\n // Apply the constraint CSS inline so it survives consumer overrides\n // and works regardless of class-bundling order. `resize` becomes a\n // CSS variable consumed by the field rule so the class can read it.\n const fieldStyle: CSSProperties = {\n maxHeight: toCss(maxHeight),\n maxWidth: toCss(maxWidth),\n minHeight: toCss(minHeight),\n minWidth: toCss(minWidth),\n resize: resolvedResize,\n };\n\n return (\n <div\n className={cn(\n \"ods-textarea\",\n `ods-textarea--${size}`,\n `ods-textarea--resize-${resolvedResize}`,\n autoResize && \"ods-textarea--auto-resize\",\n error && \"ods-textarea--error\",\n disabled && \"ods-textarea--disabled\",\n className,\n )}\n style={consumerStyle}\n >\n {label && (\n <label {...labelProps} htmlFor={baseId} className=\"ods-textarea__label\">\n {label}\n </label>\n )}\n {toolbarEnabled && toolbarPosition === \"top\" && (\n <TextareaToolbar tools={toolbar.tools} onRun={toolbar.runTool} />\n )}\n <div className=\"ods-textarea__wrapper\">\n <textarea\n {...(props as ComponentPropsWithoutRef<\"textarea\">)}\n {...inputProps}\n ref={setRef}\n id={baseId}\n rows={autoResize ? (minRows ?? rows) : rows}\n disabled={disabled}\n maxLength={maxLength}\n defaultValue={defaultValue}\n value={value}\n onChange={handleChangeWithMirror}\n onKeyDown={handleKeyDownWithCommands}\n className=\"ods-textarea__field\"\n style={fieldStyle}\n aria-invalid={error || undefined}\n aria-describedby={describedBy}\n // When the command palette is open, expose it as the\n // companion combobox so AT users hear the active option.\n aria-autocomplete={cmdEnabled ? \"list\" : undefined}\n aria-expanded={cmdEnabled ? cmdPalette.isOpen : undefined}\n aria-controls={cmdEnabled && cmdPalette.isOpen ? `${baseId}-cmd-list` : undefined}\n aria-activedescendant={\n cmdEnabled && cmdPalette.isOpen && cmdPalette.items[cmdPalette.activeIndex]\n ? `${baseId}-cmd-${cmdPalette.items[cmdPalette.activeIndex].id}`\n : undefined\n }\n />\n\n {/* ── Inline command palette ─────────────────────────── */}\n {cmdEnabled &&\n cmdPalette.isOpen &&\n cmdPalette.items.length > 0 &&\n typeof document !== \"undefined\" &&\n createPortal(\n <ul\n id={`${baseId}-cmd-list`}\n role=\"listbox\"\n aria-label=\"Inline commands\"\n className=\"ods-textarea__cmd-popover\"\n style={{\n position: \"fixed\",\n top: (cmdPalette.caretRect?.bottom ?? 0) + 6,\n left: cmdPalette.caretRect?.left ?? 0,\n }}\n >\n {cmdPalette.items.map((c, i) => (\n <li\n key={c.id}\n id={`${baseId}-cmd-${c.id}`}\n role=\"option\"\n aria-selected={i === cmdPalette.activeIndex}\n className={cn(\n \"ods-textarea__cmd-item\",\n i === cmdPalette.activeIndex && \"ods-textarea__cmd-item--active\",\n )}\n onMouseDown={(e) => {\n // mousedown + preventDefault so the textarea\n // doesn't lose focus before commit fires.\n e.preventDefault();\n cmdPalette.commit(c);\n }}\n onMouseEnter={() => {\n // No public hover-state setter — close + reopen\n // pattern would be heavy. Skipping hover-to-\n // highlight for now; ArrowUp/Down nav covers it.\n }}\n >\n {c.icon && <span className=\"ods-textarea__cmd-icon\">{c.icon}</span>}\n <span className=\"ods-textarea__cmd-text\">\n <span className=\"ods-textarea__cmd-label\">{c.label}</span>\n {c.description && (\n <span className=\"ods-textarea__cmd-desc\">{c.description}</span>\n )}\n </span>\n </li>\n ))}\n </ul>,\n document.body,\n )}\n\n {/* ── Selection toolbar ──────────────────────────────── */}\n {selectionToolbar &&\n sel.active &&\n sel.rect &&\n typeof document !== \"undefined\" &&\n createPortal(\n <div\n role=\"toolbar\"\n aria-label=\"Selection actions\"\n className=\"ods-textarea__sel-toolbar\"\n style={{\n position: \"fixed\",\n top: sel.rect.top - 36,\n left: sel.rect.left,\n }}\n // mousedown + preventDefault keeps the textarea\n // selection alive while the user clicks a button.\n onMouseDown={(e) => e.preventDefault()}\n >\n <button\n type=\"button\"\n className=\"ods-textarea__sel-btn\"\n onClick={() => sel.copy()}\n aria-label=\"Copy selection\"\n title=\"Copy\"\n >\n <CopyIcon size=\"xs\" />\n </button>\n <button\n type=\"button\"\n className=\"ods-textarea__sel-btn\"\n onClick={() => sel.cut()}\n aria-label=\"Cut selection\"\n title=\"Cut\"\n >\n <CutIcon size=\"xs\" />\n </button>\n {selectionActions?.map((a) => (\n <button\n key={a.id}\n type=\"button\"\n className=\"ods-textarea__sel-btn\"\n onClick={() =>\n a.onAction(sel.text, {\n replace: sel.replace,\n wrap: sel.wrap,\n copy: sel.copy,\n cut: sel.cut,\n })\n }\n title={typeof a.label === \"string\" ? a.label : undefined}\n >\n {a.icon}\n {a.label && <span className=\"ods-textarea__sel-btn-label\">{a.label}</span>}\n </button>\n ))}\n </div>,\n document.body,\n )}\n {maxLength != null && (\n <span\n className=\"ods-textarea__count\"\n aria-live={charCount > maxLength ? \"polite\" : \"off\"}\n >\n {charCount}/{maxLength}\n </span>\n )}\n </div>\n {toolbarEnabled && toolbarPosition === \"bottom\" && (\n <TextareaToolbar tools={toolbar.tools} onRun={toolbar.runTool} />\n )}\n {error && errorMessage ? (\n <div id={hintId} className=\"ods-textarea__error-message\" role=\"alert\">\n {errorMessage}\n </div>\n ) : helperText ? (\n <div id={hintId} className=\"ods-textarea__hint\">\n {helperText}\n </div>\n ) : null}\n </div>\n );\n});\n\nTextarea.displayName = \"Textarea\";\n\n/* ---------------------------------------------------------------------------\n * Internal — toolbar renderer\n *\n * Stays internal because consumers who want a custom UI should call\n * `useTextareaTools` directly. The toolbar's only job here is to map\n * the resolved tools array to clickable buttons / dividers using the\n * same chrome as the rest of the textarea section.\n * ------------------------------------------------------------------------- */\nfunction TextareaToolbar({\n tools,\n onRun,\n}: {\n tools: TextareaTool[];\n onRun: (id: string) => void | Promise<void>;\n}) {\n return (\n <div\n role=\"toolbar\"\n aria-label=\"Formatting\"\n className=\"ods-textarea__toolbar\"\n // mousedown + preventDefault keeps the textarea's selection /\n // caret alive while a button is clicked.\n onMouseDown={(e) => {\n if ((e.target as HTMLElement).closest(\".ods-textarea__toolbar-btn\")) {\n e.preventDefault();\n }\n }}\n >\n {tools.map((t) => {\n if (t.kind === \"divider\") {\n return <span key={t.id} className=\"ods-textarea__toolbar-divider\" aria-hidden=\"true\" />;\n }\n return (\n <button\n key={t.id}\n type=\"button\"\n className=\"ods-textarea__toolbar-btn\"\n title={t.title ?? (typeof t.label === \"string\" ? t.label : undefined)}\n aria-label={typeof t.label === \"string\" ? t.label : t.id}\n onClick={() => onRun(t.id)}\n >\n {t.icon ? (\n <span className=\"ods-textarea__toolbar-icon\">{t.icon}</span>\n ) : (\n <span className=\"ods-textarea__toolbar-text\">{t.label}</span>\n )}\n </button>\n );\n })}\n </div>\n );\n}\n","\"use client\";\nimport { QuotesIcon, StarFilledIcon, StarIcon } from \"@octaviaflow/icons\";\nimport { type ComponentPropsWithoutRef, forwardRef, type ReactNode, useId } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Avatar, type AvatarProps } from \"../Avatar\";\nimport { Card, type CardRadius } from \"../Card\";\n\n/* ---------------------------------------------------------------------------\n * TestimonialCard — pull-quote card with author + optional rating.\n *\n * Composes on the polished `Card` primitive (forwardRef, native props,\n * focus rings, radius). Uses the polished `Avatar` primitive for the\n * author photo and `@octaviaflow/icons` for the quote glyph + star\n * rating.\n * ------------------------------------------------------------------------- */\n\nexport type TestimonialCardSize = \"sm\" | \"md\" | \"lg\";\n\nexport interface TestimonialCardAuthor {\n /** Display name. */\n name: ReactNode;\n /** Avatar — forwarded to the polished Avatar primitive. */\n avatar?: Pick<AvatarProps, \"src\" | \"initials\" | \"alt\" | \"seed\" | \"palette\">;\n /** Job title / role / handle. */\n role?: ReactNode;\n}\n\nexport interface TestimonialCardProps\n extends Omit<\n ComponentPropsWithoutRef<\"figure\">,\n // Native `role` is an AriaRole string; our legacy `role` prop is a\n // ReactNode (author's job title). Omit so they don't collide.\n \"role\" | \"onDrag\" | \"onDragStart\" | \"onDragEnd\" | \"onAnimationStart\"\n > {\n /** The testimonial body. */\n quote: ReactNode;\n /**\n * Author — accepts either a plain ReactNode (legacy: name only) or a\n * structured `{ name, role?, avatar? }` object (preferred).\n */\n author: ReactNode | TestimonialCardAuthor;\n /** Legacy: author role rendered below the name. Use `author.role` instead. */\n role?: ReactNode;\n /** Legacy: raw avatar slot (e.g. <img />). Use `author.avatar` instead. */\n avatar?: ReactNode;\n /** Legacy: initial character to render in the avatar circle. */\n initial?: ReactNode;\n /** 0–5 star rating. */\n rating?: number;\n /** Optional company logo node — rendered top-right (e.g. customer logo). */\n logo?: ReactNode;\n /** Size variant — drives quote-text size + padding. */\n size?: TestimonialCardSize;\n /** Card corner radius (passes through). */\n radius?: CardRadius;\n}\n\nfunction isAuthorObject(v: TestimonialCardProps[\"author\"]): v is TestimonialCardAuthor {\n return (\n typeof v === \"object\" &&\n v !== null &&\n !(\"type\" in (v as object)) && // exclude React elements\n \"name\" in (v as unknown as Record<string, unknown>)\n );\n}\n\nexport const TestimonialCard = forwardRef<HTMLElement, TestimonialCardProps>(\n function TestimonialCard(\n {\n quote,\n author,\n role: legacyRole,\n avatar: legacyAvatar,\n initial: legacyInitial,\n rating,\n logo,\n size = \"md\",\n radius = \"md\",\n id: providedId,\n className,\n ...rest\n },\n ref,\n ) {\n const reactId = useId();\n const baseId = providedId ?? `ods-testimonial-${reactId}`;\n const quoteId = `${baseId}-quote`;\n const authorId = `${baseId}-author`;\n\n // Resolve the author shape — structured wins, legacy props fill in.\n const resolved: TestimonialCardAuthor = isAuthorObject(author)\n ? author\n : {\n name: author,\n role: legacyRole,\n avatar: legacyAvatar\n ? undefined // legacy raw-node path handled below\n : {\n initials:\n typeof legacyInitial === \"string\"\n ? legacyInitial\n : typeof author === \"string\"\n ? author.charAt(0).toUpperCase()\n : undefined,\n },\n };\n\n const renderAvatar = () => {\n // Legacy raw `avatar` node (e.g. <img />) — preserve back-compat.\n if (!isAuthorObject(author) && legacyAvatar) {\n return (\n <span\n className=\"ods-testimonial__avatar ods-testimonial__avatar--legacy\"\n aria-hidden=\"true\"\n >\n {legacyAvatar}\n </span>\n );\n }\n return (\n <Avatar\n size={size === \"sm\" ? \"xs\" : size === \"lg\" ? \"md\" : \"sm\"}\n src={resolved.avatar?.src}\n initials={resolved.avatar?.initials}\n seed={resolved.avatar?.seed}\n palette={resolved.avatar?.palette}\n alt={\n resolved.avatar?.alt ?? (typeof resolved.name === \"string\" ? resolved.name : undefined)\n }\n className=\"ods-testimonial__avatar\"\n />\n );\n };\n\n return (\n <Card\n // Card forwards refs to a div; figure is a different element so we\n // render the figure semantics in our children and let Card own\n // the focusable surface as a generic block. The forwardRef on\n // TestimonialCard's outer type is `HTMLElement` so consumers\n // can still attach a ref without TS friction.\n {...(rest as unknown as ComponentPropsWithoutRef<\"div\">)}\n ref={ref as unknown as React.Ref<HTMLDivElement>}\n id={baseId}\n radius={radius}\n padding=\"none\"\n variant=\"subtle\"\n className={cn(\"ods-testimonial\", `ods-testimonial--${size}`, className)}\n aria-labelledby={authorId}\n aria-describedby={quoteId}\n >\n <div className=\"ods-testimonial__head\">\n <span className=\"ods-testimonial__quote\" aria-hidden=\"true\">\n <QuotesIcon size=\"md\" />\n </span>\n {logo && (\n <span className=\"ods-testimonial__logo\" aria-hidden=\"true\">\n {logo}\n </span>\n )}\n </div>\n\n <blockquote id={quoteId} className=\"ods-testimonial__text\">\n {quote}\n </blockquote>\n\n {typeof rating === \"number\" && (\n <div\n className=\"ods-testimonial__rating\"\n role=\"img\"\n aria-label={`${rating} out of 5 stars`}\n >\n {Array.from({ length: 5 }).map((_, i) =>\n i < Math.round(rating) ? (\n <StarFilledIcon\n key={i}\n size=\"xs\"\n className=\"ods-testimonial__star ods-testimonial__star--on\"\n />\n ) : (\n <StarIcon key={i} size=\"xs\" className=\"ods-testimonial__star\" />\n ),\n )}\n </div>\n )}\n\n <figcaption className=\"ods-testimonial__author\" id={authorId}>\n {renderAvatar()}\n <span className=\"ods-testimonial__author-info\">\n <span className=\"ods-testimonial__author-name\">{resolved.name}</span>\n {resolved.role && <span className=\"ods-testimonial__author-role\">{resolved.role}</span>}\n </span>\n </figcaption>\n </Card>\n );\n },\n);\n\nTestimonialCard.displayName = \"TestimonialCard\";\n","/* The assistant surfaces' small glyphs (header controls, launchers). Inline so\n * the surfaces never hard-depend on the icon package for these shapes. */\n\nconst stroke = {\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 1.5,\n strokeLinecap: \"round\" as const,\n strokeLinejoin: \"round\" as const,\n};\n\nexport function CloseGlyph() {\n return (\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M4 4l8 8M12 4l-8 8\" {...stroke} />\n </svg>\n );\n}\n\n/** Start a new chat. */\nexport function NewChatGlyph() {\n return (\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M8 3.5v9M3.5 8h9\" {...stroke} />\n </svg>\n );\n}\n\n/** Focus mode (expand). */\nexport function ExpandGlyph() {\n return (\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M9.5 2.5h4v4M6.5 13.5h-4v-4M13.5 2.5 9 7M2.5 13.5 7 9\" {...stroke} />\n </svg>\n );\n}\n\n/** Leave focus mode (collapse). */\nexport function CollapseGlyph() {\n return (\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M13.5 6.5h-4v-4M2.5 9.5h4v4M9.5 6.5 14 2M6.5 9.5 2 14\" {...stroke} />\n </svg>\n );\n}\n\n/** Pin beside the page (dock) vs. float over it. */\nexport function PinGlyph() {\n return (\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M2.5 2.5h11v11h-11zM10 2.5v11\" {...stroke} />\n </svg>\n );\n}\n\nexport function HistoryGlyph() {\n return (\n <svg viewBox=\"0 0 16 16\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M2.5 8a5.5 5.5 0 1 0 1.6-3.9M2.5 2.5v2.6h2.6M8 5v3.2l2 1.3\" {...stroke} />\n </svg>\n );\n}\n\n/** A speech glyph for launchers. */\nexport function ChatGlyph() {\n return (\n <svg viewBox=\"0 0 20 20\" aria-hidden=\"true\" focusable=\"false\">\n <path\n d=\"M4 4.5h12a1.5 1.5 0 0 1 1.5 1.5v6.5A1.5 1.5 0 0 1 16 14H9l-3.5 2.8V14H4a1.5 1.5 0 0 1-1.5-1.5V6A1.5 1.5 0 0 1 4 4.5Z\"\n {...stroke}\n />\n </svg>\n );\n}\n"],"mappings":"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","names":["Card","CardHeader","CardBody","CardFooter","CardTitle","CardDescription","forwardRef","jsx","forwardRef","Avatar","AvatarStack","forwardRef","jsx","jsxs","forwardRef","BlogCard","forwardRef","jsx","jsxs","forwardRef","ChatBubble","forwardRef","useId","useState","jsx","jsxs","forwardRef","ChatComposer","useState","useId","forwardRef","useRef","useState","jsx","useRef","useState","jsx","jsxs","forwardRef","ChatLinkPreview","forwardRef","jsx","jsxs","forwardRef","ChatDocPreview","forwardRef","useId","useRef","jsx","jsxs","forwardRef","RadioGroup","useId","useRef","forwardRef","useRef","jsx","jsxs","forwardRef","Radio","useRef","forwardRef","useId","useState","Fragment","jsx","jsxs","forwardRef","ChatInputRequest","useId","useState","forwardRef","useState","jsx","jsxs","forwardRef","ChatFeedback","useState","forwardRef","jsx","jsxs","forwardRef","ChatScrollToBottom","forwardRef","useEffect","useRef","jsx","jsxs","forwardRef","ChatThread","useRef","useEffect","isEmpty","forwardRef","useCallback","useRef","useState","jsx","jsxs","forwardRef","ChatPanel","useRef","useState","useCallback","jsx","jsx","jsxs","forwardRef","useState","jsx","jsxs","hostOf","forwardRef","ChatSources","useState","forwardRef","jsx","jsxs","forwardRef","ChatSuggestions","forwardRef","useEffect","useState","Fragment","jsx","jsxs","forwardRef","ChatThinking","useState","useEffect","forwardRef","useState","jsx","jsxs","forwardRef","ChatToolTrace","useState","forwardRef","useState","jsx","jsxs","forwardRef","ChatVideoPreview","useState","useState","Fragment","jsx","jsxs","useState","forwardRef","useEffect","useRef","useState","jsxs","forwardRef","CountUp","useState","useRef","useEffect","useCallback","useEffect","useMemo","useRef","useState","pick","useCallback","useEffect","useState","useCallback","useMemo","useRef","jsx","forwardRef","useEffect","useId","useRef","useState","jsx","jsxs","forwardRef","Textarea","useRef","useId","useState","useEffect","QuotesIcon","forwardRef","useId","jsx","jsxs","forwardRef","TestimonialCard","useId","QuotesIcon","jsx"]}